Merge ssh://github.com/web2py/web2py

This commit is contained in:
Michele Comitini committed 2013-07-17 02:59:33 +02:00
commit 49c189547b
44 files changed
+1377 -1618

No files matched your search

+1 -1
View File
@@ -1 +1 @@
Version 2.6.0-development+timestamp.2013.07.05.02.12.46 Version 2.6.0-development+timestamp.2013.07.16.13.14.21
+6 -3
View File
@@ -623,7 +623,10 @@ def manage():
orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None
elif table == auth.table_permission(): elif table == auth.table_permission():
orderby = 'group_id' orderby = 'group_id'
grid = SQLFORM.smartgrid(table, args=request.args[:2], user_signature=True, kwargs = dict(user_signature=True, maxtextlength=1000,
orderby=orderby, linked_tables=linked_tables, orderby=orderby, linked_tables=linked_tables)
maxtextlength=1000, formname=formname) smartgrid_args = manager_action.get('smartgrid_args', {})
kwargs.update(**smartgrid_args.get('DEFAULT', {}))
kwargs.update(**smartgrid_args.get(table._tablename, {}))
grid = SQLFORM.smartgrid(table, args=request.args[:2], formname=formname, **kwargs)
return grid return grid
+2 -3
View File
@@ -565,7 +565,7 @@ def edit():
# return the scaffolding, the rest will be through ajax requests # return the scaffolding, the rest will be through ajax requests
response.title = T('Editing %s' % app) response.title = T('Editing %s' % app)
editarea_preferences = {} editarea_preferences = {}
editarea_preferences['FONT_SIZE'] = '10' editarea_preferences['FONT_SIZE'] = '10'
editarea_preferences['FULL_SCREEN'] = 'false' editarea_preferences['FULL_SCREEN'] = 'false'
editarea_preferences['ALLOW_TOGGLE'] = 'true' editarea_preferences['ALLOW_TOGGLE'] = 'true'
editarea_preferences['REPLACE_TAB_BY_SPACES'] = '4' editarea_preferences['REPLACE_TAB_BY_SPACES'] = '4'
@@ -746,7 +746,7 @@ def edit():
view_link=view_link, view_link=view_link,
editviewlinks=editviewlinks, editviewlinks=editviewlinks,
id=IS_SLUG()(filename)[0], id=IS_SLUG()(filename)[0],
force= True if (request.vars.restore or request.vars.revert) else False) force= True if (request.vars.restore or request.vars.revert) else False)
plain_html = response.render('default/edit_js.html', file_details) plain_html = response.render('default/edit_js.html', file_details)
file_details['plain_html'] = plain_html file_details['plain_html'] = plain_html
return response.json(file_details) return response.json(file_details)
@@ -1770,4 +1770,3 @@ def git_push():
session.flash = T("Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.") session.flash = T("Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.")
redirect(URL('site')) redirect(URL('site'))
return dict(app=app, form=form) return dict(app=app, form=form)
+24 -8
View File
@@ -8,6 +8,7 @@
'%Y-%m-%d': '%d/%m/%Y', '%Y-%m-%d': '%d/%m/%Y',
'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S', '%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S',
'(requires internet access)': '(requires internet access)', '(requires internet access)': '(requires internet access)',
'(requires internet access, experimental)': '(requires internet access, experimental)',
'(something like "it-it")': '(qualcosa simile a "it-it")', '(something like "it-it")': '(qualcosa simile a "it-it")',
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)', '@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)',
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', '@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
@@ -43,6 +44,7 @@
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': "ATTENZIONE: L'accesso richiede una connessione sicura (HTTPS) o l'esecuzione di web2py in locale (connessione su localhost)", 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': "ATTENZIONE: L'accesso richiede una connessione sicura (HTTPS) o l'esecuzione di web2py in locale (connessione su localhost)",
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTZIONE: NON ESEGUIRE PIÙ TEST IN PARALLELO (I TEST NON SONO "THREAD SAFE")', 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTZIONE: NON ESEGUIRE PIÙ TEST IN PARALLELO (I TEST NON SONO "THREAD SAFE")',
'ATTENTION: you cannot edit the running application!': "ATTENZIONE: non puoi modificare l'applicazione correntemente in uso ", 'ATTENTION: you cannot edit the running application!': "ATTENZIONE: non puoi modificare l'applicazione correntemente in uso ",
'Autocomplete Python Code': 'Autocomplete Python Code',
'Available databases and tables': 'Database e tabelle disponibili', 'Available databases and tables': 'Database e tabelle disponibili',
'back': 'indietro', 'back': 'indietro',
'cache': 'cache', 'cache': 'cache',
@@ -113,10 +115,12 @@
'Edit': 'modifica', 'Edit': 'modifica',
'Edit application': 'Modifica applicazione', 'Edit application': 'Modifica applicazione',
'edit controller': 'modifica controller', 'edit controller': 'modifica controller',
'edit controller:': 'edit controller:',
'Edit current record': 'Modifica record corrente', 'Edit current record': 'Modifica record corrente',
'edit profile': 'modifica profilo', 'edit profile': 'modifica profilo',
'Edit This App': 'Modifica questa applicazione', 'Edit This App': 'Modifica questa applicazione',
'edit views:': 'modifica viste (view):', 'edit views:': 'modifica viste (view):',
'Editing bigul': 'Editing bigul',
'Editing file "%s"': 'Modifica del file "%s"', 'Editing file "%s"': 'Modifica del file "%s"',
'Editing Language file': 'Modifica file linguaggio', 'Editing Language file': 'Modifica file linguaggio',
'Enterprise Web Framework': 'Enterprise Web Framework', 'Enterprise Web Framework': 'Enterprise Web Framework',
@@ -140,6 +144,8 @@
'file saved on %(time)s': "file salvato nell'istante %(time)s", 'file saved on %(time)s': "file salvato nell'istante %(time)s",
'file saved on %s': 'file salvato: %s', 'file saved on %s': 'file salvato: %s',
'filter': 'filter', 'filter': 'filter',
'Find Next': 'Find Next',
'Find Previous': 'Find Previous',
'Frames': 'Frames', 'Frames': 'Frames',
'Functions with no doctests will result in [passed] tests.': 'I test delle funzioni senza "doctests" risulteranno sempre [passed].', 'Functions with no doctests will result in [passed] tests.': 'I test delle funzioni senza "doctests" risulteranno sempre [passed].',
'Get from URL:': 'Get from URL:', 'Get from URL:': 'Get from URL:',
@@ -177,15 +183,16 @@
'License for': 'Licenza relativa a', 'License for': 'Licenza relativa a',
'loading...': 'caricamento...', 'loading...': 'caricamento...',
'locals': 'locals', 'locals': 'locals',
'login': 'accesso',
'Login': 'Accesso', 'Login': 'Accesso',
'login': 'accesso',
'Login to the Administrative Interface': "Accesso all'interfaccia amministrativa", 'Login to the Administrative Interface': "Accesso all'interfaccia amministrativa",
'Logout': 'uscita', 'Logout': 'uscita',
'Main Menu': 'Menu principale', 'Main Menu': 'Menu principale',
'Manage': 'Manage',
'Menu Model': 'Menu Modelli', 'Menu Model': 'Menu Modelli',
'merge': 'unisci', 'merge': 'unisci',
'models': 'modelli',
'Models': 'Modelli', 'Models': 'Modelli',
'models': 'modelli',
'Modules': 'Moduli', 'Modules': 'Moduli',
'modules': 'moduli', 'modules': 'moduli',
'new application "%s" created': 'creata la nuova applicazione "%s"', 'new application "%s" created': 'creata la nuova applicazione "%s"',
@@ -198,6 +205,7 @@
'NO': 'NO', 'NO': 'NO',
'No databases in this application': 'Nessun database presente in questa applicazione', 'No databases in this application': 'Nessun database presente in questa applicazione',
'no match': 'nessuna corrispondenza', 'no match': 'nessuna corrispondenza',
'online designer': 'online designer',
'or alternatively': 'or alternatively', 'or alternatively': 'or alternatively',
'Or Get from URL:': 'Or Get from URL:', 'Or Get from URL:': 'Or Get from URL:',
'or import from csv file': 'oppure importa da file CSV', 'or import from csv file': 'oppure importa da file CSV',
@@ -206,6 +214,7 @@
'Overwrite installed app': 'sovrascrivi applicazione installata', 'Overwrite installed app': 'sovrascrivi applicazione installata',
'Pack all': 'crea pacchetto', 'Pack all': 'crea pacchetto',
'Pack compiled': 'crea pacchetto del codice compilato', 'Pack compiled': 'crea pacchetto del codice compilato',
'Pack custom': 'Pack custom',
'pack plugin': 'crea pacchetto del plugin', 'pack plugin': 'crea pacchetto del plugin',
'PAM authenticated user, cannot change password here': 'utente autenticato tramite PAM, impossibile modificare password qui', 'PAM authenticated user, cannot change password here': 'utente autenticato tramite PAM, impossibile modificare password qui',
'password changed': 'password modificata', 'password changed': 'password modificata',
@@ -217,15 +226,19 @@
'Plural-Forms:': 'Plural-Forms:', 'Plural-Forms:': 'Plural-Forms:',
'Powered by': 'Powered by', 'Powered by': 'Powered by',
'previous 100 rows': '100 righe precedenti', 'previous 100 rows': '100 righe precedenti',
'private files': 'private files',
'Private files': 'Private files', 'Private files': 'Private files',
'private files': 'private files',
'Query:': 'Richiesta (query):', 'Query:': 'Richiesta (query):',
'Rapid Search': 'Rapid Search',
'record': 'record', 'record': 'record',
'record does not exist': 'il record non esiste', 'record does not exist': 'il record non esiste',
'record id': 'ID del record', 'record id': 'ID del record',
'register': 'registrazione', 'register': 'registrazione',
'reload': 'reload', 'reload': 'reload',
'Reload routes': 'Reload routes',
'Remove compiled': 'rimozione codice compilato', 'Remove compiled': 'rimozione codice compilato',
'Replace': 'Replace',
'Replace All': 'Replace All',
'request': 'request', 'request': 'request',
'Resolve Conflict file': 'File di risoluzione conflitto', 'Resolve Conflict file': 'File di risoluzione conflitto',
'response': 'response', 'response': 'response',
@@ -237,6 +250,8 @@
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", "Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')",
'Running on %s': 'Running on %s', 'Running on %s': 'Running on %s',
'Save': 'Save', 'Save': 'Save',
'Save file:': 'Save file:',
'Save file: %s': 'Save file: %s',
'Save via Ajax': 'Save via Ajax', 'Save via Ajax': 'Save via Ajax',
'Saved file hash:': 'Hash del file salvato:', 'Saved file hash:': 'Hash del file salvato:',
'selected': 'selezionato', 'selected': 'selezionato',
@@ -245,23 +260,24 @@
'shell': 'shell', 'shell': 'shell',
'Site': 'sito', 'Site': 'sito',
'some files could not be removed': 'non è stato possibile rimuovere alcuni files', 'some files could not be removed': 'non è stato possibile rimuovere alcuni files',
'Start searching': 'Start searching',
'Start wizard': 'start wizard', 'Start wizard': 'start wizard',
'state': 'stato', 'state': 'stato',
'static': 'statico', 'static': 'statico',
'Static': 'Static', 'Static': 'Static',
'Static files': 'Files statici', 'Static files': 'Files statici',
'Stylesheet': 'Foglio di stile (stylesheet)', 'Stylesheet': 'Foglio di stile (stylesheet)',
'submit': 'invia',
'Submit': 'Submit', 'Submit': 'Submit',
'submit': 'invia',
'Sure you want to delete this object?': 'Vuoi veramente cancellare questo oggetto?', 'Sure you want to delete this object?': 'Vuoi veramente cancellare questo oggetto?',
'table': 'tabella', 'table': 'tabella',
'test': 'test', 'test': 'test',
'Testing application': 'Test applicazione in corsg', 'Testing application': 'Test applicazione in corsg',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La richiesta (query) è una condizione come ad esempio "db.tabella1.campo1==\'valore\'". Una condizione come "db.tabella1.campo1==db.tabella2.campo2" produce un "JOIN" SQL.', 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La richiesta (query) è una condizione come ad esempio "db.tabella1.campo1==\'valore\'". Una condizione come "db.tabella1.campo1==db.tabella2.campo2" produce un "JOIN" SQL.',
'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
'the application logic, each URL path is mapped in one exposed function in the controller': 'logica dell\'applicazione, ogni percorso "URL" corrisponde ad una funzione esposta da un controller', 'the application logic, each URL path is mapped in one exposed function in the controller': 'logica dell\'applicazione, ogni percorso "URL" corrisponde ad una funzione esposta da un controller',
'The data representation, define database tables and sets': 'The data representation, define database tables and sets', 'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
'the data representation, define database tables and sets': 'rappresentazione dei dati, definizione di tabelle di database e di "set" ', 'the data representation, define database tables and sets': 'rappresentazione dei dati, definizione di tabelle di database e di "set" ',
'The data representation, define database tables and sets': 'The data representation, define database tables and sets',
'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', 'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates',
'the presentations layer, views are also known as templates': 'Presentazione dell\'applicazione, viste (views, chiamate anche "templates")', 'the presentations layer, views are also known as templates': 'Presentazione dell\'applicazione, viste (views, chiamate anche "templates")',
'There are no controllers': 'Non ci sono controller', 'There are no controllers': 'Non ci sono controller',
@@ -273,8 +289,8 @@
'There are no translators, only default language is supported': 'Non ci sono traduzioni, viene solo supportato il linguaggio di base', 'There are no translators, only default language is supported': 'Non ci sono traduzioni, viene solo supportato il linguaggio di base',
'There are no views': 'Non ci sono viste ("view")', 'There are no views': 'Non ci sono viste ("view")',
'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', 'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app',
'these files are served without processing, your images go here': 'questi files vengono serviti così come sono, le immagini vanno qui',
'These files are served without processing, your images go here': 'These files are served without processing, your images go here', 'These files are served without processing, your images go here': 'These files are served without processing, your images go here',
'these files are served without processing, your images go here': 'questi files vengono serviti così come sono, le immagini vanno qui',
'This is the %(filename)s template': 'Questo è il template %(filename)s', 'This is the %(filename)s template': 'Questo è il template %(filename)s',
'Ticket': 'Ticket', 'Ticket': 'Ticket',
'Ticket ID': 'Ticket ID', 'Ticket ID': 'Ticket ID',
@@ -322,8 +338,8 @@
'Version %s.%s.%s (%s) %s': 'Version %s.%s.%s (%s) %s', 'Version %s.%s.%s (%s) %s': 'Version %s.%s.%s (%s) %s',
'versioning': 'sistema di versioni', 'versioning': 'sistema di versioni',
'Versioning': 'Versioning', 'Versioning': 'Versioning',
'view': 'vista',
'View': 'Vista', 'View': 'Vista',
'view': 'vista',
'Views': 'viste', 'Views': 'viste',
'views': 'viste', 'views': 'viste',
'Web Framework': 'Web Framework', 'Web Framework': 'Web Framework',
+46
View File
@@ -281,6 +281,52 @@ td.cbcentered>input, th.cbcentered>input { margin-top:-1px; }
.languageform input.untranslated { background-color:#FC0; } .languageform input.untranslated { background-color:#FC0; }
/*=============================================================
MASKED UPLOAD INPUT (NO BOOTSTRAP RELATED)
==============================================================*/
#appupdate_file.masked {
margin: 0;
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* IE 8 */
filter: alpha(opacity=0); /* IE 7 */
font-size: 100px;
position: absolute;
top: 0;
right: 0;
z-index: 410;
}
#fileselect {
padding: 4px 6px;
border: 1px solid #ccc;
border-radius: 4px;
color: #555;
cursor: default;
position: relative;
z-index: 400;
font-size: 14px;
background-color: #fff;
margin-bottom: 10px;
overflow: hidden;
}
#fileselect span {
position: absolute;
left: 6px;
top: 4px;
}
.uploadbtn {
position: absolute;
top: 3px;
right: 3px;
}
.txtPlaceholder {
font-style: italic;
color: #ccc;
}
/*============================================================= /*=============================================================
MEDIA QUERIES MEDIA QUERIES
==============================================================*/ ==============================================================*/
@@ -90,6 +90,7 @@ div.controls select +.error_wrapper {margin-left:5px;}
.ie-lte7 div.error{color:#fff;} .ie-lte7 div.error{color:#fff;}
/* beautify brand */ /* beautify brand */
.navbar {margin-bottom:0}
.navbar-inverse .brand{color:#c6cecc;} .navbar-inverse .brand{color:#c6cecc;}
.navbar-inverse .brand b{display:inline-block;margin-top:-1px;} .navbar-inverse .brand b{display:inline-block;margin-top:-1px;}
.navbar-inverse .brand b>span{font-size:22px;color:white} .navbar-inverse .brand b>span{font-size:22px;color:white}
@@ -222,6 +223,10 @@ td.w2p_fw ul{margin-left:0px;}
/* auth_user_remember checkbox extrapadding in IE fix */ /* auth_user_remember checkbox extrapadding in IE fix */
.ie-lte9 input#auth_user_remember.checkbox {padding-left:0;} .ie-lte9 input#auth_user_remember.checkbox {padding-left:0;}
div.controls .error {
width: auto;
}
/*============================================================= /*=============================================================
MEDIA QUERIES MEDIA QUERIES
==============================================================*/ ==============================================================*/
+242 -223
View File
@@ -1,262 +1,281 @@
function prepareDataForSave(name,data) { function prepareDataForSave(name, data) {
var obj = new Object(); var obj = new Object();
obj.Name = name; obj.Name = name;
obj.Data = data; obj.Data = data;
return obj; return obj;
} }
function prepareMultiPartPOST(data) { function prepareMultiPartPOST(data) {
// var boundary = 'sPlItME' + Math.floor(Math.random()*10000); // var boundary = 'sPlItME' + Math.floor(Math.random()*10000);
var boundary = '' + Math.floor(Math.random()*10000); var boundary = '' + Math.floor(Math.random() * 10000);
var reqdata = '--' + boundary + '\r\n'; var reqdata = '--' + boundary + '\r\n';
//console.log(data.length); //console.log(data.length);
for (var i=0;i < data.length;i++) { for(var i = 0; i < data.length; i++) {
reqdata += 'content-disposition: form-data; name="'; reqdata += 'content-disposition: form-data; name="';
reqdata += data[i].Name + '"'; reqdata += data[i].Name + '"';
reqdata += "\r\n\r\n" ; reqdata += "\r\n\r\n";
reqdata += data[i].Data; reqdata += data[i].Data;
reqdata += "\r\n" ; reqdata += "\r\n";
reqdata += '--' + boundary + '\r\n'; reqdata += '--' + boundary + '\r\n';
} }
return new Array(reqdata,boundary); return new Array(reqdata, boundary);
} }
function on_error() { function on_error() {
jQuery("input[name='saved_on']").attr('style','background-color:red'); jQuery("input[name='saved_on']").attr('style', 'background-color:red');
jQuery("input[name='saved_on']").val('communication error'); jQuery("input[name='saved_on']").val('communication error');
} }
function doHighlight(highlight) { function doHighlight(highlight) {
// Put the cursor at the offending line: // Put the cursor at the offending line:
editor.setCursor({line:highlight.lineno-1, editor.setCursor({
ch:highlight.offset+1}); line: highlight.lineno - 1,
} ch: highlight.offset + 1
});
}
function doClickSave() { function doClickSave() {
var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id'); var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id');
var editor = jQuery (currentTabID + ' textarea').data('editor'); var editor = jQuery(currentTabID + ' textarea').data('editor');
var data = editor.getValue(); var data = editor.getValue();
var dataForPost = prepareMultiPartPOST(new Array( var dataForPost = prepareMultiPartPOST(new Array(
prepareDataForSave('data', data), prepareDataForSave('data', data),
prepareDataForSave('file_hash', prepareDataForSave('file_hash',
jQuery(currentTabID + " input[name='file_hash']").val()), jQuery(currentTabID + " input[name='file_hash']").val()),
prepareDataForSave('saved_on', prepareDataForSave('saved_on',
jQuery(currentTabID + " input[name='saved_on']").val()), jQuery(currentTabID + " input[name='saved_on']").val()),
prepareDataForSave('saved_on', prepareDataForSave('saved_on',
jQuery(currentTabID + " input[name='saved_on']").val()), jQuery(currentTabID + " input[name='saved_on']").val()),
prepareDataForSave('from_ajax','true'))); prepareDataForSave('from_ajax', 'true')));
// console.info(area.textarea.value); // console.info(area.textarea.value);
jQuery(currentTabID + " input[name='saved_on']").attr('style', jQuery(currentTabID + " input[name='saved_on']").attr('style',
'background-color:yellow'); 'background-color:yellow');
jQuery(currentTabID + " input[name='saved_on']").val('saving now...') jQuery(currentTabID + " input[name='saved_on']").val('saving now...')
currentUrl = jQuery(currentTabID + ' form').attr('action'); currentUrl = jQuery(currentTabID + ' form').attr('action');
jQuery.ajax({ jQuery.ajax({
type: "POST", type: "POST",
contentType: 'multipart/form-data;boundary="' contentType: 'multipart/form-data;boundary="' + dataForPost[1] + '"',
+ dataForPost[1] + '"', url: currentUrl,
url: currentUrl, dataType: "json",
dataType: "json", data: dataForPost[0],
data: dataForPost[0], timeout: 5000,
timeout: 5000, beforeSend: function (xhr) {
beforeSend: function(xhr) { xhr.setRequestHeader('web2py-component-location',
xhr.setRequestHeader('web2py-component-location', document.location);
document.location); xhr.setRequestHeader('web2py-component-element',
xhr.setRequestHeader('web2py-component-element', 'doClickSave');
'doClickSave'); },
}, success: function (json, text, xhr) {
success: function(json,text,xhr){ jQuery(editor).data('saved', true); // Set as saved
jQuery(editor).data('saved', true); // Set as saved editor.on("change", store_changes_function); // Re-enable change watcher
editor.on("change", store_changes_function); // Re-enable change watcher // reenable disabled submit button
// reenable disabled submit button var t = jQuery("input[name='save']");
var t=jQuery("input[name='save']"); t.attr('class', '');
t.attr('class',''); t.attr('disabled', '');
t.attr('disabled',''); try {
try { if(json.error) {
if (json.error) { window.location.href = json.redirect;
window.location.href=json.redirect; } else {
} else { // console.info( json.file_hash );
// console.info( json.file_hash ); jQuery(currentTabID + " input[name='file_hash']").val(json.file_hash);
jQuery(currentTabID + " input[name='file_hash']").val(json.file_hash); jQuery(currentTabID + " input[name='saved_on']").val(json.saved_on);
jQuery(currentTabID + " input[name='saved_on']").val(json.saved_on); if(json.highlight) {
if (json.highlight) { doHighlight(json.highlight);
doHighlight(json.highlight); } else {
} else { jQuery(currentTabID + " input[name='saved_on']").attr('style', 'background-color:#99FF99');
jQuery(currentTabID + " input[name='saved_on']").attr('style','background-color:#99FF99'); //jQuery(".flash").delay(1000).fadeOut('slow');
//jQuery(".flash").delay(1000).fadeOut('slow'); }
} // console.info(jQuery("input[name='file_hash']").val());
// console.info(jQuery("input[name='file_hash']").val()); var output = '<b>exposes:</b> ';
var output = '<b>exposes:</b> '; for(var i in json.functions) {
for ( var i in json.functions) { output += ' <a target="_blank" href="/' + json.application + '/' + json.controller + '/' + json.functions[i] + '">' + json.functions[i] + '</a>,';
output += ' <a target="_blank" href="/' + json.application + '/' + json.controller + '/' + json.functions[i] + '">' + json.functions[i] + '</a>,'; }
} if(output != '<b>exposes:</b> ') {
if(output!='<b>exposes:</b> ') { jQuery(currentTabID + " .exposed").html(output.substring(0, output.length - 1));
jQuery(currentTabID + " .exposed").html( output.substring(0, output.length-1)); }
} }
} } catch(e) {
} catch(e) { on_error();} on_error();
}, }
error: function(json) { on_error(); } },
}); error: function (json) {
return false; on_error();
}
});
return false;
} }
function getActiveEditor() { function getActiveEditor() {
var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id'); var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id');
var editor = jQuery (currentTabID + ' textarea').data('editor'); var editor = jQuery(currentTabID + ' textarea').data('editor');
return editor; return editor;
} }
function getSelectionRange() { function getSelectionRange() {
var editor = getActiveEditor(); var editor = getActiveEditor();
var sel = {}; var sel = {};
sel['start'] = editor.getCursor(true).line; sel['start'] = editor.getCursor(true).line;
sel['end'] = editor.getCursor(false).line; sel['end'] = editor.getCursor(false).line;
sel['data'] = ''; sel['data'] = '';
return sel; return sel;
} }
function doToggleBreakpoint(filename, url, sel) { function doToggleBreakpoint(filename, url, sel) {
var editor = getActiveEditor(); var editor = getActiveEditor();
if (sel==null) { if(sel == null) {
// use cursor position to determine the breakpoint line // use cursor position to determine the breakpoint line
// (gutter already tell us the selected line) // (gutter already tell us the selected line)
sel = getSelectionRange(); sel = getSelectionRange();
}
var dataForPost = prepareMultiPartPOST(new Array(
prepareDataForSave('filename', filename),
prepareDataForSave('sel_start', sel["start"]),
prepareDataForSave('sel_end', sel["end"]),
prepareDataForSave('data', sel['data'])));
jQuery.ajax({
type: "POST",
contentType: 'multipart/form-data;boundary="' + dataForPost[1] + '"',
url: url,
dataType: "json",
data: dataForPost[0],
timeout: 5000,
beforeSend: function (xhr) {
xhr.setRequestHeader('web2py-component-location',
document.location);
xhr.setRequestHeader('web2py-component-element',
'doSetBreakpoint');
},
success: function (json, text, xhr) {
// show flash message (if any)
var flash = xhr.getResponseHeader('web2py-component-flash');
if(flash) {
jQuery('.flash').html(decodeURIComponent(flash))
.append('<a href="#" class="close">&times;</a>')
.slideDown();
} else jQuery('.flash').hide();
try {
if(json.error) {
window.location.href = json.redirect;
} else {
if(json.ok == true) {
// mark the breakpoint if ok=True
editor.setGutterMarker(json.lineno - 1, "breakpoints", makeMarker());
} else if(json.ok == false) {
// remove mark if ok=False
editor.setGutterMarker(json.lineno - 1, "breakpoints", null);
}
}
} catch(e) {
on_error();
}
},
error: function (json) {
on_error();
} }
var dataForPost = prepareMultiPartPOST(new Array( });
prepareDataForSave('filename', filename), return false;
prepareDataForSave('sel_start', sel["start"]),
prepareDataForSave('sel_end', sel["end"]),
prepareDataForSave('data', sel['data'])));
jQuery.ajax({
type: "POST",
contentType: 'multipart/form-data;boundary="'+dataForPost[1]+'"',
url: url,
dataType: "json",
data: dataForPost[0],
timeout: 5000,
beforeSend: function(xhr) {
xhr.setRequestHeader('web2py-component-location',
document.location);
xhr.setRequestHeader('web2py-component-element',
'doSetBreakpoint');},
success: function(json,text,xhr){
// show flash message (if any)
var flash=xhr.getResponseHeader('web2py-component-flash');
if (flash) {
jQuery('.flash').html(decodeURIComponent(flash))
.append('<a href="#" class="close">&times;</a>')
.slideDown();
}
else jQuery('.flash').hide();
try {
if (json.error) {
window.location.href=json.redirect;
} else {
if (json.ok==true) {
// mark the breakpoint if ok=True
editor.setGutterMarker(json.lineno-1, "breakpoints", makeMarker());
} else if (json.ok==false) {
// remove mark if ok=False
editor.setGutterMarker(json.lineno-1, "breakpoints", null);
}
}
} catch(e) { on_error(); }
},
error: function(json) { on_error(); }
});
return false;
} }
// on load, update all breakpoints markers: // on load, update all breakpoints markers:
function doListBreakpoints(filename, url, editor) { function doListBreakpoints(filename, url, editor) {
var dataForPost = prepareMultiPartPOST(new Array( var dataForPost = prepareMultiPartPOST(new Array(
prepareDataForSave('filename', filename) prepareDataForSave('filename', filename)
)); ));
jQuery.ajax({ jQuery.ajax({
type: "POST", type: "POST",
contentType: 'multipart/form-data;boundary="'+dataForPost[1]+'"', contentType: 'multipart/form-data;boundary="' + dataForPost[1] + '"',
url: url, url: url,
dataType: "json", dataType: "json",
data: dataForPost[0], data: dataForPost[0],
timeout: 5000, timeout: 5000,
beforeSend: function(xhr) { beforeSend: function (xhr) {
xhr.setRequestHeader('web2py-component-location', xhr.setRequestHeader('web2py-component-location',
document.location); document.location);
xhr.setRequestHeader('web2py-component-element', xhr.setRequestHeader('web2py-component-element',
'doListBreakpoints');}, 'doListBreakpoints');
success: function(json,text,xhr){ },
try { success: function (json, text, xhr) {
if (json.error) { try {
window.location.href=json.redirect; if(json.error) {
} else { window.location.href = json.redirect;
var editor = getActiveEditor(); } else {
for (i in json.breakpoints) { var editor = getActiveEditor();
lineno = json.breakpoints[i]; for(i in json.breakpoints) {
// mark the breakpoint if ok=True lineno = json.breakpoints[i];
editor.setGutterMarker(lineno-1, "breakpoints",makeMarker()); // mark the breakpoint if ok=True
} editor.setGutterMarker(lineno - 1, "breakpoints", makeMarker());
} }
} catch(e) { on_error(); } }
}, } catch(e) {
error: function(json) { on_error(); } on_error();
}); }
return false; },
error: function (json) {
on_error();
}
});
return false;
} }
function makeMarker() { function makeMarker() {
var marker = document.createElement("div"); var marker = document.createElement("div");
marker.style.color = "#822"; marker.style.color = "#822";
marker.innerHTML = "●"; marker.innerHTML = "●";
marker.className = "breakpoint"; marker.className = "breakpoint";
return marker; return marker;
} }
function keepalive(url) { function keepalive(url) {
jQuery.ajax({ jQuery.ajax({
type: "GET", type: "GET",
url: url, url: url,
timeout: 1000, timeout: 1000,
success: function(){}, success: function () {},
error: function(x) { on_error(); } }); error: function (x) {
on_error();
}
});
} }
function load_file (url) { function load_file(url) {
jQuery.ajax({ jQuery.ajax({
type: "GET", type: "GET",
dataType: 'json', dataType: 'json',
url: url, url: url,
timeout: 1000, timeout: 1000,
success: function(json){ success: function (json) {
if (typeof(json['plain_html']) !== undefined) { if(typeof (json['plain_html']) !== undefined) {
if (jQuery('#' + json['id']).length === 0 || json['force'] === true) { if(jQuery('#' + json['id']).length === 0 || json['force'] === true) {
// Create a tab and put the code in it // Create a tab and put the code in it
var tab_header = '<li><a href="#'+json['id']+'" data-toggle="tab">'+json['filename']+'<button type="button" class="close">&times;</button></a></li>'; var tab_header = '<li><a href="#' + json['id'] + '" data-toggle="tab">' + json['filename'] + '<button type="button" class="close">&times;</button></a></li>';
var tab_body = '<div id="' + json['id'] + '" class="tab-pane fade in " >' + json['plain_html'] + '</div>'; var tab_body = '<div id="' + json['id'] + '" class="tab-pane fade in " >' + json['plain_html'] + '</div>';
if (json['force'] === false) { if(json['force'] === false) {
jQuery('#filesTab').append(jQuery(tab_header)); jQuery('#filesTab').append(jQuery(tab_header));
jQuery('#myTabContent').append(jQuery(tab_body)); jQuery('#myTabContent').append(jQuery(tab_body));
} else { } else {
jQuery('#' + json['id']).html(jQuery(tab_body)); jQuery('#' + json['id']).html(jQuery(tab_body));
} }
} }
jQuery("a[href='#" + json['id'] + "']" ).click(); jQuery("a[href='#" + json['id'] + "']").click();
} }
}, },
error: function(x) { on_error(); } error: function (x) {
}); on_error();
}
});
} }
function set_font(editor, incr) { function set_font(editor, incr) {
var fontSize = ''; var fontSize = '';
if (incr !== 0) { if(incr !== 0) {
fontSize = parseInt(jQuery(editor.getWrapperElement()).css('font-size')); fontSize = parseInt(jQuery(editor.getWrapperElement()).css('font-size'));
fontSize = fontSize + incr + "px"; fontSize = fontSize + incr + "px";
} }
jQuery(editor.getWrapperElement()).css('font-size', fontSize); jQuery(editor.getWrapperElement()).css('font-size', fontSize);
editor.refresh(); editor.refresh();
} }
var template_js = '<p class="repo-name">{{{a_tag}}}</p><small>{{address}}</small>'; var template_js = '<p class="repo-name">{{{a_tag}}}</p><small>{{address}}</small>';
+1 -562
View File
@@ -12,565 +12,4 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
var Hogan={};(function(a,b){function i(a){return String(a===null||a===undefined?"":a)}function j(a){return a=i(a),h.test(a)?a.replace(c,"&amp;").replace(d,"&lt;").replace(e,"&gt;").replace(f,"&#39;").replace(g,"&quot;"):a}a.Template=function(a,c,d,e){this.r=a||this.r,this.c=d,this.options=e,this.text=c||"",this.buf=b?[]:""},a.Template.prototype={r:function(a,b,c){return""},v:j,t:i,render:function(b,c,d){return this.ri([b],c||{},d)},ri:function(a,b,c){return this.r(a,b,c)},rp:function(a,b,c,d){var e=c[a];return e?(this.c&&typeof e=="string"&&(e=this.c.compile(e,this.options)),e.ri(b,c,d)):""},rs:function(a,b,c){var d=a[a.length-1];if(!k(d)){c(a,b,this);return}for(var e=0;e<d.length;e++)a.push(d[e]),c(a,b,this),a.pop()},s:function(a,b,c,d,e,f,g){var h;return k(a)&&a.length===0?!1:(typeof a=="function"&&(a=this.ls(a,b,c,d,e,f,g)),h=a===""||!!a,!d&&h&&b&&b.push(typeof a=="object"?a:b[b.length-1]),h)},d:function(a,b,c,d){var e=a.split("."),f=this.f(e[0],b,c,d),g=null;if(a==="."&&k(b[b.length-2]))return b[b.length-1];for(var h=1;h<e.length;h++)f&&typeof f=="object"&&e[h]in f?(g=f,f=f[e[h]]):f="";return d&&!f?!1:(!d&&typeof f=="function"&&(b.push(g),f=this.lv(f,b,c),b.pop()),f)},f:function(a,b,c,d){var e=!1,f=null,g=!1;for(var h=b.length-1;h>=0;h--){f=b[h];if(f&&typeof f=="object"&&a in f){e=f[a],g=!0;break}}return g?(!d&&typeof e=="function"&&(e=this.lv(e,b,c)),e):d?!1:""},ho:function(a,b,c,d,e){var f=this.c,g=this.options;g.delimiters=e;var d=a.call(b,d);return d=d==null?String(d):d.toString(),this.b(f.compile(d,g).render(b,c)),!1},b:b?function(a){this.buf.push(a)}:function(a){this.buf+=a},fl:b?function(){var a=this.buf.join("");return this.buf=[],a}:function(){var a=this.buf;return this.buf="",a},ls:function(a,b,c,d,e,f,g){var h=b[b.length-1],i=null;if(!d&&this.c&&a.length>0)return this.ho(a,h,c,this.text.substring(e,f),g);i=a.call(h);if(typeof i=="function"){if(d)return!0;if(this.c)return this.ho(i,h,c,this.text.substring(e,f),g)}return i},lv:function(a,b,c){var d=b[b.length-1],e=a.call(d);if(typeof e=="function"){e=i(e.call(d));if(this.c&&~e.indexOf("{{"))return this.c.compile(e,this.options).render(d,c)}return i(e)}};var c=/&/g,d=/</g,e=/>/g,f=/\'/g,g=/\"/g,h=/[&<>\"\']/,k=Array.isArray||function(a){return Object.prototype.toString.call(a)==="[object Array]"}})(typeof exports!="undefined"?exports:Hogan),function(a){function h(a){a.n.substr(a.n.length-1)==="}"&&(a.n=a.n.substring(0,a.n.length-1))}function i(a){return a.trim?a.trim():a.replace(/^\s*|\s*$/g,"")}function j(a,b,c){if(b.charAt(c)!=a.charAt(0))return!1;for(var d=1,e=a.length;d<e;d++)if(b.charAt(c+d)!=a.charAt(d))return!1;return!0}function k(a,b,c,d){var e=[],f=null,g=null;while(a.length>0){g=a.shift();if(g.tag=="#"||g.tag=="^"||l(g,d))c.push(g),g.nodes=k(a,g.tag,c,d),e.push(g);else{if(g.tag=="/"){if(c.length===0)throw new Error("Closing tag without opener: /"+g.n);f=c.pop();if(g.n!=f.n&&!m(g.n,f.n,d))throw new Error("Nesting error: "+f.n+" vs. "+g.n);return f.end=g.i,e}e.push(g)}}if(c.length>0)throw new Error("missing closing tag: "+c.pop().n);return e}function l(a,b){for(var c=0,d=b.length;c<d;c++)if(b[c].o==a.n)return a.tag="#",!0}function m(a,b,c){for(var d=0,e=c.length;d<e;d++)if(c[d].c==a&&c[d].o==b)return!0}function n(a){return a.replace(f,"\\\\").replace(c,'\\"').replace(d,"\\n").replace(e,"\\r")}function o(a){return~a.indexOf(".")?"d":"f"}function p(a){var b="";for(var c=0,d=a.length;c<d;c++){var e=a[c].tag;e=="#"?b+=q(a[c].nodes,a[c].n,o(a[c].n),a[c].i,a[c].end,a[c].otag+" "+a[c].ctag):e=="^"?b+=r(a[c].nodes,a[c].n,o(a[c].n)):e=="<"||e==">"?b+=s(a[c]):e=="{"||e=="&"?b+=t(a[c].n,o(a[c].n)):e=="\n"?b+=v('"\\n"'+(a.length-1==c?"":" + i")):e=="_v"?b+=u(a[c].n,o(a[c].n)):e===undefined&&(b+=v('"'+n(a[c])+'"'))}return b}function q(a,b,c,d,e,f){return"if(_.s(_."+c+'("'+n(b)+'",c,p,1),'+"c,p,0,"+d+","+e+',"'+f+'")){'+"_.rs(c,p,"+"function(c,p,_){"+p(a)+"});c.pop();}"}function r(a,b,c){return"if(!_.s(_."+c+'("'+n(b)+'",c,p,1),c,p,1,0,0,"")){'+p(a)+"};"}function s(a){return'_.b(_.rp("'+n(a.n)+'",c,p,"'+(a.indent||"")+'"));'}function t(a,b){return"_.b(_.t(_."+b+'("'+n(a)+'",c,p,0)));'}function u(a,b){return"_.b(_.v(_."+b+'("'+n(a)+'",c,p,0)));'}function v(a){return"_.b("+a+");"}var b=/\S/,c=/\"/g,d=/\n/g,e=/\r/g,f=/\\/g,g={"#":1,"^":2,"/":3,"!":4,">":5,"<":6,"=":7,_v:8,"{":9,"&":10};a.scan=function(c,d){function w(){p.length>0&&(q.push(new String(p)),p="")}function x(){var a=!0;for(var c=t;c<q.length;c++){a=q[c].tag&&g[q[c].tag]<g._v||!q[c].tag&&q[c].match(b)===null;if(!a)return!1}return a}function y(a,b){w();if(a&&x())for(var c=t,d;c<q.length;c++)q[c].tag||((d=q[c+1])&&d.tag==">"&&(d.indent=q[c].toString()),q.splice(c,1));else b||q.push({tag:"\n"});r=!1,t=q.length}function z(a,b){var c="="+v,d=a.indexOf(c,b),e=i(a.substring(a.indexOf("=",b)+1,d)).split(" ");return u=e[0],v=e[1],d+c.length-1}var e=c.length,f=0,k=1,l=2,m=f,n=null,o=null,p="",q=[],r=!1,s=0,t=0,u="{{",v="}}";d&&(d=d.split(" "),u=d[0],v=d[1]);for(s=0;s<e;s++)m==f?j(u,c,s)?(--s,w(),m=k):cLine truncated
var Hogan = {};
(function (Hogan, useArrayBuffer) {
Hogan.Template = function (renderFunc, text, compiler, options) {
this.r = renderFunc || this.r;
this.c = compiler;
this.options = options;
this.text = text || '';
this.buf = (useArrayBuffer) ? [] : '';
}
Hogan.Template.prototype = {
// render: replaced by generated code.
r: function (context, partials, indent) { return ''; },
// variable escaping
v: hoganEscape,
// triple stache
t: coerceToString,
render: function render(context, partials, indent) {
return this.ri([context], partials || {}, indent);
},
// render internal -- a hook for overrides that catches partials too
ri: function (context, partials, indent) {
return this.r(context, partials, indent);
},
// tries to find a partial in the curent scope and render it
rp: function(name, context, partials, indent) {
var partial = partials[name];
if (!partial) {
return '';
}
if (this.c && typeof partial == 'string') {
partial = this.c.compile(partial, this.options);
}
return partial.ri(context, partials, indent);
},
// render a section
rs: function(context, partials, section) {
var tail = context[context.length - 1];
if (!isArray(tail)) {
section(context, partials, this);
return;
}
for (var i = 0; i < tail.length; i++) {
context.push(tail[i]);
section(context, partials, this);
context.pop();
}
},
// maybe start a section
s: function(val, ctx, partials, inverted, start, end, tags) {
var pass;
if (isArray(val) && val.length === 0) {
return false;
}
if (typeof val == 'function') {
val = this.ls(val, ctx, partials, inverted, start, end, tags);
}
pass = (val === '') || !!val;
if (!inverted && pass && ctx) {
ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
}
return pass;
},
// find values with dotted names
d: function(key, ctx, partials, returnFound) {
var names = key.split('.'),
val = this.f(names[0], ctx, partials, returnFound),
cx = null;
if (key === '.' && isArray(ctx[ctx.length - 2])) {
return ctx[ctx.length - 1];
}
for (var i = 1; i < names.length; i++) {
if (val && typeof val == 'object' && names[i] in val) {
cx = val;
val = val[names[i]];
} else {
val = '';
}
}
if (returnFound && !val) {
return false;
}
if (!returnFound && typeof val == 'function') {
ctx.push(cx);
val = this.lv(val, ctx, partials);
ctx.pop();
}
return val;
},
// find values with normal names
f: function(key, ctx, partials, returnFound) {
var val = false,
v = null,
found = false;
for (var i = ctx.length - 1; i >= 0; i--) {
v = ctx[i];
if (v && typeof v == 'object' && key in v) {
val = v[key];
found = true;
break;
}
}
if (!found) {
return (returnFound) ? false : "";
}
if (!returnFound && typeof val == 'function') {
val = this.lv(val, ctx, partials);
}
return val;
},
// higher order templates
ho: function(val, cx, partials, text, tags) {
var compiler = this.c;
var options = this.options;
options.delimiters = tags;
var text = val.call(cx, text);
text = (text == null) ? String(text) : text.toString();
this.b(compiler.compile(text, options).render(cx, partials));
return false;
},
// template result buffering
b: (useArrayBuffer) ? function(s) { this.buf.push(s); } :
function(s) { this.buf += s; },
fl: (useArrayBuffer) ? function() { var r = this.buf.join(''); this.buf = []; return r; } :
function() { var r = this.buf; this.buf = ''; return r; },
// lambda replace section
ls: function(val, ctx, partials, inverted, start, end, tags) {
var cx = ctx[ctx.length - 1],
t = null;
if (!inverted && this.c && val.length > 0) {
return this.ho(val, cx, partials, this.text.substring(start, end), tags);
}
t = val.call(cx);
if (typeof t == 'function') {
if (inverted) {
return true;
} else if (this.c) {
return this.ho(t, cx, partials, this.text.substring(start, end), tags);
}
}
return t;
},
// lambda replace variable
lv: function(val, ctx, partials) {
var cx = ctx[ctx.length - 1];
var result = val.call(cx);
if (typeof result == 'function') {
result = coerceToString(result.call(cx));
if (this.c && ~result.indexOf("{\u007B")) {
return this.c.compile(result, this.options).render(cx, partials);
}
}
return coerceToString(result);
}
};
var rAmp = /&/g,
rLt = /</g,
rGt = />/g,
rApos =/\'/g,
rQuot = /\"/g,
hChars =/[&<>\"\']/;
function coerceToString(val) {
return String((val === null || val === undefined) ? '' : val);
}
function hoganEscape(str) {
str = coerceToString(str);
return hChars.test(str) ?
str
.replace(rAmp,'&amp;')
.replace(rLt,'&lt;')
.replace(rGt,'&gt;')
.replace(rApos,'&#39;')
.replace(rQuot, '&quot;') :
str;
}
var isArray = Array.isArray || function(a) {
return Object.prototype.toString.call(a) === '[object Array]';
};
})(typeof exports !== 'undefined' ? exports : Hogan);
(function (Hogan) {
// Setup regex assignments
// remove whitespace according to Mustache spec
var rIsWhitespace = /\S/,
rQuot = /\"/g,
rNewline = /\n/g,
rCr = /\r/g,
rSlash = /\\/g,
tagTypes = {
'#': 1, '^': 2, '/': 3, '!': 4, '>': 5,
'<': 6, '=': 7, '_v': 8, '{': 9, '&': 10
};
Hogan.scan = function scan(text, delimiters) {
var len = text.length,
IN_TEXT = 0,
IN_TAG_TYPE = 1,
IN_TAG = 2,
state = IN_TEXT,
tagType = null,
tag = null,
buf = '',
tokens = [],
seenTag = false,
i = 0,
lineStart = 0,
otag = '{{',
ctag = '}}';
function addBuf() {
if (buf.length > 0) {
tokens.push(new String(buf));
buf = '';
}
}
function lineIsWhitespace() {
var isAllWhitespace = true;
for (var j = lineStart; j < tokens.length; j++) {
isAllWhitespace =
(tokens[j].tag && tagTypes[tokens[j].tag] < tagTypes['_v']) ||
(!tokens[j].tag && tokens[j].match(rIsWhitespace) === null);
if (!isAllWhitespace) {
return false;
}
}
return isAllWhitespace;
}
function filterLine(haveSeenTag, noNewLine) {
addBuf();
if (haveSeenTag && lineIsWhitespace()) {
for (var j = lineStart, next; j < tokens.length; j++) {
if (!tokens[j].tag) {
if ((next = tokens[j+1]) && next.tag == '>') {
// set indent to token value
next.indent = tokens[j].toString()
}
tokens.splice(j, 1);
}
}
} else if (!noNewLine) {
tokens.push({tag:'\n'});
}
seenTag = false;
lineStart = tokens.length;
}
function changeDelimiters(text, index) {
var close = '=' + ctag,
closeIndex = text.indexOf(close, index),
delimiters = trim(
text.substring(text.indexOf('=', index) + 1, closeIndex)
).split(' ');
otag = delimiters[0];
ctag = delimiters[1];
return closeIndex + close.length - 1;
}
if (delimiters) {
delimiters = delimiters.split(' ');
otag = delimiters[0];
ctag = delimiters[1];
}
for (i = 0; i < len; i++) {
if (state == IN_TEXT) {
if (tagChange(otag, text, i)) {
--i;
addBuf();
state = IN_TAG_TYPE;
} else {
if (text.charAt(i) == '\n') {
filterLine(seenTag);
} else {
buf += text.charAt(i);
}
}
} else if (state == IN_TAG_TYPE) {
i += otag.length - 1;
tag = tagTypes[text.charAt(i + 1)];
tagType = tag ? text.charAt(i + 1) : '_v';
if (tagType == '=') {
i = changeDelimiters(text, i);
state = IN_TEXT;
} else {
if (tag) {
i++;
}
state = IN_TAG;
}
seenTag = i;
} else {
if (tagChange(ctag, text, i)) {
tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
i: (tagType == '/') ? seenTag - ctag.length : i + otag.length});
buf = '';
i += ctag.length - 1;
state = IN_TEXT;
if (tagType == '{') {
if (ctag == '}}') {
i++;
} else {
cleanTripleStache(tokens[tokens.length - 1]);
}
}
} else {
buf += text.charAt(i);
}
}
}
filterLine(seenTag, true);
return tokens;
}
function cleanTripleStache(token) {
if (token.n.substr(token.n.length - 1) === '}') {
token.n = token.n.substring(0, token.n.length - 1);
}
}
function trim(s) {
if (s.trim) {
return s.trim();
}
return s.replace(/^\s*|\s*$/g, '');
}
function tagChange(tag, text, index) {
if (text.charAt(index) != tag.charAt(0)) {
return false;
}
for (var i = 1, l = tag.length; i < l; i++) {
if (text.charAt(index + i) != tag.charAt(i)) {
return false;
}
}
return true;
}
function buildTree(tokens, kind, stack, customTags) {
var instructions = [],
opener = null,
token = null;
while (tokens.length > 0) {
token = tokens.shift();
if (token.tag == '#' || token.tag == '^' || isOpener(token, customTags)) {
stack.push(token);
token.nodes = buildTree(tokens, token.tag, stack, customTags);
instructions.push(token);
} else if (token.tag == '/') {
if (stack.length === 0) {
throw new Error('Closing tag without opener: /' + token.n);
}
opener = stack.pop();
if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
}
opener.end = token.i;
return instructions;
} else {
instructions.push(token);
}
}
if (stack.length > 0) {
throw new Error('missing closing tag: ' + stack.pop().n);
}
return instructions;
}
function isOpener(token, tags) {
for (var i = 0, l = tags.length; i < l; i++) {
if (tags[i].o == token.n) {
token.tag = '#';
return true;
}
}
}
function isCloser(close, open, tags) {
for (var i = 0, l = tags.length; i < l; i++) {
if (tags[i].c == close && tags[i].o == open) {
return true;
}
}
}
Hogan.generate = function (tree, text, options) {
var code = 'var _=this;_.b(i=i||"");' + walk(tree) + 'return _.fl();';
if (options.asString) {
return 'function(c,p,i){' + code + ';}';
}
return new Hogan.Template(new Function('c', 'p', 'i', code), text, Hogan, options);
}
function esc(s) {
return s.replace(rSlash, '\\\\')
.replace(rQuot, '\\\"')
.replace(rNewline, '\\n')
.replace(rCr, '\\r');
}
function chooseMethod(s) {
return (~s.indexOf('.')) ? 'd' : 'f';
}
function walk(tree) {
var code = '';
for (var i = 0, l = tree.length; i < l; i++) {
var tag = tree[i].tag;
if (tag == '#') {
code += section(tree[i].nodes, tree[i].n, chooseMethod(tree[i].n),
tree[i].i, tree[i].end, tree[i].otag + " " + tree[i].ctag);
} else if (tag == '^') {
code += invertedSection(tree[i].nodes, tree[i].n,
chooseMethod(tree[i].n));
} else if (tag == '<' || tag == '>') {
code += partial(tree[i]);
} else if (tag == '{' || tag == '&') {
code += tripleStache(tree[i].n, chooseMethod(tree[i].n));
} else if (tag == '\n') {
code += text('"\\n"' + (tree.length-1 == i ? '' : ' + i'));
} else if (tag == '_v') {
code += variable(tree[i].n, chooseMethod(tree[i].n));
} else if (tag === undefined) {
code += text('"' + esc(tree[i]) + '"');
}
}
return code;
}
function section(nodes, id, method, start, end, tags) {
return 'if(_.s(_.' + method + '("' + esc(id) + '",c,p,1),' +
'c,p,0,' + start + ',' + end + ',"' + tags + '")){' +
'_.rs(c,p,' +
'function(c,p,_){' +
walk(nodes) +
'});c.pop();}';
}
function invertedSection(nodes, id, method) {
return 'if(!_.s(_.' + method + '("' + esc(id) + '",c,p,1),c,p,1,0,0,"")){' +
walk(nodes) +
'};';
}
function partial(tok) {
return '_.b(_.rp("' + esc(tok.n) + '",c,p,"' + (tok.indent || '') + '"));';
}
function tripleStache(id, method) {
return '_.b(_.t(_.' + method + '("' + esc(id) + '",c,p,0)));';
}
function variable(id, method) {
return '_.b(_.v(_.' + method + '("' + esc(id) + '",c,p,0)));';
}
function text(id) {
return '_.b(' + id + ');';
}
Hogan.parse = function(tokens, text, options) {
options = options || {};
return buildTree(tokens, '', [], options.sectionTags || []);
},
Hogan.cache = {};
Hogan.compile = function(text, options) {
// options
//
// asString: false (default)
//
// sectionTags: [{o: '_foo', c: 'foo'}]
// An array of object with o and c fields that indicate names for custom
// section tags. The example above allows parsing of {{_foo}}{{/foo}}.
//
// delimiters: A string that overrides the default delimiters.
// Example: "<% %>"
//
options = options || {};
var key = text + '||' + !!options.asString;
var t = this.cache[key];
if (t) {
return t;
}
t = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
return this.cache[key] = t;
};
})(typeof exports !== 'undefined' ? exports : Hogan);
+70 -61
View File
@@ -7,6 +7,10 @@
* Released under the MIT license * Released under the MIT license
* *
*/ */
if($.web2py !== undefined) {
$.error('web2py.js has already been loaded!');
}
String.prototype.reverse = function () { String.prototype.reverse = function () {
return this.split('').reverse().join(''); return this.split('').reverse().join('');
@@ -36,12 +40,13 @@
} }
} else { } else {
pcs = []; pcs = [];
if(s != null && s != undefined) for(i = 0; i < s.length; i++) { if(s != null && s != undefined)
for(i = 0; i < s.length; i++) {
q = $("[name=" + s[i] + "]").serialize(); q = $("[name=" + s[i] + "]").serialize();
if(q) { if(q) {
pcs.push(q); pcs.push(q);
} }
} }
if(pcs.length > 0) { if(pcs.length > 0) {
query = pcs.join("&"); query = pcs.join("&");
} }
@@ -147,9 +152,9 @@
web2py.component_handler(target); web2py.component_handler(target);
}, },
//manage errors in forms //manage errors in forms
manage_errors: function(target) { manage_errors: function (target) {
$('.error', target).hide().slideDown('slow'); $('.error', target).hide().slideDown('slow');
//$('.error', target).hide().fadeIn('slow'); //jQuery('.error', target).hide().fadeIn('slow');
}, },
event_handlers: function () { event_handlers: function () {
/* This is called once for page /* This is called once for page
@@ -172,7 +177,8 @@
}); });
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?"; var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
doc.on('click', "input[type='checkbox'].delete", function () { doc.on('click', "input[type='checkbox'].delete", function () {
if(this.checked) if(!web2py.confirm(confirm_message)) this.checked = false; if(this.checked)
if(!web2py.confirm(confirm_message)) this.checked = false;
}); });
doc.ajaxSuccess(function (e, xhr) { doc.ajaxSuccess(function (e, xhr) {
@@ -424,7 +430,7 @@
el.addClass('disabled'); el.addClass('disabled');
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
// store enabled state // store enabled state
el.data('w2p:enable-with', el[method]); el.data('w2p:enable-with', el[method]());
/* little addition by default*/ /* little addition by default*/
if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
el.data('w2p_disable_with', 'Working...'); el.data('w2p_disable_with', 'Working...');
@@ -441,7 +447,7 @@
enableElement: function (el) { enableElement: function (el) {
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
if(el.data('w2p:enable-with') !== undefined) { if(el.data('w2p:enable-with') !== undefined) {
// set to old enabled state // set to old enabled state
el[method](el.data('w2p:enable-with')); el[method](el.data('w2p:enable-with'));
el.removeData('w2p:enable-with'); // clean up cache el.removeData('w2p:enable-with'); // clean up cache
} }
@@ -453,39 +459,39 @@
web2py.component(action, target, 0, 1, element); web2py.component(action, target, 0, 1, element);
}, },
//helper for flash messages //helper for flash messages
flash: function(message, status) { flash: function (message, status) {
var flash = $('.flash'); var flash = $('.flash');
web2py.hide_flash(); web2py.hide_flash();
flash.html(message).addClass(status); flash.html(message).addClass(status);
if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown(); if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown();
}, },
hide_flash: function() { hide_flash: function () {
$('.flash').hide().html(''); $('.flash').hide().html('');
}, },
show_if_handler: function(target) { show_if_handler: function (target) {
var triggers = {}; var triggers = {};
var show_if = function () { var show_if = function () {
var t = $(this); var t = $(this);
var id = t.attr('id'); var id = t.attr('id');
t.attr('value', t.val()); t.attr('value', t.val());
for(var k = 0; k < triggers[id].length; k++) { for(var k = 0; k < triggers[id].length; k++) {
var dep = $('#' + triggers[id][k], target); var dep = $('#' + triggers[id][k], target);
var tr = $('#' + triggers[id][k] + '__row', target); var tr = $('#' + triggers[id][k] + '__row', target);
if(t.is(dep.attr('data-show-if'))) tr.slideDown(); if(t.is(dep.attr('data-show-if'))) tr.slideDown();
else tr.hide(); else tr.hide();
} }
}; };
$('[data-show-trigger]', target).each(function () { $('[data-show-trigger]', target).each(function () {
var name = $(this).attr('data-show-trigger'); var name = $(this).attr('data-show-trigger');
if(!triggers[name]) triggers[name] = []; if(!triggers[name]) triggers[name] = [];
triggers[name].push($(this).attr('id')); triggers[name].push($(this).attr('id'));
}); });
for(var name in triggers) { for(var name in triggers) {
$('#' + name, target).change(show_if).keyup(show_if); $('#' + name, target).change(show_if).keyup(show_if);
show_if.call($('#' + name, target)); show_if.call($('#' + name, target));
}; };
}, },
component_handler : function (target) { component_handler: function (target) {
$('div[data-w2p_remote]', target).each(function () { $('div[data-w2p_remote]', target).each(function () {
var remote, times, timeout, target; var remote, times, timeout, target;
var el = $(this); var el = $(this);
@@ -494,8 +500,7 @@
timeout = el.data('w2p_timeout'); timeout = el.data('w2p_timeout');
target = el.attr('id'); target = el.attr('id');
web2py.component(remote, target, timeout, times, $(this)); web2py.component(remote, target, timeout, times, $(this));
} })
)
}, },
a_handler: function (el, e) { a_handler: function (el, e) {
e.preventDefault(); e.preventDefault();
@@ -517,14 +522,16 @@
} }
if(target == undefined) { if(target == undefined) {
if(method == 'GET') { if(method == 'GET') {
web2py.simple_component(action, el.attr('id'), el); //not working with original web2py.ajax_page('get', action, [], 'bogus', el); //fixme?
//web2py.simple_component(action, el.attr('id'), el); //not working with original
} else if(method == 'POST') { } else if(method == 'POST') {
//should be web2py.ajax(action, [], ''); but it's too simple //should be web2py.ajax(action, [], ''); but it's too simple
web2py.ajax_page('post', action, [], 'bogus', el); //fixme? web2py.ajax_page('post', action, [], 'bogus', el); //fixme?
} }
} else { } else {
if(method == 'GET') { if(method == 'GET') {
web2py.simple_component(action, target, el); web2py.ajax_page('get', action, [], target, el);
//web2py.simple_component(action, target, el);
} else if(method == 'POST') { } else if(method == 'POST') {
//should be web2py.ajax(action, [], target); but it's too simple //should be web2py.ajax(action, [], target); but it's too simple
web2py.ajax_page('post', action, [], target, el); web2py.ajax_page('post', action, [], target, el);
@@ -539,7 +546,7 @@
toremove = el.closest(toremove); toremove = el.closest(toremove);
if(!toremove.length) { if(!toremove.length) {
//this enables removal of whatever selector if a closest is not found //this enables removal of whatever selector if a closest is not found
toremove = $(toremove); toremove = jQuery(toremove);
} }
toremove.remove(); toremove.remove();
} }
@@ -571,16 +578,17 @@
web2py.enableElement($(this)); web2py.enableElement($(this));
}); });
}, },
/* Disables form elements: /* Disables form elements:
- Caches element value in 'ujs:enable-with' data store - Caches element value in 'ujs:enable-with' data store
- Replaces element text with value of 'data-disable-with' attribute - Replaces element text with value of 'data-disable-with' attribute
- Sets disabled property to true - Sets disabled property to true
*/ */
disableFormElements: function(form) { disableFormElements: function (form) {
form.find(web2py.disableSelector).each(function() { form.find(web2py.disableSelector).each(function () {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this),
method = element.is('button') ? 'html' : 'val';
var disable_with = element.data('w2p_disable_with'); var disable_with = element.data('w2p_disable_with');
if (disable_with == undefined) { if(disable_with == undefined) {
element.data('w2p_disable_with', element[method]()) element.data('w2p_disable_with', element[method]())
} }
element.data('w2p:enable-with', element[method]()); element.data('w2p:enable-with', element[method]());
@@ -593,14 +601,15 @@
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Sets disabled property to false - Sets disabled property to false
*/ */
enableFormElements: function(form) { enableFormElements: function (form) {
form.find(web2py.enableSelector).each(function() { form.find(web2py.enableSelector).each(function () {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this),
if (element.data('w2p:enable-with')) element[method](element.data('w2p:enable-with')); method = element.is('button') ? 'html' : 'val';
if(element.data('w2p:enable-with')) element[method](element.data('w2p:enable-with'));
element.prop('disabled', false); element.prop('disabled', false);
}); });
}, },
form_handlers: function() { form_handlers: function () {
var el = $(document); var el = $(document);
el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) {
web2py.disableFormElements($(this)); web2py.disableFormElements($(this));
@@ -626,28 +635,28 @@
})(jQuery); })(jQuery);
/* compatibility code - start */ /* compatibility code - start */
ajax = $.web2py.ajax; ajax = jQuery.web2py.ajax;
web2py_component = $.web2py.component; web2py_component = jQuery.web2py.component;
web2py_websocket = $.web2py.websocket; web2py_websocket = jQuery.web2py.websocket;
web2py_ajax_page = $.web2py.ajax_page; web2py_ajax_page = jQuery.web2py.ajax_page;
//needed for IS_STRONG(entropy) //needed for IS_STRONG(entropy)
web2py_validate_entropy = $.web2py.validate_entropy; web2py_validate_entropy = jQuery.web2py.validate_entropy;
//needed for crud.search and SQLFORM.grid's search //needed for crud.search and SQLFORM.grid's search
web2py_ajax_fields = $.web2py.ajax_fields; web2py_ajax_fields = jQuery.web2py.ajax_fields;
//used for LOAD(ajax=False) //used for LOAD(ajax=False)
web2py_trap_form = $.web2py.trap_form; web2py_trap_form = jQuery.web2py.trap_form;
/*undocumented - rare*/ /*undocumented - rare*/
popup = $.web2py.popup; popup = jQuery.web2py.popup;
collapse = $.web2py.collapse; collapse = jQuery.web2py.collapse;
fade = $.web2py.fade; fade = jQuery.web2py.fade;
/* internals - shouldn't be needed /* internals - shouldn't be needed
web2py_ajax_init = $.web2py.ajax_init; web2py_ajax_init = jQuery.web2py.ajax_init;
web2py_event_handlers = $.web2py.event_handlers; web2py_event_handlers = jQuery.web2py.event_handlers;
web2py_trap_link = $.web2py.trap_link; web2py_trap_link = jQuery.web2py.trap_link;
web2py_calc_entropy = $.web2py.calc_entropy; web2py_calc_entropy = jQuery.web2py.calc_entropy;
*/ */
/* compatibility code - end*/ /* compatibility code - end*/
@@ -1,2 +0,0 @@
/*! jQuery Mobile vGit Build: SHA1: c2d61e2e592c67519d9a9ed0ba796fa44787e136 <> Date: Tue Sep 25 10:38:12 2012 -0700 jquerymobile.com | jquery.org/license !*/
.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:bold;text-shadow:0 -1px 1px #000;background-image:-webkit-gradient(linear,left top,left bottom,from( #3c3c3c ),to( #111 ));background-image:-webkit-linear-gradient( #3c3c3c,#111 );background-image:-moz-linear-gradient( #3c3c3c,#111 );background-image:-ms-linear-gradient( #3c3c3c,#111 );background-image:-o-linear-gradient( #3c3c3c,#111 );background-image:linear-gradient( #3c3c3c,#111 )}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:bold}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 1px #111;font-weight:normal;background-image:-webkit-gradient(linear,left top,left bottom,from( #444 ),to( #222 ));background-image:-webkit-linear-gradient( #444,#222 );background-image:-moz-linear-gradient( #444,#222 );background-image:-ms-linear-gradient( #444,#222 );background-image:-o-linear-gradient( #444,#222 );background-image:linear-gradient( #444,#222 )}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:bold}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from( #444 ),to( #2d2d2d ));background-image:-webkit-linear-gradient( #444,#2d2d2d );background-image:-moz-linear-gradient( #444,#2d2d2d );background-image:-ms-linear-gradient( #444,#2d2d2d );background-image:-o-linear-gradient( #444,#2d2d2d );background-image:linear-gradient( #444,#2d2d2d )}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from( #555 ),to( #383838 ));background-image:-webkit-linear-gradient( #555,#383838 );background-image:-moz-linear-gradient( #555,#383838 );background-image:-ms-linear-gradient( #555,#383838 );background-image:-o-linear-gradient( #555,#383838 );background-image:linear-gradient( #555,#383838 )}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from( #202020 ),to( #2c2c2c ));background-image:-webkit-linear-gradient( #202020,#2c2c2c );background-image:-moz-linear-gradient( #202020,#2c2c2c );background-image:-ms-linear-gradient( #202020,#2c2c2c );background-image:-o-linear-gradient( #202020,#2c2c2c );background-image:linear-gradient( #202020,#2c2c2c )}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:bold;text-shadow:0 1px 1px #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from( #6facd5 ),to( #497bae ));background-image:-webkit-linear-gradient( #6facd5,#497bae );background-image:-moz-linear-gradient( #6facd5,#497bae );background-image:-ms-linear-gradient( #6facd5,#497bae );background-image:-o-linear-gradient( #6facd5,#497bae );background-image:linear-gradient( #6facd5,#497bae )}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:bold}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:normal;background-image:-webkit-gradient(linear,left top,left bottom,from( #ddd ),to( #ccc ));background-image:-webkit-linear-gradient( #ddd,#ccc );background-image:-moz-linear-gradient( #ddd,#ccc );background-image:-ms-linear-gradient( #ddd,#ccc );background-image:-o-linear-gradient( #ddd,#ccc );background-image:linear-gradient( #ddd,#ccc )}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:bold}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#24Line truncated
@@ -1,2 +0,0 @@
/*! jQuery Mobile vGit Build: SHA1: c2d61e2e592c67519d9a9ed0ba796fa44787e136 <> Date: Tue Sep 25 10:38:12 2012 -0700 jquerymobile.com | jquery.org/license !*/
(function(a,b,c){typeof define=="function"&&define.amd?define(["jquery"],function(d){return c(d,a,b),d.mobile}):c(a.jQuery,a,b)})(this,document,function(a,b,c,d){(function(a,b,d){var e={};a.mobile=a.extend({},{version:"1.2.0",ns:"",subPageUrlKey:"ui-page",activePageClass:"ui-page-active",activeBtnClass:"ui-btn-active",focusClass:"ui-focus",ajaxEnabled:!0,hashListeningEnabled:!0,linkBindingEnabled:!0,defaultPageTransition:"fade",maxTransitionWidth:!1,minScrollBack:250,touchOverflowEnabled:!1,defaultDialogTransition:"pop",pageLoadErrorMessage:"Error Loading Page",pageLoadErrorMessageTheme:"e",phonegapNavigationEnabled:!1,autoInitializePage:!0,pushStateEnabled:!0,ignoreContentEnabled:!1,orientationChangeEnabled:!0,buttonMarkup:{hoverDelay:200},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},silentScroll:function(d){a.type(d)!=="number"&&(d=a.mobile.defaultHomeScroll),a.event.special.scrollstart.enabled=!1,setTimeout(function(){b.scrollTo(0,d),a(c).trigger("silentscroll",{x:0,y:d})},20),setTimeout(function(){a.event.special.scrollstart.enabled=!0},150)},nsNormalizeDict:e,nsNormalize:function(b){if(!b)return;return e[b]||(e[b]=a.camelCase(a.mobile.ns+b))},getInheritedTheme:function(a,b){var c=a[0],d="",e=/ui-(bar|body|overlay)-([a-z])\b/,f,g;while(c){f=c.className||"";if(f&&(g=e.exec(f))&&(d=g[2]))break;c=c.parentNode}return d||b||"a"},closestPageData:function(a){return a.closest(':jqmData(role="page"), :jqmData(role="dialog")').data("page")},enhanceable:function(a){return this.haveParents(a,"enhance")},hijackable:function(a){return this.haveParents(a,"ajax")},haveParents:function(b,c){if(!a.mobile.ignoreContentEnabled)return b;var d=b.length,e=a(),f,g,h;for(var i=0;i<d;i++){g=b.eq(i),h=!1,f=b[i];while(f){var j=f.getAttribute?f.getAttribute("data-"+a.mobile.ns+c):"";if(j==="false"){h=!0;break}f=f.parentNode}h||(e=e.add(g))}return e},getScreenHeight:function(){return b.innerHeight||a(b).height()}},a.mobile),a.fn.jqmData=function(b,c){var e;return typeof b!="undefined"&&(b&&(b=a.mobile.nsNormalize(b)),arguments.length<2||c===d?e=this.data(b):e=this.data(b,c)),e},a.jqmData=function(b,c,d){var e;return typeof c!="undefined"&&(e=a.data(b,c?a.mobile.nsNormalize(c):c,d)),e},a.fn.jqmRemoveData=function(b){return this.removeData(a.mobile.nsNormalize(b))},a.jqmRemoveData=function(b,c){return a.removeData(b,a.mobile.nsNormalize(c))},a.fn.removeWithDependents=function(){a.removeWithDependents(this)},a.removeWithDependents=function(b){var c=a(b);(c.jqmData("dependents")||a()).remove(),c.remove()},a.fn.addDependents=function(b){a.addDependents(a(this),b)},a.addDependents=function(b,c){var d=a(b).jqmData("dependents")||a();a(b).jqmData("dependents",a.merge(d,c))},a.fn.getEncodedText=function(){return a("<div/>").text(a(this).text()).html()},a.fn.jqmEnhanceable=function(){return a.mobile.enhanceable(this)},a.fn.jqmHijackable=function(){return a.mobile.hijackable(this)};var f=a.find,g=/:jqmData\(([^)]*)\)/g;a.find=function(b,c,d,e){return b=b.replace(g,"[data-"+(a.mobile.ns||"")+"$1]"),f.call(this,b,c,d,e)},a.extend(a.find,f),a.find.matches=function(b,c){return a.find(b,null,null,c)},a.find.matchesSelector=function(b,c){return a.find(c,null,null,[b]).length>0}})(a,this),function(a,b){var c=0,d=Array.prototype.slice,e=a.cleanData;a.cleanData=function(b){for(var c=0,d;(d=b[c])!=null;c++)try{a(d).triggerHandler("remove")}catch(f){}e(b)},a.widget=function(b,c,d){var e,f,g,h,i=b.split(".")[0];b=b.split(".")[1],e=i+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][e]=function(b){return!!a.data(b,e)},a[i]=a[i]||{},f=a[i][b],g=a[i][b]=function(a,b){if(!this._createWidget)return new g(a,b);arguments.length&&this._createWidget(a,b)},a.extend(g,f,{version:d.version,_proto:a.extend({},d),_childConstructors:[]}),h=new c,h.options=a.widget.extend({},h.options),a.each(d,function(b,e){a.isFunction(e)&&(d[b]=function(){var a=function(){return c.prototype[b].apply(this,arguments)},d=function(a){return c.prototype[b].apply(this,a)};return function(){var b=this._super,c=this._superApply,f;return this._super=a,this._superApply=d,f=e.apply(this,arguments),this._super=b,this._superApply=c,f}}())}),g.prototype=a.widget.extend(h,{widgetEventPrefix:b},d,{constructor:g,namespace:i,widgetName:b,widgetBaseClass:e,widgetFullName:e}),f?(a.each(f._childConstructors,function(b,c){var d=c.prototype;a.widget(d.namespace+"."+d.widgetName,g,c._proto)}),delete f._childConstructors):c._childConstructors.push(g),a.widget.bridge(b,g)},a.widget.extend=function(c){var e=d.call(arguments,1),f=0,g=e.length,h,i;for(;f<g;f++)for(h in e[f])i=e[f][h],e[f].hasOwnProperty(h)&&i!==b&&(c[h]=a.isPlainObject(i)?a.widget.extend({},c[h],i):i);return c},a.widget.bridge=fuLine truncated
@@ -0,0 +1,3 @@
/*! jQuery Mobile 1.3.1 | Git HEAD hash: 74b4bec <> 2013-04-08T19:41:28Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */
.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:700;text-shadow:0 -1px 0 #000;background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111));background-image:-webkit-linear-gradient(#3c3c3c,#111);background-image:-moz-linear-gradient(#3c3c3c,#111);background-image:-ms-linear-gradient(#3c3c3c,#111);background-image:-o-linear-gradient(#3c3c3c,#111);background-image:linear-gradient(#3c3c3c,#111)}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 0 #111;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#222));background-image:-webkit-linear-gradient(#444,#222);background-image:-moz-linear-gradient(#444,#222);background-image:-ms-linear-gradient(#444,#222);background-image:-o-linear-gradient(#444,#222);background-image:linear-gradient(#444,#222)}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:700}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#2d2d2d));background-image:-webkit-linear-gradient(#444,#2d2d2d);background-image:-moz-linear-gradient(#444,#2d2d2d);background-image:-ms-linear-gradient(#444,#2d2d2d);background-image:-o-linear-gradient(#444,#2d2d2d);background-image:linear-gradient(#444,#2d2d2d)}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#555),to(#383838));background-image:-webkit-linear-gradient(#555,#383838);background-image:-moz-linear-gradient(#555,#383838);background-image:-ms-linear-gradient(#555,#383838);background-image:-o-linear-gradient(#555,#383838);background-image:linear-gradient(#555,#383838)}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#202020),to(#2c2c2c));background-image:-webkit-linear-gradient(#202020,#2c2c2c);background-image:-moz-linear-gradient(#202020,#2c2c2c);background-image:-ms-linear-gradient(#202020,#2c2c2c);background-image:-o-linear-gradient(#202020,#2c2c2c);background-image:linear-gradient(#202020,#2c2c2c)}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:700;text-shadow:0 1px 0 #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#497bae));background-image:-webkit-linear-gradient(#6facd5,#497bae);background-image:-moz-linear-gradient(#6facd5,#497bae);background-image:-ms-linear-gradient(#6facd5,#497bae);background-image:-o-linear-gradient(#6facd5,#497bae);background-image:linear-gradient(#6facd5,#497bae)}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:700}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#ccc));background-image:-webkit-linear-gradient(#ddd,#ccc);background-image:-moz-linear-gradient(#ddd,#ccc);background-image:-ms-linear-gradient(#ddd,#ccc);background-image:-o-linear-gradient(#ddd,#ccc);background-image:linear-gradient(#ddd,#ccc)}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:700}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:700;color:Line truncated
@@ -0,0 +1,7 @@
/*! jQuery Mobile 1.3.1 | Git HEAD hash: 74b4bec <> 2013-04-08T19:41:28Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */
(function(e,t,i){"function"==typeof define&&define.amd?define(["jquery"],function(n){return i(n,e,t),n.mobile}):i(e.jQuery,e,t)})(this,document,function(e,t,i,n){(function(e){e.mobile={}})(e),function(e,t,n){var a={};e.mobile=e.extend(e.mobile,{version:"1.3.1",ns:"",subPageUrlKey:"ui-page",activePageClass:"ui-page-active",activeBtnClass:"ui-btn-active",focusClass:"ui-focus",ajaxEnabled:!0,hashListeningEnabled:!0,linkBindingEnabled:!0,defaultPageTransition:"fade",maxTransitionWidth:!1,minScrollBack:250,touchOverflowEnabled:!1,defaultDialogTransition:"pop",pageLoadErrorMessage:"Error Loading Page",pageLoadErrorMessageTheme:"e",phonegapNavigationEnabled:!1,autoInitializePage:!0,pushStateEnabled:!0,ignoreContentEnabled:!1,orientationChangeEnabled:!0,buttonMarkup:{hoverDelay:200},window:e(t),document:e(i),keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},behaviors:{},silentScroll:function(i){"number"!==e.type(i)&&(i=e.mobile.defaultHomeScroll),e.event.special.scrollstart.enabled=!1,setTimeout(function(){t.scrollTo(0,i),e.mobile.document.trigger("silentscroll",{x:0,y:i})},20),setTimeout(function(){e.event.special.scrollstart.enabled=!0},150)},nsNormalizeDict:a,nsNormalize:function(t){return t?a[t]||(a[t]=e.camelCase(e.mobile.ns+t)):n},getInheritedTheme:function(e,t){for(var i,n,a=e[0],o="",s=/ui-(bar|body|overlay)-([a-z])\b/;a&&(i=a.className||"",!(i&&(n=s.exec(i))&&(o=n[2])));)a=a.parentNode;return o||t||"a"},closestPageData:function(e){return e.closest(':jqmData(role="page"), :jqmData(role="dialog")').data("mobile-page")},enhanceable:function(e){return this.haveParents(e,"enhance")},hijackable:function(e){return this.haveParents(e,"ajax")},haveParents:function(t,i){if(!e.mobile.ignoreContentEnabled)return t;for(var n,a,o,s=t.length,r=e(),l=0;s>l;l++){for(a=t.eq(l),o=!1,n=t[l];n;){var d=n.getAttribute?n.getAttribute("data-"+e.mobile.ns+i):"";if("false"===d){o=!0;break}n=n.parentNode}o||(r=r.add(a))}return r},getScreenHeight:function(){return t.innerHeight||e.mobile.window.height()}},e.mobile),e.fn.jqmData=function(t,i){var a;return t!==n&&(t&&(t=e.mobile.nsNormalize(t)),a=2>arguments.length||i===n?this.data(t):this.data(t,i)),a},e.jqmData=function(t,i,a){var o;return i!==n&&(o=e.data(t,i?e.mobile.nsNormalize(i):i,a)),o},e.fn.jqmRemoveData=function(t){return this.removeData(e.mobile.nsNormalize(t))},e.jqmRemoveData=function(t,i){return e.removeData(t,e.mobile.nsNormalize(i))},e.fn.removeWithDependents=function(){e.removeWithDependents(this)},e.removeWithDependents=function(t){var i=e(t);(i.jqmData("dependents")||e()).remove(),i.remove()},e.fn.addDependents=function(t){e.addDependents(e(this),t)},e.addDependents=function(t,i){var n=e(t).jqmData("dependents")||e();e(t).jqmData("dependents",e.merge(n,i))},e.fn.getEncodedText=function(){return e("<div/>").text(e(this).text()).html()},e.fn.jqmEnhanceable=function(){return e.mobile.enhanceable(this)},e.fn.jqmHijackable=function(){return e.mobile.hijackable(this)};var o=e.find,s=/:jqmData\(([^)]*)\)/g;e.find=function(t,i,n,a){return t=t.replace(s,"[data-"+(e.mobile.ns||"")+"$1]"),o.call(this,t,i,n,a)},e.extend(e.find,o),e.find.matches=function(t,i){return e.find(t,null,null,i)},e.find.matchesSelector=function(t,i){return e.find(i,null,null,[t]).length>0}}(e,this),function(e,t){var i=0,n=Array.prototype.slice,a=e.cleanData;e.cleanData=function(t){for(var i,n=0;null!=(i=t[n]);n++)try{e(i).triggerHandler("remove")}catch(o){}a(t)},e.widget=function(i,n,a){var o,s,r,l,d=i.split(".")[0];i=i.split(".")[1],o=d+"-"+i,a||(a=n,n=e.Widget),e.expr[":"][o.toLowerCase()]=function(t){return!!e.data(t,o)},e[d]=e[d]||{},s=e[d][i],r=e[d][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new r(e,i)},e.extend(r,s,{version:a.version,_proto:e.extend({},a),_childConstructors:[]}),l=new n,l.options=e.widget.extend({},l.options),e.each(a,function(t,i){e.isFunction(i)&&(a[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},a=function(e){return n.prototype[t].apply(this,e)};return function(){var t,n=this._super,o=this._superApply;return this._super=e,this._superApply=a,t=i.apply(this,arguments),this._super=n,this._superApply=o,t}}())}),r.prototype=e.widget.extend(l,{widgetEventPrefix:s?l.widgetEventPrefix:i},a,{constructor:r,namespace:d,widgetName:i,widgetFullName:o}),s?(e.each(s._childConstructors,function(t,i){var n=i.prototype;e.widget(n.namespace+"."+n.widgetName,r,i._proto)}),delete s._childConstructors):n._childConstructors.push(r),e.widget.bridge(i,r)},e.widget.extend=function(i){for(var a,o,s=n.call(arguments,1),r=0,l=s.length;l>r;r++)for(a in s[r])o=s[r][a],s[r].hasOwnProperty(a)&&o!==t&&(i[a]=e.isPlainLine truncated
},e.event.special.tap.tapholdThreshold)})}},e.event.special.swipe={scrollSupressionThreshold:30,durationThreshold:1e3,horizontalDistanceThreshold:30,verticalDistanceThreshold:75,start:function(t){var i=t.originalEvent.touches?t.originalEvent.touches[0]:t;return{time:(new Date).getTime(),coords:[i.pageX,i.pageY],origin:e(t.target)}},stop:function(e){var t=e.originalEvent.touches?e.originalEvent.touches[0]:e;return{time:(new Date).getTime(),coords:[t.pageX,t.pageY]}},handleSwipe:function(t,i){i.time-t.time<e.event.special.swipe.durationThreshold&&Math.abs(t.coords[0]-i.coords[0])>e.event.special.swipe.horizontalDistanceThreshold&&Math.abs(t.coords[1]-i.coords[1])<e.event.special.swipe.verticalDistanceThreshold&&t.origin.trigger("swipe").trigger(t.coords[0]>i.coords[0]?"swipeleft":"swiperight")},setup:function(){var t=this,i=e(t);i.bind(l,function(t){function a(t){s&&(o=e.event.special.swipe.stop(t),Math.abs(s.coords[0]-o.coords[0])>e.event.special.swipe.scrollSupressionThreshold&&t.preventDefault())}var o,s=e.event.special.swipe.start(t);i.bind(c,a).one(d,function(){i.unbind(c,a),s&&o&&e.event.special.swipe.handleSwipe(s,o),s=o=n})})}},e.each({scrollstop:"scrollstart",taphold:"tap",swipeleft:"swipe",swiperight:"swipe"},function(t,i){e.event.special[t]={setup:function(){e(this).bind(i,e.noop)}}})}(e,this),function(e){e.event.special.throttledresize={setup:function(){e(this).bind("resize",o)},teardown:function(){e(this).unbind("resize",o)}};var t,i,n,a=250,o=function(){i=(new Date).getTime(),n=i-s,n>=a?(s=i,e(this).trigger("throttledresize")):(t&&clearTimeout(t),t=setTimeout(o,a-n))},s=0}(e),function(e,t){function a(){var e=o();e!==s&&(s=e,d.trigger(c))}var o,s,r,l,d=e(t),c="orientationchange",h={0:!0,180:!0};if(e.support.orientation){var u=t.innerWidth||d.width(),p=t.innerHeight||d.height(),m=50;r=u>p&&u-p>m,l=h[t.orientation],(r&&l||!r&&!l)&&(h={"-90":!0,90:!0})}e.event.special.orientationchange=e.extend({},e.event.special.orientationchange,{setup:function(){return e.support.orientation&&!e.event.special.orientationchange.disabled?!1:(s=o(),d.bind("throttledresize",a),n)},teardown:function(){return e.support.orientation&&!e.event.special.orientationchange.disabled?!1:(d.unbind("throttledresize",a),n)},add:function(e){var t=e.handler;e.handler=function(e){return e.orientation=o(),t.apply(this,arguments)}}}),e.event.special.orientationchange.orientation=o=function(){var n=!0,a=i.documentElement;return n=e.support.orientation?h[t.orientation]:a&&1.1>a.clientWidth/a.clientHeight,n?"portrait":"landscape"},e.fn[c]=function(e){return e?this.bind(c,e):this.trigger(c)},e.attrFn&&(e.attrFn[c]=!0)}(e,this),function(e){e.widget("mobile.page",e.mobile.widget,{options:{theme:"c",domCache:!1,keepNativeDefault:":jqmData(role='none'), :jqmData(role='nojs')"},_create:function(){return this._trigger("beforecreate")===!1?!1:(this.element.attr("tabindex","0").addClass("ui-page ui-body-"+this.options.theme),this._on(this.element,{pagebeforehide:"removeContainerBackground",pagebeforeshow:"_handlePageBeforeShow"}),n)},_handlePageBeforeShow:function(){this.setContainerBackground()},removeContainerBackground:function(){e.mobile.pageContainer.removeClass("ui-overlay-"+e.mobile.getInheritedTheme(this.element.parent()))},setContainerBackground:function(t){this.options.theme&&e.mobile.pageContainer.addClass("ui-overlay-"+(t||this.options.theme))},keepNativeSelector:function(){var t=this.options,i=t.keepNative&&e.trim(t.keepNative);return i&&t.keepNative!==t.keepNativeDefault?[t.keepNative,t.keepNativeDefault].join(", "):t.keepNativeDefault}})}(e),function(e,t,i){var n=function(n){return n===i&&(n=!0),function(i,a,o,s){var r=new e.Deferred,l=a?" reverse":"",d=e.mobile.urlHistory.getActive(),c=d.lastScroll||e.mobile.defaultHomeScroll,h=e.mobile.getScreenHeight(),u=e.mobile.maxTransitionWidth!==!1&&e.mobile.window.width()>e.mobile.maxTransitionWidth,p=!e.support.cssTransitions||u||!i||"none"===i||Math.max(e.mobile.window.scrollTop(),c)>e.mobile.getMaxScrollForTransition(),m=" ui-page-pre-in",f=function(){e.mobile.pageContainer.toggleClass("ui-mobile-viewport-transitioning viewport-"+i)},g=function(){e.event.special.scrollstart.enabled=!1,t.scrollTo(0,c),setTimeout(function(){e.event.special.scrollstart.enabled=!0},150)},b=function(){s.removeClass(e.mobile.activePageClass+" out in reverse "+i).height("")},v=function(){n?s.animationComplete(_):_(),s.height(h+e.mobile.window.scrollTop()).addClass(i+" out"+l)},_=function(){s&&n&&b(),C()},C=function(){o.css("z-index",-10),o.addClass(e.mobile.activePageClass+m),e.mobile.focusPage(o),o.height(h+c),g(),o.css("z-index",""),p||o.animationComplete(x),o.removeClass(m).addClass(i+" in"+l),p&&x()},x=function(){n||s&&b(),o.removeClass("out in reverse "+i).height(""),f(),e.mobile.window.scrollTop()!==c&&g(),r.resolve(i,a,o,s,!0)};return f(),s&&!p?v():_(),r.promise()}},a=n(),o=n(!1),s=function(){return 3*e.mobile.getScreenHeight()};e.mobile.defaultTransitionHandler=a,e.mobile.transitionHandlers={"default":eLine truncated
this._refresh("true"),i.trigger("expand")},_refresh:function(t){var i=this.element.children(":jqmData(role='collapsible')");e.mobile.collapsible.prototype.enhance(i.not(".ui-collapsible")),this._addFirstLastClasses(i,this._getVisibles(i,t),t)},refresh:function(){this._refresh(!1)}},e.mobile.behaviors.addFirstLastClasses)),e.mobile.document.bind("pagecreate create",function(t){e.mobile.collapsibleset.prototype.enhanceWithin(t.target)})}(e),function(e){e.fn.fieldcontain=function(){return this.addClass("ui-field-contain ui-body ui-br").contents().filter(function(){return 3===this.nodeType&&!/\S/.test(this.nodeValue)}).remove()},e(i).bind("pagecreate create",function(t){e(":jqmData(role='fieldcontain')",t.target).jqmEnhanceable().fieldcontain()})}(e),function(e){e.fn.grid=function(t){return this.each(function(){var i,n=e(this),a=e.extend({grid:null},t),o=n.children(),s={solo:1,a:2,b:3,c:4,d:5},r=a.grid;if(!r)if(5>=o.length)for(var l in s)s[l]===o.length&&(r=l);else r="a",n.addClass("ui-grid-duo");i=s[r],n.addClass("ui-grid-"+r),o.filter(":nth-child("+i+"n+1)").addClass("ui-block-a"),i>1&&o.filter(":nth-child("+i+"n+2)").addClass("ui-block-b"),i>2&&o.filter(":nth-child("+i+"n+3)").addClass("ui-block-c"),i>3&&o.filter(":nth-child("+i+"n+4)").addClass("ui-block-d"),i>4&&o.filter(":nth-child("+i+"n+5)").addClass("ui-block-e")})}}(e),function(e,t){e.widget("mobile.navbar",e.mobile.widget,{options:{iconpos:"top",grid:null,initSelector:":jqmData(role='navbar')"},_create:function(){var n=this.element,a=n.find("a"),o=a.filter(":jqmData(icon)").length?this.options.iconpos:t;n.addClass("ui-navbar ui-mini").attr("role","navigation").find("ul").jqmEnhanceable().grid({grid:this.options.grid}),a.buttonMarkup({corners:!1,shadow:!1,inline:!0,iconpos:o}),n.delegate("a","vclick",function(t){var n=e(t.target).is("a")?e(this):e(this).parent("a");if(!n.is(".ui-disabled, .ui-btn-active")){a.removeClass(e.mobile.activeBtnClass),e(this).addClass(e.mobile.activeBtnClass);var o=e(this);e(i).one("pagehide",function(){o.removeClass(e.mobile.activeBtnClass)})}}),n.closest(".ui-page").bind("pagebeforeshow",function(){a.filter(".ui-state-persist").addClass(e.mobile.activeBtnClass)})}}),e.mobile.document.bind("pagecreate create",function(t){e.mobile.navbar.prototype.enhanceWithin(t.target)})}(e),function(e){var t={};e.widget("mobile.listview",e.mobile.widget,e.extend({options:{theme:null,countTheme:"c",headerTheme:"b",dividerTheme:"b",icon:"arrow-r",splitIcon:"arrow-r",splitTheme:"b",corners:!0,shadow:!0,inset:!1,initSelector:":jqmData(role='listview')"},_create:function(){var e=this,t="";t+=e.options.inset?" ui-listview-inset":"",e.options.inset&&(t+=e.options.corners?" ui-corner-all":"",t+=e.options.shadow?" ui-shadow":""),e.element.addClass(function(e,i){return i+" ui-listview"+t}),e.refresh(!0)},_findFirstElementByTagName:function(e,t,i,n){var a={};for(a[i]=a[n]=!0;e;){if(a[e.nodeName])return e;e=e[t]}return null},_getChildrenByTagName:function(t,i,n){var a=[],o={};for(o[i]=o[n]=!0,t=t.firstChild;t;)o[t.nodeName]&&a.push(t),t=t.nextSibling;return e(a)},_addThumbClasses:function(t){var i,n,a=t.length;for(i=0;a>i;i++)n=e(this._findFirstElementByTagName(t[i].firstChild,"nextSibling","img","IMG")),n.length&&(n.addClass("ui-li-thumb"),e(this._findFirstElementByTagName(n[0].parentNode,"parentNode","li","LI")).addClass(n.is(".ui-li-icon")?"ui-li-has-icon":"ui-li-has-thumb"))},refresh:function(t){this.parentPage=this.element.closest(".ui-page"),this._createSubPages();var n,a,o,s,r,l,d,c,h,u,p,m,f=this.options,g=this.element,b=g.jqmData("dividertheme")||f.dividerTheme,v=g.jqmData("splittheme"),_=g.jqmData("spliticon"),C=g.jqmData("icon"),x=this._getChildrenByTagName(g[0],"li","LI"),y=!!e.nodeName(g[0],"ol"),w=!e.support.cssPseudoElement,T=g.attr("start"),D={};y&&w&&g.find(".ui-li-dec").remove(),y&&(T||0===T?w?d=parseInt(T,10):(c=parseInt(T,10)-1,g.css("counter-reset","listnumbering "+c)):w&&(d=1)),f.theme||(f.theme=e.mobile.getInheritedTheme(this.element,"c"));for(var P=0,k=x.length;k>P;P++){if(n=x.eq(P),a="ui-li",t||!n.hasClass("ui-li")){o=n.jqmData("theme")||f.theme,s=this._getChildrenByTagName(n[0],"a","A");var E="list-divider"===n.jqmData("role");s.length&&!E?(p=n.jqmData("icon"),n.buttonMarkup({wrapperEls:"div",shadow:!1,corners:!1,iconpos:"right",icon:s.length>1||p===!1?!1:p||C||f.icon,theme:o}),p!==!1&&1===s.length&&n.addClass("ui-li-has-arrow"),s.first().removeClass("ui-link").addClass("ui-link-inherit"),s.length>1&&(a+=" ui-li-has-alt",r=s.last(),l=v||r.jqmData("theme")||f.splitTheme,m=r.jqmData("icon"),r.appendTo(n).attr("title",e.trim(r.getEncodedText())).addClass("ui-li-link-alt").empty().buttonMarkup({shadow:!1,corners:!1,theme:o,icon:!1,iconpos:"notext"}).find(".ui-btn-inner").append(e(i.createElement("span")).buttonMarkup({shadow:!0,corners:!0,theme:l,iconpos:"notext",icon:m||p||_||f.splitIcon})))):E?(a+=" ui-li-divider ui-bar-"+(n.jqmData("theme")||b),n.attr("role","heading"),y&&(T||0===T?w?d=parseInt(T,10):(h=parseInt(T,10)-1,n.csLine truncated
},_setDisabled:function(e){return this.element.attr("disabled",e),this.button.attr("aria-disabled",e),this._setOption("disabled",e)},_focusButton:function(){var e=this;setTimeout(function(){e.button.focus()},40)},_selectOptions:function(){return this.select.find("option")},_preExtension:function(){var t="";~this.element[0].className.indexOf("ui-btn-left")&&(t=" ui-btn-left"),~this.element[0].className.indexOf("ui-btn-right")&&(t=" ui-btn-right"),this.select=this.element.removeClass("ui-btn-left ui-btn-right").wrap("<div class='ui-select"+t+"'>"),this.selectID=this.select.attr("id"),this.label=e("label[for='"+this.selectID+"']").addClass("ui-select"),this.isMultiple=this.select[0].multiple,this.options.theme||(this.options.theme=e.mobile.getInheritedTheme(this.select,"c"))},_destroy:function(){var e=this.element.parents(".ui-select");e.length>0&&(e.is(".ui-btn-left, .ui-btn-right")&&this.element.addClass(e.is(".ui-btn-left")?"ui-btn-left":"ui-btn-right"),this.element.insertAfter(e),e.remove())},_create:function(){this._preExtension(),this._trigger("beforeCreate"),this.button=this._button();var i=this,n=this.options,a=n.inline||this.select.jqmData("inline"),o=n.mini||this.select.jqmData("mini"),s=n.icon?n.iconpos||this.select.jqmData("iconpos"):!1,r=(-1===this.select[0].selectedIndex?0:this.select[0].selectedIndex,this.button.insertBefore(this.select).buttonMarkup({theme:n.theme,icon:n.icon,iconpos:s,inline:a,corners:n.corners,shadow:n.shadow,iconshadow:n.iconshadow,mini:o}));this.setButtonText(),n.nativeMenu&&t.opera&&t.opera.version&&r.addClass("ui-select-nativeonly"),this.isMultiple&&(this.buttonCount=e("<span>").addClass("ui-li-count ui-btn-up-c ui-btn-corner-all").hide().appendTo(r.addClass("ui-li-has-count"))),(n.disabled||this.element.attr("disabled"))&&this.disable(),this.select.change(function(){i.refresh(),n.nativeMenu&&this.blur()}),this._handleFormReset(),this.build()},build:function(){var t=this;this.select.appendTo(t.button).bind("vmousedown",function(){t.button.addClass(e.mobile.activeBtnClass)}).bind("focus",function(){t.button.addClass(e.mobile.focusClass)}).bind("blur",function(){t.button.removeClass(e.mobile.focusClass)}).bind("focus vmouseover",function(){t.button.trigger("vmouseover")}).bind("vmousemove",function(){t.button.removeClass(e.mobile.activeBtnClass)}).bind("change blur vmouseout",function(){t.button.trigger("vmouseout").removeClass(e.mobile.activeBtnClass)}).bind("change blur",function(){t.button.removeClass("ui-btn-down-"+t.options.theme)}),t.button.bind("vmousedown",function(){t.options.preventFocusZoom&&e.mobile.zoom.disable(!0)}),t.label.bind("click focus",function(){t.options.preventFocusZoom&&e.mobile.zoom.disable(!0)}),t.select.bind("focus",function(){t.options.preventFocusZoom&&e.mobile.zoom.disable(!0)}),t.button.bind("mouseup",function(){t.options.preventFocusZoom&&setTimeout(function(){e.mobile.zoom.enable(!0)},0)}),t.select.bind("blur",function(){t.options.preventFocusZoom&&e.mobile.zoom.enable(!0)})},selected:function(){return this._selectOptions().filter(":selected")},selectedIndices:function(){var e=this;return this.selected().map(function(){return e._selectOptions().index(this)}).get()},setButtonText:function(){var t=this,n=this.selected(),a=this.placeholder,o=e(i.createElement("span"));this.button.find(".ui-btn-text").html(function(){return a=n.length?n.map(function(){return e(this).text()}).get().join(", "):t.placeholder,o.text(a).addClass(t.select.attr("class")).addClass(n.attr("class"))})},setButtonCount:function(){var e=this.selected();this.isMultiple&&this.buttonCount[e.length>1?"show":"hide"]().text(e.length)},_reset:function(){this.refresh()},refresh:function(){this.setButtonText(),this.setButtonCount()},open:e.noop,close:e.noop,disable:function(){this._setDisabled(!0),this.button.addClass("ui-disabled")},enable:function(){this._setDisabled(!1),this.button.removeClass("ui-disabled")}},e.mobile.behaviors.formReset)),e.mobile.document.bind("pagecreate create",function(t){e.mobile.selectmenu.prototype.enhanceWithin(t.target,!0)})}(e),function(e,n){function a(e,t,i,n){var a=n;return a=t>e?i+(e-t)/2:Math.min(Math.max(i,n-t/2),i+e-t)}function o(){var i=e.mobile.window;return{x:i.scrollLeft(),y:i.scrollTop(),cx:t.innerWidth||i.width(),cy:t.innerHeight||i.height()}}e.widget("mobile.popup",e.mobile.widget,{options:{theme:null,overlayTheme:null,shadow:!0,corners:!0,transition:"none",positionTo:"origin",tolerance:null,initSelector:":jqmData(role='popup')",closeLinkSelector:"a:jqmData(rel='back')",closeLinkEvents:"click.popup",navigateEvents:"navigate.popup",closeEvents:"navigate.popup pagebeforechange.popup",dismissible:!0,history:!e.mobile.browser.oldIE},_eatEventAndClose:function(e){return e.preventDefault(),e.stopImmediatePropagation(),this.options.dismissible&&this.close(),!1},_resizeScreen:function(){var e=this._ui.container.outerHeight(!0);this._ui.screen.removeAttr("style"),e>this._ui.screen.height()&&this._ui.screen.height(e)},_handleWindowKeyUp:function(tLine truncated
e(".ui-page-active").css("padding-bottom",t+1+"px"),setTimeout(function(){e(".ui-page-active").css("padding-bottom",t+"px")},0)},destroy:function(){this._super(),this.element.closest(".ui-page-active").removeClass("ui-android-2x-fix")}})}(e),function(e,n){e.widget("mobile.panel",e.mobile.widget,{options:{classes:{panel:"ui-panel",panelOpen:"ui-panel-open",panelClosed:"ui-panel-closed",panelFixed:"ui-panel-fixed",panelInner:"ui-panel-inner",modal:"ui-panel-dismiss",modalOpen:"ui-panel-dismiss-open",pagePanel:"ui-page-panel",pagePanelOpen:"ui-page-panel-open",contentWrap:"ui-panel-content-wrap",contentWrapOpen:"ui-panel-content-wrap-open",contentWrapClosed:"ui-panel-content-wrap-closed",contentFixedToolbar:"ui-panel-content-fixed-toolbar",contentFixedToolbarOpen:"ui-panel-content-fixed-toolbar-open",contentFixedToolbarClosed:"ui-panel-content-fixed-toolbar-closed",animate:"ui-panel-animate"},animate:!0,theme:"c",position:"left",dismissible:!0,display:"reveal",initSelector:":jqmData(role='panel')",swipeClose:!0,positionFixed:!1},_panelID:null,_closeLink:null,_page:null,_modal:null,_panelInner:null,_wrapper:null,_fixedToolbar:null,_create:function(){var t=this,i=t.element,n=i.closest(":jqmData(role='page')"),a=function(){var t=e.data(n[0],"mobilePage").options.theme,i="ui-body-"+t;return i},o=function(){var e=i.find("."+t.options.classes.panelInner);return 0===e.length&&(e=i.children().wrapAll('<div class="'+t.options.classes.panelInner+'" />').parent()),e},s=function(){var i=n.find("."+t.options.classes.contentWrap);return 0===i.length&&(i=n.children(".ui-header:not(:jqmData(position='fixed')), .ui-content:not(:jqmData(role='popup')), .ui-footer:not(:jqmData(position='fixed'))").wrapAll('<div class="'+t.options.classes.contentWrap+" "+a()+'" />').parent(),e.support.cssTransform3d&&t.options.animate&&i.addClass(t.options.classes.animate)),i},r=function(){var i=n.find("."+t.options.classes.contentFixedToolbar);return 0===i.length&&(i=n.find(".ui-header:jqmData(position='fixed'), .ui-footer:jqmData(position='fixed')").addClass(t.options.classes.contentFixedToolbar),e.support.cssTransform3d&&t.options.animate&&i.addClass(t.options.classes.animate)),i};e.extend(this,{_panelID:i.attr("id"),_closeLink:i.find(":jqmData(rel='close')"),_page:i.closest(":jqmData(role='page')"),_pageTheme:a(),_panelInner:o(),_wrapper:s(),_fixedToolbar:r()}),t._addPanelClasses(),t._wrapper.addClass(this.options.classes.contentWrapClosed),t._fixedToolbar.addClass(this.options.classes.contentFixedToolbarClosed),t._page.addClass(t.options.classes.pagePanel),e.support.cssTransform3d&&t.options.animate&&this.element.addClass(t.options.classes.animate),t._bindUpdateLayout(),t._bindCloseEvents(),t._bindLinkListeners(),t._bindPageEvents(),t.options.dismissible&&t._createModal(),t._bindSwipeEvents()},_createModal:function(){var t=this;t._modal=e("<div class='"+t.options.classes.modal+"' data-panelid='"+t._panelID+"'></div>").on("mousedown",function(){t.close()}).appendTo(this._page)},_getPosDisplayClasses:function(e){return e+"-position-"+this.options.position+" "+e+"-display-"+this.options.display},_getPanelClasses:function(){var e=this.options.classes.panel+" "+this._getPosDisplayClasses(this.options.classes.panel)+" "+this.options.classes.panelClosed;return this.options.theme&&(e+=" ui-body-"+this.options.theme),this.options.positionFixed&&(e+=" "+this.options.classes.panelFixed),e},_addPanelClasses:function(){this.element.addClass(this._getPanelClasses())},_bindCloseEvents:function(){var e=this;e._closeLink.on("click.panel",function(t){return t.preventDefault(),e.close(),!1}),e.element.on("click.panel","a:jqmData(ajax='false')",function(){e.close()})},_positionPanel:function(){var t=this,i=t._panelInner.outerHeight(),n=i>e.mobile.getScreenHeight();n||!t.options.positionFixed?(n&&(t._unfixPanel(),e.mobile.resetActivePageHeight(i)),t._scrollIntoView(i)):t._fixPanel()},_scrollIntoView:function(i){e(t).scrollTop()>i&&t.scrollTo(0,0)},_bindFixListener:function(){this._on(e(t),{throttledresize:"_positionPanel"})},_unbindFixListener:function(){this._off(e(t),"throttledresize")},_unfixPanel:function(){this.options.positionFixed&&e.support.fixedPosition&&this.element.removeClass(this.options.classes.panelFixed)},_fixPanel:function(){this.options.positionFixed&&e.support.fixedPosition&&this.element.addClass(this.options.classes.panelFixed)},_bindUpdateLayout:function(){var e=this;e.element.on("updatelayout",function(){e._open&&e._positionPanel()})},_bindLinkListeners:function(){var t=this;t._page.on("click.panel","a",function(i){if(this.href.split("#")[1]===t._panelID&&t._panelID!==n){i.preventDefault();var a=e(this);return a.hasClass("ui-link")||(a.addClass(e.mobile.activeBtnClass),t.element.one("panelopen panelclose",function(){a.removeClass(e.mobile.activeBtnClass)})),t.toggle(),!1}})},_bindSwipeEvents:function(){var e=this,t=e._modal?e.element.add(e._modal):e.element;e.options.swipeClose&&("left"===e.options.position?t.on("swipeleft.panel",function(Line truncated
//@ sourceMappingURL=jquery.mobile-1.3.1.min.map
@@ -31,7 +31,7 @@
<link rel="apple-touch-icon" href="{{=URL('static','favicon.png')}}"> <link rel="apple-touch-icon" href="{{=URL('static','favicon.png')}}">
<!-- For the less-enabled mobile browsers like Opera Mini --> <!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" href="{{=URL('static','plugin_jqmobile/jquery.mobile-1.2.0.min.css')}}"> <link rel="stylesheet" href="{{=URL('static','plugin_jqmobile/jquery.mobile-1.3.1.min.css')}}">
<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects --> <!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="{{=URL('static','js/modernizr.custom.js')}}"></script!> <script src="{{=URL('static','js/modernizr.custom.js')}}"></script!>
@@ -61,7 +61,7 @@ $(document).bind("mobileinit", function(){
}); });
</script> </script>
<script src="{{=URL('static','plugin_jqmobile/jquery.mobile-1.2.0.min.js')}}"></script> <script src="{{=URL('static','plugin_jqmobile/jquery.mobile-1.3.1.min.js')}}"></script>
<style> <style>
.error { color: red; } .error { color: red; }
+145 -140
View File
@@ -10,9 +10,9 @@
return files return files
def editfile(path,file,vars={}): def editfile(path,file,vars={}):
args=(path,file) if 'app' in vars else (app,path,file) args=(path,file) if 'app' in vars else (app,path,file)
url = URL('edit', args=args, vars=vars) url = URL('edit', args=args, vars=vars)
return A(file, _class='editor_filelink', _href=url, _style='word-wrap: break-word;') return A(file, _class='editor_filelink', _href=url, _style='word-wrap: nowrap;')
}} }}
{{cm=URL('static','codemirror')}} {{cm=URL('static','codemirror')}}
<link rel="stylesheet" href="{{=cm}}/lib/codemirror.css"> <link rel="stylesheet" href="{{=cm}}/lib/codemirror.css">
@@ -38,123 +38,123 @@
<link rel="stylesheet" href="{{=cm}}/addon/dialog/dialog.css"> <link rel="stylesheet" href="{{=cm}}/addon/dialog/dialog.css">
<script src="{{=cm}}/addon/selection/active-line.js"></script> <script src="{{=cm}}/addon/selection/active-line.js"></script>
<script src="{{=cm}}/emmet.min.js"></script> <script src="{{=cm}}/emmet.min.js"></script>
<script language="Javascript" type="text/javascript" src="{{=URL('static','js/ajax_editor.js')}}"></script> <script src="{{=URL('static','js/ajax_editor.js')}}"></script>
<link rel="stylesheet" href="{{=URL('static/css','typeahead.js-bootstrap.css')}}"> <link rel="stylesheet" href="{{=URL('static/css','typeahead.js-bootstrap.css')}}">
<link rel="stylesheet" href="{{=URL('static/css','web2py-codemirror.css')}}"> <link rel="stylesheet" href="{{=URL('static/css','web2py-codemirror.css')}}">
<script language="Javascript" type="text/javascript"> <script type="text/javascript">
var current_theme = "web2py"; //Default theme var current_theme = "web2py"; //Default theme
var current_font_incr = 0; // Default font-size, 0 means don't set var current_font_incr = 0; // Default font-size, 0 means don't set
jQuery(document).on('shown click', 'a[data-toggle="tab"]', function (e) { jQuery(document).on('shown click', 'a[data-toggle="tab"]', function (e) {
var tab_id = jQuery(this).attr('href'); var tab_id = jQuery(this).attr('href');
var editor = jQuery(tab_id + " textarea").data('editor'); var editor = jQuery(tab_id + " textarea").data('editor');
if (editor) { if (editor) {
editor.setSize(jQuery(tab_id).width(), jQuery(tab_id).height()); editor.setSize(jQuery(tab_id).width(), jQuery(tab_id).height());
editor.refresh(); editor.refresh();
} }
//jQuery(function(){jQuery('.CodeMirror-scroll').css("height","auto").css("overflow-x","auto");}); //jQuery(function(){jQuery('.CodeMirror-scroll').css("height","auto").css("overflow-x","auto");});
}); });
// Close the selected tab // Close the selected tab
jQuery(document).on('click', '#filesTab button[class="close"]', function (e) { jQuery(document).on('click', '#filesTab button[class="close"]', function (e) {
var tab_body = jQuery(jQuery(this).parent().attr("href")); // it should be a div var tab_body = jQuery(jQuery(this).parent().attr("href")); // it should be a div
var tab_header = jQuery(this).parent().parent(); // it should be a li var tab_header = jQuery(this).parent().parent(); // it should be a li
var saved = jQuery(tab_body.find('textarea').data('editor')).data('saved'); var saved = jQuery(tab_body.find('textarea').data('editor')).data('saved');
var close = true; var close = true;
if (saved === false) { if (saved === false) {
close = confirm("You are closing an unsaved file") close = confirm("You are closing an unsaved file")
} }
if (close) { if (close) {
if (tab_header.hasClass('active') === true) { //Set active an other tab if (tab_header.hasClass('active') === true) { //Set active an other tab
jQuery(tab_header).prev().children('a[data-toggle="tab"]').tab('show'); // Select first tab jQuery(tab_header).prev().children('a[data-toggle="tab"]').tab('show'); // Select first tab
} }
tab_header.remove(); //remove li of tab tab_header.remove(); //remove li of tab
tab_body.remove(); //remove li of tab tab_body.remove(); //remove li of tab
} }
}); });
// Revert current file // Revert current file
jQuery(document).on('click', '#revert', function (e) { jQuery(document).on('click', '#revert', function (e) {
e.preventDefault(); e.preventDefault();
load_file(jQuery(this).attr("href")); load_file(jQuery(this).attr("href"));
}); });
// Restore current file // Restore current file
jQuery(document).on('click', '#restore', function (e) { jQuery(document).on('click', '#restore', function (e) {
e.preventDefault(); e.preventDefault();
load_file(jQuery(this).attr("href")); load_file(jQuery(this).attr("href"));
}); });
// open the selected file // open the selected file
jQuery(document).on('click', 'a.editor_filelink', function (e) { jQuery(document).on('click', 'a.editor_filelink', function (e) {
e.preventDefault(); e.preventDefault();
var url = jQuery(this).attr("href"); var url = jQuery(this).attr("href");
load_file(url); load_file(url);
}); });
// change the codemirror theme // change the codemirror theme
jQuery(document).on('click', '#themes a', function (e) { jQuery(document).on('click', '#themes a', function (e) {
e.preventDefault(); e.preventDefault();
var href = jQuery(this).attr('href'); var href = jQuery(this).attr('href');
var name = jQuery(this).text().replace('.css', ''); var name = jQuery(this).text().replace('.css', '');
var link = jQuery("<link>"); var link = jQuery("<link>");
link.attr({ link.attr({
type: 'text/css', type: 'text/css',
rel: 'stylesheet', rel: 'stylesheet',
href: href href: href
}); });
jQuery("head").append( link ); jQuery("head").append( link );
jQuery('textarea[name="data"]') .each(function(id, ta) { jQuery('textarea[name="data"]') .each(function(id, ta) {
editor = jQuery(ta).data('editor'); editor = jQuery(ta).data('editor');
editor.setOption("theme", name); editor.setOption("theme", name);
}); });
jQuery('#themeName').html(name); jQuery('#themeName').html(name);
current_theme = name; current_theme = name;
//#TODO save on session //#TODO save on session
}); });
// incr/decr editor font-size // incr/decr editor font-size
jQuery(document).on('click', 'a.font_button', function (e) { jQuery(document).on('click', 'a.font_button', function (e) {
e.preventDefault(); e.preventDefault();
var id = jQuery(this).attr('id'); var id = jQuery(this).attr('id');
var new_font_incr; var new_font_incr;
switch (id) { switch (id) {
case 'incr': new_incr = 2; break; case 'incr': new_incr = 2; break;
case 'decr': new_incr = -2; break; case 'decr': new_incr = -2; break;
case 'default': new_incr = 0; break; case 'default': new_incr = 0; break;
} }
jQuery('textarea[name="data"]') .each(function(id, ta) { jQuery('textarea[name="data"]') .each(function(id, ta) {
editor = jQuery(ta).data('editor'); editor = jQuery(ta).data('editor');
set_font(editor, new_incr); set_font(editor, new_incr);
}); });
current_font_incr = (new_incr !== 0) ? current_font_incr + new_incr : 0; current_font_incr = (new_incr !== 0) ? current_font_incr + new_incr : 0;
}); });
function isFullScreen(instance) { function isFullScreen(instance) {
return /\bCodeMirror-fullscreen\b/.test(instance.getWrapperElement().className); return /\bCodeMirror-fullscreen\b/.test(instance.getWrapperElement().className);
} }
function winHeight() { function winHeight() {
return window.innerHeight || (document.documentElement || document.body).clientHeight; return window.innerHeight || (document.documentElement || document.body).clientHeight;
} }
function setFullScreen(instance, full) { function setFullScreen(instance, full) {
var wrap = instance.getWrapperElement() var wrap = instance.getWrapperElement()
if (full) { if (full) {
wrap.className += " CodeMirror-fullscreen"; wrap.className += " CodeMirror-fullscreen";
wrap.style.height = winHeight() + "px"; wrap.style.height = winHeight() + "px";
document.documentElement.style.overflow = "hidden"; document.documentElement.style.overflow = "hidden";
} else { } else {
wrap.className = wrap.className.replace(" CodeMirror-fullscreen", ""); wrap.className = wrap.className.replace(" CodeMirror-fullscreen", "");
wrap.style.height = ""; wrap.style.height = "";
document.documentElement.style.overflow = ""; document.documentElement.style.overflow = "";
} }
instance.refresh(); instance.refresh();
} }
CodeMirror.on(window, "resize", function() { CodeMirror.on(window, "resize", function() {
var showing = document.body.getElementsByClassName("CodeMirror-fullscreen")[0]; var showing = document.body.getElementsByClassName("CodeMirror-fullscreen")[0];
if (!showing) return; if (!showing) return;
showing.CodeMirror.getWrappererElement().style.height = winHeight() + "px"; showing.CodeMirror.getWrappererElement().style.height = winHeight() + "px";
}); });
{{if len(request.args) > 1:}} {{if len(request.args) > 1:}}
load_file('{{=URL(f='edit', args=request.args, vars=request.get_vars)}}'); load_file('{{=URL(f='edit', args=request.args, vars=request.get_vars)}}');
{{pass}} {{pass}}
</script> </script>
@@ -163,18 +163,21 @@ jQuery(document).on('click', 'a.font_button', function (e) {
<div class='row-fluid'> <div class='row-fluid'>
<div class="right controls btn-toolbar pull-right"> <div class="right controls btn-toolbar pull-right">
<div class="btn-group">
<a class="button btn" onclick="jQuery('#files').toggle(); return false" href="#">Files toggle</a>
</div>
<div class="dropdown btn-group pull-left"> <div class="dropdown btn-group pull-left">
<a class="dropdown-toggle button btn" data-target="themes" data-toggle="dropdown" href="#" >Theme: <span id="themeName" style="color: #E8953C">Web2py</span> <span class="caret"></span></a> <a class="dropdown-toggle button btn" data-target="themes" data-toggle="dropdown" href="#" >Theme: <span id="themeName" style="color: #E8953C">Web2py</span> <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu" id="themes"> <ul class="dropdown-menu" role="menu" id="themes">
{{for f in listfiles('admin', "static/codemirror/theme", regexp='.*\.css$' ):}} {{for f in listfiles('admin', "static/codemirror/theme", regexp='.*\.css$' ):}}
<li class=""><a href="{{=URL('static/codemirror/theme', f, host=True)}}">{{=f[:-4]}}</a></li> <li class=""><a href="{{=URL('static/codemirror/theme', f, host=True)}}">{{=f[:-4]}}</a></li>
{{pass}} {{pass}}
</ul> </ul>
</div> </div>
<div class="btn-group"> <div class="btn-group">
<a id="decr" class="button btn font_button">-</a> <a id="decr" class="button btn font_button">-</a>
<a id="default" class="button btn font_button" >A</a> <a id="default" class="button btn font_button" >A</a>
<a id="incr" class="button btn font_button">+</a> <a id="incr" class="button btn font_button">+</a>
</div> </div>
<div class="btn-group"> <div class="btn-group">
{{=button(URL('design',args=request.vars.app if request.vars.app else request.args[0], anchor=request.vars.id), T('back'))}} {{=button(URL('design',args=request.vars.app if request.vars.app else request.args[0], anchor=request.vars.id), T('back'))}}
@@ -186,51 +189,53 @@ jQuery(document).on('click', 'a.font_button', function (e) {
</div> </div>
</div> </div>
<div id="editor_area" class="row-fluid"> <div id="editor_area" class="row-fluid">
<ul class="nav nav-list span2 well" rel="pagebookmark" id="filelist"> <div id="files">
<li><input type="text" placeholder="{{=T('Rapid Search')}}" class="input-block-level typeahead-tw search-query"></li> <ul class="nav nav-list span2 well" rel="pagebookmark" id="filelist">
{{dirs=[{'name':'models', 'reg':'.*\.py$'}, <li><input type="text" placeholder="{{=T('Rapid Search')}}" class="input-block-level typeahead-tw search-query"></li>
{'name':'controllers', 'reg':'.*\.py$'}, {{dirs=[{'name':'models', 'reg':'.*\.py$'},
{'name':'views', 'reg':'[\w/\-]+(\.\w+)+$'}, {'name':'controllers', 'reg':'.*\.py$'},
{'name':'modules', 'reg':'.*\.py$'}, {'name':'views', 'reg':'[\w/\-]+(\.\w+)+$'},
{'name':'private', 'reg': '[^\.#].*'}]}} {'name':'modules', 'reg':'.*\.py$'},
{{auto_complete_list=[]}} {'name':'private', 'reg': '[^\.#].*'}]}}
{{for dir in dirs:}} {{auto_complete_list=[]}}
<li class="nav-header component" onclick="collapse('{{="%s_files" % dir['name']}}');">{{=dir['name']}}</li> {{for dir in dirs:}}
<li id="{{="%s_files" % dir['name']}}"> <li class="nav-header component" onclick="collapse('{{="%s_files" % dir['name']}}');">{{=dir['name']}}</li>
<ul class="nav nav-list small-font"> <li id="{{="%s_files" % dir['name']}}">
{{for f in listfiles(app, dir['name'], regexp=dir['reg'] ):}} <ul class="nav nav-list small-font">
{{id="%s__" % dir['name'] + f.replace('.','__')}} {{for f in listfiles(app, dir['name'], regexp=dir['reg'] ):}}
{{current_file = request.args(len(request.args) - 1)}} {{id="%s__" % dir['name'] + f.replace('.','__')}}
<li class="{{#='active' if current_file==f else ''}}"> {{current_file = request.args(len(request.args) - 1)}}
{{a_tag=editfile(dir['name'], f, dict(id=id))}} <li class="{{#='active' if current_file==f else ''}}" style="overflow:hidden">
{{=a_tag}} {{a_tag=editfile(dir['name'], f, dict(id=id))}}
{{auto_complete_list.append({'value':f, 'tokens':f.split('/'), 'a_tag':a_tag})}} {{=a_tag}}
</li> {{auto_complete_list.append({'value':f, 'tokens':f.split('/'), 'a_tag':a_tag})}}
{{pass}} </li>
</ul> {{pass}}
</li> </ul>
{{pass}} </li>
</ul> {{pass}}
<div class="span10" id="edit_placeholder"> </ul>
<ul class="nav nav-tabs " id="filesTab"> </div>
</ul> <div class="span10" id="edit_placeholder">
<div id="myTabContent" class="tab-content"> <ul class="nav nav-tabs " id="filesTab">
</div> </ul>
</div> <div id="myTabContent" class="tab-content">
</div>
</div>
</div> </div>
<!-- Typeahead scripts here so the page load faster --> <!-- Typeahead scripts here so the page load faster -->
<script src="{{=URL('static/js', 'typeahead.min.js')}}"></script> <script src="{{=URL('static/js', 'typeahead.min.js')}}"></script>
<script src="{{=URL('static/js', 'hogan-2.0.0.js')}}"></script> <script src="{{=URL('static/js', 'hogan-2.0.0.js')}}"></script>
<script> <script>
jQuery('.typeahead-tw').typeahead({ jQuery('.typeahead-tw').typeahead({
name: 'files', name: 'files',
local:{{from gluon.serializers import json}}{{=XML(json(auto_complete_list))}}, local:{{from gluon.serializers import json}}{{=XML(json(auto_complete_list))}},
template: template_js, template: template_js,
engine: Hogan, engine: Hogan,
}); });
jQuery(document).on("typeahead:selected", '.typeahead', function(e, datum) { jQuery(document).on("typeahead:selected", '.typeahead', function(e, datum) {
load_file(datum.link); load_file(datum.link);
jQuery(this).val(''); jQuery(this).val('');
}); });
</script> </script>
<!-- end "edit" block --> <!-- end "edit" block -->
+132 -132
View File
@@ -4,12 +4,12 @@
<form action="{{=URL('edit', args=filename)}}" method="post" name="editform" id="editform" class="form-inline row-fluid"> <form action="{{=URL('edit', args=filename)}}" method="post" name="editform" id="editform" class="form-inline row-fluid">
<div class="span12 well well-small"> <div class="span12 well well-small">
<label class="">{{=T('Save file:')}}</label> <label class="">{{=T('Save file:')}}</label>
<a value="save" title="{{=T('Save file: %s', filename)}}" href="#" name="save" onclick="return doClickSave();" class="icon saveicon" style="background-image: -webkit-linear-gradient(top,white,#E6E6E6);">{{=IMG(_src=URL('static', 'images/save_icon.png'), _alt=T('Save'))}}</a> <a value="save" title="{{=T('Save file: %s', filename)}}" href="#" name="save" onclick="return doClickSave();" class="icon saveicon" style="background-image: -webkit-linear-gradient(top,white,#E6E6E6);">{{=IMG(_src=URL('static', 'images/save_icon.png'), _alt=T('Save'))}}</a>
<label class="">{{=T('Saved file hash:')}}</label> <label class="">{{=T('Saved file hash:')}}</label>
<input type="input" name="file_hash" value="{{=file_hash}}" class="input-long uneditable-input" readonly="readonly"/> <input type="input" name="file_hash" value="{{=file_hash}}" class="input-long uneditable-input" readonly="readonly"/>
<label>{{=T('Last saved on:')}}</label> <label>{{=T('Last saved on:')}}</label>
<input type="input" name="saved_on" value="{{=saved_on}}" class="input-normal uneditable-input" readonly="readonly"/> <input type="input" name="saved_on" value="{{=saved_on}}" class="input-normal uneditable-input" readonly="readonly"/>
{{if filetype=='python':}} {{if filetype=='python':}}
{{=A(SPAN(T('toggle breakpoint')), {{=A(SPAN(T('toggle breakpoint')),
_value="breakpoint", _name="breakpoint", _value="breakpoint", _name="breakpoint",
@@ -19,153 +19,153 @@
_class="button special btn btn-inverse")}} _class="button special btn btn-inverse")}}
{{pass}} {{pass}}
{{if view_link:}} {{if view_link:}}
{{=button(view_link, T('try view'))}} {{=button(view_link, T('try view'))}}
{{pass}} {{pass}}
<p class="formfield"> <p class="formfield">
{{if functions:}} {{if functions:}}
<span style="text-align:left;" class="exposed"> <span style="text-align:left;" class="exposed">
{{=B(T('exposes:'))}} {{=XML(', '.join([A(f,_target="_blank", _href=URL(a=app,c=controller,f=f)).xml() for f in functions]))}} {{=B(T('exposes:'))}} {{=XML(', '.join([A(f,_target="_blank", _href=URL(a=app,c=controller,f=f)).xml() for f in functions]))}}
</span> </span>
{{if editviewlinks:}}<br/> {{if editviewlinks:}}<br/>
{{=B(T('edit views:'))}} {{=B(T('edit views:'))}}
{{=XML(', '.join([v.xml() for v in editviewlinks]))}} {{=XML(', '.join([v.xml() for v in editviewlinks]))}}
{{pass}} {{pass}}
{{pass}} {{pass}}
{{if edit_controller:}} {{if edit_controller:}}
{{=B(T('edit controller:'))}} {{=B(T('edit controller:'))}}
{{=A(request.args[2]+'.py', _class="editor_filelink", _target="_blank", _href=edit_controller)}} {{=A(request.args[2]+'.py', _class="editor_filelink", _target="_blank", _href=edit_controller)}}
{{pass}} {{pass}}
</p> </p>
</div> </div>
<textarea style=" height:100%; direction:ltr;" id="textarea_{{=id}}" class="input-block-level" name="data" >{{=data}}</textarea> <textarea style=" height:100%; direction:ltr;" id="textarea_{{=id}}" class="input-block-level" name="data" >{{=data}}</textarea>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("textarea_{{=id}}"),{ var editor = CodeMirror.fromTextArea(document.getElementById("textarea_{{=id}}"),{
{{if filetype=='html':}} {{if filetype=='html':}}
mode : "text/html", mode : "text/html",
profile: 'xhtml', profile: 'xhtml',
{{else:}} {{else:}}
mode: { name: '{{=filetype}}'{{if filetype=='python':}},version: 2,singleLineStringErrors: false, {{pass}} }, mode: { name: '{{=filetype}}'{{if filetype=='python':}},version: 2,singleLineStringErrors: false, {{pass}} },
{{pass}} {{pass}}
lineNumbers: true, lineNumbers: true,
indentUnit: 4, indentUnit: 4,
styleActiveLine: true, styleActiveLine: true,
autoCloseTags: true, autoCloseTags: true,
theme: current_theme, theme: current_theme,
tabMode: "shift", tabMode: "shift",
lineWrapping: true, lineWrapping: true,
gutters: ["CodeMirror-linenumbers", "breakpoints"], gutters: ["CodeMirror-linenumbers", "breakpoints"],
{{if TEXT_EDITOR_KEYBINDING == 'emacs':}}keyMap: "emacs",{{pass}} {{if TEXT_EDITOR_KEYBINDING == 'emacs':}}keyMap: "emacs",{{pass}}
{{if TEXT_EDITOR_KEYBINDING == 'vi':}}keyMap: "vim",{{pass}} {{if TEXT_EDITOR_KEYBINDING == 'vi':}}keyMap: "vim",{{pass}}
matchBrackets: true, matchBrackets: true,
autofocus: false, autofocus: false,
height: "350px", height: "350px",
showTrailingSpace: true showTrailingSpace: true
}); });
editor.on("gutterClick", function(cm, n) { editor.on("gutterClick", function(cm, n) {
var info = cm.lineInfo(n); var info = cm.lineInfo(n);
cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker()); cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker());
sel = {start: n, end: n, data: ''}; sel = {start: n, end: n, data: ''};
doToggleBreakpoint({{=XML("'%s','%s://%s%s'" % (filename, doToggleBreakpoint({{=XML("'%s','%s://%s%s'" % (filename,
request.env['wsgi_url_scheme'], request.env['http_host'], request.env['wsgi_url_scheme'], request.env['http_host'],
URL(c='debug', f='toggle_breakpoint')))}}, sel); URL(c='debug', f='toggle_breakpoint')))}}, sel);
}); });
function makeMarker() { function makeMarker() {
var marker = document.createElement("div"); var marker = document.createElement("div");
marker.style.color = "#822"; marker.style.color = "#822";
marker.innerHTML = "●"; marker.innerHTML = "●";
marker.className = "breakpoint"; marker.className = "breakpoint";
return marker; return marker;
} }
{{if filetype=='html':}} {{if filetype=='html':}}
// must be here or break emmet/zencoding for html // must be here or break emmet/zencoding for html
CodeMirror.defaults.extraKeys["Ctrl-S"] = CodeMirror.defaults.extraKeys["Ctrl-S"] =
function(instance) { function(instance) {
doClickSave();}; doClickSave();};
CodeMirror.defaults.extraKeys["Ctrl-F11"]= CodeMirror.defaults.extraKeys["Ctrl-F11"]=
function(instance) { function(instance) {
setFullScreen(instance, !isFullScreen(instance));}; setFullScreen(instance, !isFullScreen(instance));};
CodeMirror.defaults.extraKeys["Tab"] = "indentMore"; CodeMirror.defaults.extraKeys["Tab"] = "indentMore";
CodeMirror.defaults.extraKeys["Esc"]= CodeMirror.defaults.extraKeys["Esc"]=
function(instance) { function(instance) {
if (isFullScreen(instance)) { if (isFullScreen(instance)) {
setFullScreen(instance, false);};} setFullScreen(instance, false);};}
{{pass}} {{pass}}
{{if filetype=='python':}} {{if filetype=='python':}}
// must be here or break emmet/zencoding for python // must be here or break emmet/zencoding for python
CodeMirror.defaults.extraKeys["Ctrl-S"] = CodeMirror.defaults.extraKeys["Ctrl-S"] =
function(instance) { function(instance) {
doClickSave();}; doClickSave();};
CodeMirror.defaults.extraKeys["Ctrl-Space"] = CodeMirror.defaults.extraKeys["Ctrl-Space"] =
"autocomplete"; "autocomplete";
CodeMirror.defaults.extraKeys["Ctrl-F11"]= CodeMirror.defaults.extraKeys["Ctrl-F11"]=
function(instance) { function(instance) {
setFullScreen(instance, !isFullScreen(instance));}; setFullScreen(instance, !isFullScreen(instance));};
CodeMirror.defaults.extraKeys["Tab"] = "indentMore"; CodeMirror.defaults.extraKeys["Tab"] = "indentMore";
CodeMirror.defaults.extraKeys["Esc"]= CodeMirror.defaults.extraKeys["Esc"]=
function(instance) { function(instance) {
if (isFullScreen(instance)) { if (isFullScreen(instance)) {
setFullScreen(instance, false);};} setFullScreen(instance, false);};}
//for autocomplete //for autocomplete
CodeMirror.commands.autocomplete = function(cm) { CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.pythonHint); CodeMirror.showHint(cm, CodeMirror.pythonHint);
} }
{{pass}} {{pass}}
store_changes_function = function(instance, changeObj) { store_changes_function = function(instance, changeObj) {
jQuery(instance).data('saved', false); jQuery(instance).data('saved', false);
instance.off("change", store_changes_function); instance.off("change", store_changes_function);
} }
editor.on("change", store_changes_function); editor.on("change", store_changes_function);
// save the editor as textarea data attribute // save the editor as textarea data attribute
jQuery("#{{=id}} textarea").data('editor', editor); jQuery("#{{=id}} textarea").data('editor', editor);
var hlLine = editor.addLineClass(0, "background", "activeline"); var hlLine = editor.addLineClass(0, "background", "activeline");
window.mirror = editor; //backward compatibility window.mirror = editor; //backward compatibility
set_font(editor, current_font_incr); set_font(editor, current_font_incr);
doListBreakpoints({{=XML("'%s','%s://%s%s'" % (filename, doListBreakpoints({{=XML("'%s','%s://%s%s'" % (filename,
request.env['wsgi_url_scheme'], request.env['http_host'], request.env['wsgi_url_scheme'], request.env['http_host'],
URL(c='debug', f='list_breakpoints')))}}, editor); URL(c='debug', f='list_breakpoints')))}}, editor);
</script> </script>
<div class="editor-bar-bottom" style="margin-top:9px;"> <div class="editor-bar-bottom" style="margin-top:9px;">
<a class="editbutton btn" href="{{=URL('edit', args=request.args, vars={'restore':True})}}" id="restore">{{=T('restore')}}</a> <a class="editbutton btn" href="{{=URL('edit', args=request.args, vars={'restore':True})}}" id="restore">{{=T('restore')}}</a>
{{=T('currently saved or')}} {{=T('currently saved or')}}
<a class="editbutton btn" href="{{=URL('edit', args=request.args, vars={'revert':True})}}" id="revert">{{=T('revert')}}</a> <a class="editbutton btn" href="{{=URL('edit', args=request.args, vars={'revert':True})}}" id="revert">{{=T('revert')}}</a>
{{=T('to previous version.')}} {{=T('to previous version.')}}
</div> </div>
<br/> <br/>
</form> </form>
<div class="row-fluid"> <div class="row-fluid">
<div class="help alert alert-block alert-info"> <div class="help alert alert-block alert-info">
{{if TEXT_EDITOR == 'codemirror' and filetype=='html':}} {{if TEXT_EDITOR == 'codemirror' and filetype=='html':}}
<h3>{{=T('Key bindings for ZenCoding Plugin')}}</h3> <h3>{{=T('Key bindings for ZenCoding Plugin')}}</h3>
<ul class="keybindings unstyled"> <ul class="keybindings unstyled">
{{=shortcut('Ctrl+S', T('Save via Ajax'))}} {{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}} {{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}}
{{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}} {{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}}
{{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}} {{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}}
{{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}} {{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}}
{{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}} {{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}}
{{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}} {{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}}
{{=shortcut('Tab', T('Expand Abbreviation'))}} {{=shortcut('Tab', T('Expand Abbreviation'))}}
</ul> </ul>
{{elif TEXT_EDITOR == 'codemirror':}} {{elif TEXT_EDITOR == 'codemirror':}}
<h3>{{=T("Key bindings")}}</h3> <h3>{{=T("Key bindings")}}</h3>
<ul class="keybindings unstyled"> <ul class="keybindings unstyled">
{{=shortcut('Ctrl+S', T('Save via Ajax'))}} {{=shortcut('Ctrl+S', T('Save via Ajax'))}}
{{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}} {{=shortcut('Ctrl+F11', T('Toggle Fullscreen'))}}
{{if filetype=='python':}} {{if filetype=='python':}}
{{=shortcut('Ctrl-Space', T('Autocomplete Python Code'))}} {{=shortcut('Ctrl-Space', T('Autocomplete Python Code'))}}
{{pass}} {{pass}}
{{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}} {{=shortcut('Ctrl-F / Cmd-F', T('Start searching'))}}
{{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}} {{=shortcut('Ctrl-G / Cmd-G', T('Find Next'))}}
{{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}} {{=shortcut('Shift-Ctrl-G / Shift-Cmd-G', T('Find Previous'))}}
{{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}} {{=shortcut('Shift-Ctrl-F / Cmd-Option-F', T('Replace'))}}
{{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}} {{=shortcut('Shift-Ctrl-R / Shift-Cmd-Option-F', T('Replace All'))}}
</ul> </ul>
{{pass}} {{pass}}
</div> </div>
</div> </div>
@@ -7,7 +7,7 @@ function delkey(id) {
return false; return false;
} }
function hideShowTranslated(){ function hideShowTranslated(){
jQuery(".translated").closest("div.row-fluid").toggle(); jQuery(".translated").closest("div.row-fluid").toggle();
} }
</script> </script>
+111 -111
View File
@@ -3,122 +3,122 @@
{{block sectionclass}}errors{{end}} {{block sectionclass}}errors{{end}}
<!-- begin "errors" block --> <!-- begin "errors" block -->
{{if db_ready['status'] == False: {{if db_ready['status'] == False:
switchbutton = A(SPAN("switch to : db"), _href=db_ready['errlink'], _class="button unavailable btn btn-danger", _title="%s" % (db_ready['errmessage'])) switchbutton = A(SPAN("switch to : db"), _href=db_ready['errlink'], _class="button unavailable btn btn-danger", _title="%s" % (db_ready['errmessage']))
else: else:
switchbutton = A(SPAN("switch to : db"), _href=URL(args=[app, 'dbnew']), _class="button btn") switchbutton = A(SPAN("switch to : db"), _href=URL(args=[app, 'dbnew']), _class="button btn")
pass}} pass}}
<h2>{{=T('Error logs for "%(app)s"',dict(app=app))}}</h2> <h2>{{=T('Error logs for "%(app)s"',dict(app=app))}}</h2>
<div class="errorform"> <div class="errorform">
<form name="myform" method="post"> <form name="myform" method="post">
{{ if 'new' in method: }} {{ if 'new' in method: }}
{{base_url = 'db' in method and 'ticketdb' or 'ticket' }} {{base_url = 'db' in method and 'ticketdb' or 'ticket' }}
<p class="controls row-fluid"> <p class="controls row-fluid">
<div class="controls controls-row"> <div class="controls controls-row">
{{if 'db' in method:}} {{if 'db' in method:}}
<span class="uneditable-input">source : db</span> <span class="uneditable-input">source : db</span>
<a class="button btn" href="{{=URL(args=[app, 'new'])}}"><span>switch to : filesystem</span></a> <a class="button btn" href="{{=URL(args=[app, 'new'])}}"><span>switch to : filesystem</span></a>
<a class="button btn" href="{{=URL(args=[app, 'dbold'])}}"><span>lists by ticket</span></a> <a class="button btn" href="{{=URL(args=[app, 'dbold'])}}"><span>lists by ticket</span></a>
{{else:}} {{else:}}
<span class="uneditable-input">source : filesystem</span> <span class="uneditable-input">source : filesystem</span>
{{=switchbutton}} {{=switchbutton}}
<a class="button btn" href="{{=URL(args=[app, 'old'])}}"><span>lists by ticket</span></a> <a class="button btn" href="{{=URL(args=[app, 'old'])}}"><span>lists by ticket</span></a>
{{pass}} {{pass}}
</div> </div>
</p> </p>
<div class="tablebar"> <div class="tablebar">
<input value="{{=T('delete all checked')}}" type="submit" class="btn"/> <input value="{{=T('delete all checked')}}" type="submit" class="btn"/>
<span class="help label label-info">{{=T('Click row to expand traceback')}}</span> <span class="help label label-info">{{=T('Click row to expand traceback')}}</span>
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
<div class="span6"> <div class="span6">
<table id="trck_errors" class="sortable table table-hover table-condensed"> <table id="trck_errors" class="sortable table table-hover table-condensed">
<thead> <thead>
<tr> <tr>
<th class="column1 cbcentered"><input type="checkbox" name="delete_all}" /></th> <th class="column1 cbcentered"><input type="checkbox" name="delete_all}" /></th>
<th class="column2">{{=T("Count")}}</th> <th class="column2">{{=T("Count")}}</th>
<th class="column3">{{=T("File")}}</th> <th class="column3">{{=T("File")}}</th>
<th>{{=T("Error")}}</th> <th>{{=T("Error")}}</th>
<th class="columnN"></th> <th class="columnN"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{for e in errors:}} {{for e in errors:}}
<tr class="error_ticket"> <tr class="error_ticket">
<td class="cbcentered"><input type="checkbox" name="delete_{{=e['hash']}}" /></td> <td class="cbcentered"><input type="checkbox" name="delete_{{=e['hash']}}" /></td>
<td>{{=e['count']}}</td> <td>{{=e['count']}}</td>
<td>{{=e['causer']}}</td> <td>{{=e['causer']}}</td>
<td>{{=A(e['last_line'],_href="#",_onclick="collapse('%s');return false;"%e['hash'])}}</td> <td>{{=A(e['last_line'],_href="#",_onclick="collapse('%s');return false;"%e['hash'])}}</td>
<td>+&nbsp;{{=A(T('details'),_href=URL(base_url,args=[app,e['ticket']]))}}</td> <td>+&nbsp;{{=A(T('details'),_href=URL(base_url,args=[app,e['ticket']]))}}</td>
</tr> </tr>
<tr id="{{=e['hash']}}" class="traceback"> <tr id="{{=e['hash']}}" class="traceback">
<td colspan="5"> <td colspan="5">
<div class="ticket_code"> <div class="ticket_code">
{{=CODE(e['pickel']['traceback'])}} {{=CODE(e['pickel']['traceback'])}}
</div> </div>
</td> </td>
</tr> </tr>
{{pass}} {{pass}}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
{{ else: }} {{ else: }}
<p class="controls row-fluid"> <p class="controls row-fluid">
<div class="controls controls-row"> <div class="controls controls-row">
{{if 'db' in method:}} {{if 'db' in method:}}
<span class="uneditable-input">source : db</span> <span class="uneditable-input">source : db</span>
<a class="button btn" href="{{=URL(args=[app, 'old'])}}"><span>switch to : filesystem</span></a> <a class="button btn" href="{{=URL(args=[app, 'old'])}}"><span>switch to : filesystem</span></a>
<a class="button btn" href="{{=URL(args=[app, 'dbnew'])}}"><span>lists by exception</span></a> <a class="button btn" href="{{=URL(args=[app, 'dbnew'])}}"><span>lists by exception</span></a>
{{else:}} {{else:}}
<span class="uneditable-input">source : filesystem</span> <span class="uneditable-input">source : filesystem</span>
{{=switchbutton}} {{=switchbutton}}
<a class="button btn" href="{{=URL(args=[app, 'new'])}}"><span>lists by exception</span></a> <a class="button btn" href="{{=URL(args=[app, 'new'])}}"><span>lists by exception</span></a>
{{pass}} {{pass}}
</div> </div>
</p> </p>
<div class="tablebar"> <div class="tablebar">
<input value="{{=T('delete all checked')}}" type="submit" class="btn"/> <input value="{{=T('delete all checked')}}" type="submit" class="btn"/>
<span class="help label label-info">{{=T('Click row to expand traceback')}}</span> <span class="help label label-info">{{=T('Click row to expand traceback')}}</span>
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
<div class="span6"> <div class="span6">
<table id="trck_errors" class="sortable table table-hover table-condensed"> <table id="trck_errors" class="sortable table table-hover table-condensed">
<thead> <thead>
<tr> <tr>
<th class="column1 cbcentered"><input type="checkbox" name="delete_all}" /></th> <th class="column1 cbcentered"><input type="checkbox" name="delete_all}" /></th>
<th>{{=T("Ticket")}}</th> <th>{{=T("Ticket")}}</th>
<th class="columnN1">{{=T("Date and Time")}}</th> <th class="columnN1">{{=T("Date and Time")}}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{for ticket in tickets:}} {{for ticket in tickets:}}
<tr> <tr>
<td class="cbcentered"><input type="checkbox" name="delete_{{=ticket}}"/></td> <td class="cbcentered"><input type="checkbox" name="delete_{{=ticket}}"/></td>
{{if 'db' in method:}} {{if 'db' in method:}}
<td><a href="{{=URL('ticketdb',args=[app,ticket])}}">{{=ticket}}</a></td> <td><a href="{{=URL('ticketdb',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',times[ticket].timetuple())}}</td> <td>{{=time.strftime('%Y-%m-%d %H:%M:%S',times[ticket].timetuple())}}</td>
{{else:}} {{else:}}
<td><a href="{{=URL('ticket',args=[app,ticket])}}">{{=ticket}}</a></td> <td><a href="{{=URL('ticket',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(os.stat(os.path.join(request.folder,'../%s/errors/%s' % (app,ticket)))[stat.ST_CTIME]))}}</td> <td>{{=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(os.stat(os.path.join(request.folder,'../%s/errors/%s' % (app,ticket)))[stat.ST_CTIME]))}}</td>
{{pass}} {{pass}}
</tr> </tr>
{{pass}} {{pass}}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
{{ pass }} {{ pass }}
</form><!-- /errorform --> </form><!-- /errorform -->
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
jQuery(document).ready(function() { jQuery(document).ready(function() {
jQuery('.traceback').hide(); jQuery('.traceback').hide();
jQuery("#trck_errors thead tr th:first input[type=checkbox]").click(function() { jQuery("#trck_errors thead tr th:first input[type=checkbox]").click(function() {
var checkedStatus = this.checked; var checkedStatus = this.checked;
jQuery("#trck_errors tbody tr td:first-child input[type=checkbox]").each(function() { jQuery("#trck_errors tbody tr td:first-child input[type=checkbox]").each(function() {
this.checked = checkedStatus; this.checked = checkedStatus;
}); });
}); });
}); });
</script> </script>
<!-- end "errors" block --> <!-- end "errors" block -->
@@ -9,14 +9,14 @@
<ul class="collapsible"> <ul class="collapsible">
{{for file in files[path]['files']:}} {{for file in files[path]['files']:}}
<li style="list-style-type: none;"> <li style="list-style-type: none;">
{{p = os.path.relpath(os.path.join(path,file),base)}} {{p = os.path.relpath(os.path.join(path,file),base)}}
<input type="checkbox" value="{{=p}}" name="file" checked="checked"/> <input type="checkbox" value="{{=p}}" name="file" checked="checked"/>
{{=file}} {{=file}}
</li> </li>
{{pass}} {{pass}}
{{for dir in files[path]['folders']:}} {{for dir in files[path]['folders']:}}
<li style="list-style-type: none;"> <li style="list-style-type: none;">
{{tree(os.path.join(path,dir))}} {{tree(os.path.join(path,dir))}}
</li> </li>
{{pass}} {{pass}}
</ul> </ul>
+107 -108
View File
@@ -7,57 +7,57 @@
<div class="applist_inner"> <div class="applist_inner">
<h2>{{=T("Installed applications")}}</h2> <h2>{{=T("Installed applications")}}</h2>
<table width="100%" class="table"> <table width="100%" class="table">
{{for a in apps:}} {{for a in apps:}}
<tr>{{buttons = []}} <tr>{{buttons = []}}
<td> <td>
{{if a==request.application:}} {{if a==request.application:}}
<h4 class="currentapp">{{=a}} ({{=T('currently running')}})</h4> <h4 class="currentapp">{{=a}} ({{=T('currently running')}})</h4>
{{else:}} {{else:}}
<h4 class="editableapp">{{=A(a,_href=URL(a,'default','index'))}}</h4> <h4 class="editableapp">{{=A(a,_href=URL(a,'default','index'))}}</h4>
{{if MULTI_USER_MODE and db.app(name=a):}}(created by {{="%(first_name)s %(last_name)s" % db.auth_user[db.app(name=a).owner]}}){{pass}} {{if MULTI_USER_MODE and db.app(name=a):}}(created by {{="%(first_name)s %(last_name)s" % db.auth_user[db.app(name=a).owner]}}){{pass}}
{{if not os.path.exists('applications/%s/compiled' % a):}} {{if not os.path.exists('applications/%s/compiled' % a):}}
{{buttons.append((URL('design',args=a), T("Edit")))}} {{buttons.append((URL('design',args=a), T("Edit")))}}
{{else:}} {{else:}}
{{buttons.append((URL(a,'appadmin','index'), T("appadmin")))}} {{buttons.append((URL(a,'appadmin','index'), T("appadmin")))}}
{{pass}} {{pass}}
{{buttons.append((URL('about',args=a), T("About")))}} {{buttons.append((URL('about',args=a), T("About")))}}
{{pass}} {{pass}}
{{buttons.append((URL('errors',args=a), T("Errors")))}} {{buttons.append((URL('errors',args=a), T("Errors")))}}
{{buttons.append((URL('cleanup',args=a), T("Clean")))}} {{buttons.append((URL('cleanup',args=a), T("Clean")))}}
{{buttons.append((URL('pack',args=a), T("Pack all")))}} {{buttons.append((URL('pack',args=a), T("Pack all")))}}
{{buttons.append((URL('pack_custom',args=a), T("Pack custom")))}} {{buttons.append((URL('pack_custom',args=a), T("Pack custom")))}}
{{if not os.path.exists('applications/%s/compiled' % a):}} {{if not os.path.exists('applications/%s/compiled' % a):}}
{{buttons.append((URL('compile_app',args=a), T("Compile")))}} {{buttons.append((URL('compile_app',args=a), T("Compile")))}}
{{else:}} {{else:}}
{{buttons.append((URL('pack',args=(a, 'compiled')), T("Pack compiled")))}} {{buttons.append((URL('pack',args=(a, 'compiled')), T("Pack compiled")))}}
{{if glob.glob('applications/%s/controllers/*.py' % a):}} {{if glob.glob('applications/%s/controllers/*.py' % a):}}
{{buttons.append((URL('remove_compiled_app',args=a), T("Remove compiled")))}} {{buttons.append((URL('remove_compiled_app',args=a), T("Remove compiled")))}}
{{pass}} {{pass}}
{{pass}} {{pass}}
{{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }} {{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }}
{{buttons.append((URL('git_pull',args=a), T("Git Pull")))}} {{buttons.append((URL('git_pull',args=a), T("Git Pull")))}}
{{buttons.append((URL('git_push',args=a), T("Git Push")))}} {{buttons.append((URL('git_push',args=a), T("Git Push")))}}
{{pass}} {{pass}}
{{if a!=request.application:}} {{if a!=request.application:}}
{{buttons.append((URL('uninstall',args=a), T("Uninstall")))}} {{buttons.append((URL('uninstall',args=a), T("Uninstall")))}}
{{pass}} {{pass}}
</td> </td>
<td> <td>
<div class="btn-group"> <div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
{{=T('Manage')}} {{=T('Manage')}}
<span class="caret"></span> <span class="caret"></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{{for link,name in buttons:}} {{for link,name in buttons:}}
{{=LI(A(name,_href=link))}} {{=LI(A(name,_href=link))}}
{{pass}} {{pass}}
</ul> </ul>
</div> </div>
{{=button_enable(URL('enable',args=a), a)}} {{=button_enable(URL('enable',args=a), a)}}
</td> </td>
</tr> </tr>
{{pass}} {{pass}}
</table> </table>
</div> </div>
</div> <!-- /applist --> </div> <!-- /applist -->
@@ -65,85 +65,85 @@
<div class="sidebar_inner controls well well-small"> <div class="sidebar_inner controls well well-small">
<!-- CHANGE ADMIN PWD --> <!-- CHANGE ADMIN PWD -->
<div class="pwdchange pull-right"> <div class="pwdchange pull-right">
{{if MULTI_USER_MODE:}} {{if MULTI_USER_MODE:}}
{{=auth.navbar()}} {{=auth.navbar()}}
{{else:}} {{else:}}
{{=sp_button(URL('change_password'), T('Change admin password'))}} {{=sp_button(URL('change_password'), T('Change admin password'))}}
{{=button(URL('default','reload_routes'), T('Reload routes'))}} {{=button(URL('default','reload_routes'), T('Reload routes'))}}
{{pass}} {{pass}}
</div> <!-- /CHANGE ADMIN PWD --> </div> <!-- /CHANGE ADMIN PWD -->
{{if is_manager():}} {{if is_manager():}}
<!-- VERSION --> <!-- VERSION -->
<div class="box"> <div class="box">
<h4>{{=T("Version")}}</h4> <h4>{{=T("Version")}}</h4>
<p> <p>
<tt>{{=myversion}}</tt><br/> <tt>{{=myversion}}</tt><br/>
({{=T("Running on %s", request.env.server_software)}}) ({{=T("Running on %s", request.env.server_software)}})
</p> </p>
<p id="check_version" class="row-buttons"> <p id="check_version" class="row-buttons">
{{if session.check_version:}} {{if session.check_version:}}
{{=T('Checking for upgrades...')}} {{=T('Checking for upgrades...')}}
<script>ajax('{{=URL('check_version')}}',[],'check_version');</script> <script>ajax('{{=URL('check_version')}}',[],'check_version');</script>
{{session.check_version=False}} {{session.check_version=False}}
{{else:}} {{else:}}
{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}} {{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}}
{{pass}} {{pass}}
</p> </p>
{{if session.is_mobile=='auto':}} {{if session.is_mobile=='auto':}}
<p>{{=A(T('Try the mobile interface'),_href=URL('plugin_jqmobile','about'))}}</p> <p>{{=A(T('Try the mobile interface'),_href=URL('plugin_jqmobile','about'))}}</p>
{{pass}} {{pass}}
</div> <!-- /VERSION --> </div> <!-- /VERSION -->
{{pass}} {{pass}}
{{if MULTI_USER_MODE and is_manager():}} {{if MULTI_USER_MODE and is_manager():}}
<!-- MULTI_USER_INTERFACE --> <!-- MULTI_USER_INTERFACE -->
<div class="box"> <div class="box">
<h4>{{=T("Multi User Mode")}}</h4> <h4>{{=T("Multi User Mode")}}</h4>
<p class="row-buttons"> <p class="row-buttons">
{{=button(URL('bulk_register'),T('Bulk Register'))}} {{=button(URL('bulk_register'),T('Bulk Register'))}}
{{=button(URL('manage_students',vars={'order':'auth_user.id'}),T('Manage Students'))}} {{=button(URL('manage_students',vars={'order':'auth_user.id'}),T('Manage Students'))}}
</p> </p>
</div> <!-- /MULTI_USER_INTERFACE --> </div> <!-- /MULTI_USER_INTERFACE -->
{{pass}} {{pass}}
<!-- SCAFFOLD APP --> <!-- SCAFFOLD APP -->
<div class="box"> <div class="box">
<h4>{{=T("New simple application")}}</h4> <h4>{{=T("New simple application")}}</h4>
{{=form_create.custom.begin}} {{=form_create.custom.begin}}
{{=LABEL(T("Application name:"))}} {{=LABEL(T("Application name:"))}}
{{=form_create.custom.widget.name}} {{=form_create.custom.widget.name}}
<div class="controls"><button type="submit" class="btn">{{=T('Create')}}</button></div> <div class="controls"><button type="submit" class="btn">{{=T('Create')}}</button></div>
{{=form_create.custom.end}} {{=form_create.custom.end}}
</div> <!-- /SCAFFOLD APP --> </div> <!-- /SCAFFOLD APP -->
<!-- UPLOAD PACKAGE --> <!-- UPLOAD PACKAGE -->
<div class="box"> <div class="box">
<h4>{{=T("Upload and install packed application")}}</h4> <h4>{{=T("Upload and install packed application")}}</h4>
{{=form_update.custom.begin}} {{=form_update.custom.begin}}
<label for="appupdate_name">{{=T("Application name:")}}</label> <label for="appupdate_name">{{=T("Application name:")}}</label>
{{=form_update.custom.widget.name}} {{=form_update.custom.widget.name}}
<label for="appupdate_file">{{=T("Upload a package:")}}</label> <label for="appupdate_file">{{=T("Upload a package:")}}</label>
{{=form_update.custom.widget.file}} {{=form_update.custom.widget.file}}
<label for="appupdate_url">{{=T("Or Get from URL:")}}</label> <label for="appupdate_url">{{=T("Or Get from URL:")}}</label>
{{=form_update.custom.widget.url}}<small class="help-block">({{=T('can be a git repo')}})</small> {{=form_update.custom.widget.url}}<small class="help-block">({{=T('can be a git repo')}})</small>
<div class="controls"> <div class="controls">
<label class="checkbox"> <label class="checkbox">
{{=form_update.custom.widget.overwrite}} {{=T("Overwrite installed app")}} {{=form_update.custom.widget.overwrite}} {{=T("Overwrite installed app")}}
</label> </label>
<button type="submit" class='btn'>{{=T('Install')}}</button> <button type="submit" class='btn'>{{=T('Install')}}</button>
</div> </div>
{{=form_update.custom.end}} {{=form_update.custom.end}}
</div> <!-- /UPLOAD PACKAGE --> </div> <!-- /UPLOAD PACKAGE -->
<!-- DEPLOY ON GAE --> <!-- DEPLOY ON GAE -->
<div class="box"> <div class="box">
<h4>{{=T("Deploy")}}</h4> <h4>{{=T("Deploy")}}</h4>
<p class="row-buttons"> <p class="row-buttons">
{{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}} {{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}}
{{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}} {{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}
</p> </p>
</div> <!-- /DEPLOY ON GAE --> </div> <!-- /DEPLOY ON GAE -->
<!-- APP WIZARD --> <!-- APP WIZARD -->
<div class="box"> <div class="box">
<h4>{{=T("New application wizard")}}</h4> <h4>{{=T("New application wizard")}}</h4>
<p>{{=button(URL('wizard','index'), T('Start wizard'))}}<br/> <p>{{=button(URL('wizard','index'), T('Start wizard'))}}<br/>
{{=T("(requires internet access, experimental)")}}</p> {{=T("(requires internet access, experimental)")}}</p>
</div> <!-- /APP WIZARD --> </div> <!-- /APP WIZARD -->
<a class="twitter-timeline" href="https://twitter.com/web2py" data-widget-id="340456915207327745">Tweets by @web2py</a> <a class="twitter-timeline" href="https://twitter.com/web2py" data-widget-id="340456915207327745">Tweets by @web2py</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
@@ -151,4 +151,3 @@
</div> <!-- /sidebar --> </div> <!-- /sidebar -->
</div> <!-- /row-fluid </div> <!-- /row-fluid
<!-- end "site" block --> <!-- end "site" block -->
+39 -39
View File
@@ -16,7 +16,7 @@
<tr> <tr>
<th>Python</th> <th>Python</th>
<td>{{=snapshot.get('pyver','')}}</td> <td>{{=snapshot.get('pyver','')}}</td>
</tr> </tr>
{{pass}} {{pass}}
</tbody> </tbody>
</table> </table>
@@ -45,14 +45,14 @@
<div class="inspect"> <div class="inspect">
<h4>{{=T("Exception instance attributes")}}</h4> <h4>{{=T("Exception instance attributes")}}</h4>
<table> <table>
<tbody> <tbody>
{{for k,v in snapshot['exception'].items():}} {{for k,v in snapshot['exception'].items():}}
<tr> <tr>
<th>{{=k}}</th> <th>{{=k}}</th>
<td>{{=v}}</td> <td>{{=v}}</td>
</tr> </tr>
{{pass}} {{pass}}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
@@ -65,36 +65,36 @@
<li> <li>
{{is_hidden = (i != len(snapshot['frames'])-1 and 'hide' or 'inspect')}} {{is_hidden = (i != len(snapshot['frames'])-1 and 'hide' or 'inspect')}}
<div class="framefile inspect controls"> <div class="framefile inspect controls">
<p> <p>
<strong>File {{="%s in %s at line %s" % (frame['file'], frame['func'], frame['lnum'])}}</strong> <strong>File {{="%s in %s at line %s" % (frame['file'], frame['func'], frame['lnum'])}}</strong>
<a class="button tbbutton btn" onclick="collapse('{{='%s_code_inner' % i}}');"><span>{{=T("code")}}</span></a> <a class="button tbbutton btn" onclick="collapse('{{='%s_code_inner' % i}}');"><span>{{=T("code")}}</span></a>
<a class="button tbbutton btn" onclick="collapse('{{='%s_args_inner' % i}}');"><span>{{=T("arguments")}}</span></a> <a class="button tbbutton btn" onclick="collapse('{{='%s_args_inner' % i}}');"><span>{{=T("arguments")}}</span></a>
<a class="button tbbutton btn" onclick="collapse('{{='%s_vars_inner' % i}}');"><span>{{=T("variables")}}</span></a> <a class="button tbbutton btn" onclick="collapse('{{='%s_vars_inner' % i}}');"><span>{{=T("variables")}}</span></a>
</p> </p>
<div id="{{='%s_args_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto"> <div id="{{='%s_args_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto">
<h5>Function argument list</h5> <h5>Function argument list</h5>
<p>{{=frame['call']}}</p> <p>{{=frame['call']}}</p>
</div> </div>
<div id="{{='%s_code_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto"> <div id="{{='%s_code_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto">
<h5>Code listing</h5> <h5>Code listing</h5>
{{if frame['lines']:}} {{if frame['lines']:}}
<pre>{{=CODE('\n'.join([x[1] for x in sorted(frame['lines'].items(),key=lambda x: x[0])]), <pre>{{=CODE('\n'.join([x[1] for x in sorted(frame['lines'].items(),key=lambda x: x[0])]),
language='python', link=None, counter=min(frame['lines'].keys()), highlight_line=frame['lnum'])}}</pre> language='python', link=None, counter=min(frame['lines'].keys()), highlight_line=frame['lnum'])}}</pre>
{{pass}} {{pass}}
</div> </div>
<div id="{{='%s_vars_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto"> <div id="{{='%s_vars_inner' % i}}" class="{{=is_hidden}}" style="width:100%;overflow:auto">
<h5>Variables</h5> <h5>Variables</h5>
<table> <table>
<tbody> <tbody>
{{for k,v in frame['dump'].items():}} {{for k,v in frame['dump'].items():}}
<tr> <tr>
<th>{{=k}}</th> <th>{{=k}}</th>
<td>{{=v}}</td> <td>{{=v}}</td>
</tr> </tr>
{{pass}} {{pass}}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</li> </li>
{{pass}} {{pass}}
+30 -6
View File
@@ -78,11 +78,35 @@
jQuery("[rel=tooltip]").tooltip(); jQuery("[rel=tooltip]").tooltip();
}); });
</script> </script>
{{if request.function in ('index','site'):}} <script>
<a style="position:fixed;bottom:0;left:0;z-index:1000" href="https://groups.google.com/forum/?fromgroups#!forum/web2py" target="_blank"> // ====================
<!-- http://webchat.freenode.net/?channels=web2py" //--> // upload input mask
<img src="{{=URL('static','images/questions.png')}}" /> // ====================
</a>
{{pass}} function FileSelectHandler(e) {
e.stopPropagation();
var filename = e.target.value.split(/\\|\//).pop();
jQuery('#fileselect>span').removeClass('txtPlaceholder').text(filename)
}
jQuery(document).ready(function(){
var iupload = jQuery('#appupdate_file');
var ow = 300, oh = 20;
var iplaceholder = jQuery('<span class="txtPlaceholder">{{=T("no package selected")}}</span>'),
iuploadbtn = jQuery('<button class="btn btn-inverse btn-mini uploadbtn"><i class="icon-white icon-circle-arrow-up"></i></button>');
iupload
.addClass('masked')
.wrap('<div id="fileselect" style="width:'+ow+'px;height:'+oh+'px"></div>')
.on('change', function(event){FileSelectHandler(event)});
jQuery('#fileselect').append(iplaceholder, iuploadbtn);
});
</script>
{{if request.function in ('index','site'):}}
<a style="position:fixed;bottom:0;left:0;z-index:1000" href="https://groups.google.com/forum/?fromgroups#!forum/web2py" target="_blank">
<!-- http://webchat.freenode.net/?channels=web2py" //-->
<img src="{{=URL('static','images/questions.png')}}" />
</a>
{{pass}}
</body> </body>
</html> </html>
@@ -31,7 +31,7 @@
<link rel="apple-touch-icon" href="{{=URL('static','favicon.png')}}"> <link rel="apple-touch-icon" href="{{=URL('static','favicon.png')}}">
<!-- For the less-enabled mobile browsers like Opera Mini --> <!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" href="{{=URL('static','plugin_jqmobile/jquery.mobile-1.2.0.min.css')}}"> <link rel="stylesheet" href="{{=URL('static','plugin_jqmobile/jquery.mobile-1.3.1.min.css')}}">
<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects --> <!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="{{=URL('static','js/modernizr.custom.js')}}"></script!> <script src="{{=URL('static','js/modernizr.custom.js')}}"></script!>
@@ -61,7 +61,7 @@ $(document).bind("mobileinit", function(){
}); });
</script> </script>
<script src="{{=URL('static','plugin_jqmobile/jquery.mobile-1.2.0.min.js')}}"></script> <script src="{{=URL('static','plugin_jqmobile/jquery.mobile-1.3.1.min.js')}}"></script>
<style> <style>
.error { color: red; } .error { color: red; }
@@ -623,7 +623,10 @@ def manage():
orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None
elif table == auth.table_permission(): elif table == auth.table_permission():
orderby = 'group_id' orderby = 'group_id'
grid = SQLFORM.smartgrid(table, args=request.args[:2], user_signature=True, kwargs = dict(user_signature=True, maxtextlength=1000,
orderby=orderby, linked_tables=linked_tables, orderby=orderby, linked_tables=linked_tables)
maxtextlength=1000, formname=formname) smartgrid_args = manager_action.get('smartgrid_args', {})
kwargs.update(**smartgrid_args.get('DEFAULT', {}))
kwargs.update(**smartgrid_args.get(table._tablename, {}))
grid = SQLFORM.smartgrid(table, args=request.args[:2], formname=formname, **kwargs)
return grid return grid
@@ -90,6 +90,7 @@ div.controls select +.error_wrapper {margin-left:5px;}
.ie-lte7 div.error{color:#fff;} .ie-lte7 div.error{color:#fff;}
/* beautify brand */ /* beautify brand */
.navbar {margin-bottom:0}
.navbar-inverse .brand{color:#c6cecc;} .navbar-inverse .brand{color:#c6cecc;}
.navbar-inverse .brand b{display:inline-block;margin-top:-1px;} .navbar-inverse .brand b{display:inline-block;margin-top:-1px;}
.navbar-inverse .brand b>span{font-size:22px;color:white} .navbar-inverse .brand b>span{font-size:22px;color:white}
@@ -222,6 +223,10 @@ td.w2p_fw ul{margin-left:0px;}
/* auth_user_remember checkbox extrapadding in IE fix */ /* auth_user_remember checkbox extrapadding in IE fix */
.ie-lte9 input#auth_user_remember.checkbox {padding-left:0;} .ie-lte9 input#auth_user_remember.checkbox {padding-left:0;}
div.controls .error {
width: auto;
}
/*============================================================= /*=============================================================
MEDIA QUERIES MEDIA QUERIES
==============================================================*/ ==============================================================*/
+70 -61
View File
@@ -7,6 +7,10 @@
* Released under the MIT license * Released under the MIT license
* *
*/ */
if($.web2py !== undefined) {
$.error('web2py.js has already been loaded!');
}
String.prototype.reverse = function () { String.prototype.reverse = function () {
return this.split('').reverse().join(''); return this.split('').reverse().join('');
@@ -36,12 +40,13 @@
} }
} else { } else {
pcs = []; pcs = [];
if(s != null && s != undefined) for(i = 0; i < s.length; i++) { if(s != null && s != undefined)
for(i = 0; i < s.length; i++) {
q = $("[name=" + s[i] + "]").serialize(); q = $("[name=" + s[i] + "]").serialize();
if(q) { if(q) {
pcs.push(q); pcs.push(q);
} }
} }
if(pcs.length > 0) { if(pcs.length > 0) {
query = pcs.join("&"); query = pcs.join("&");
} }
@@ -147,9 +152,9 @@
web2py.component_handler(target); web2py.component_handler(target);
}, },
//manage errors in forms //manage errors in forms
manage_errors: function(target) { manage_errors: function (target) {
$('.error', target).hide().slideDown('slow'); $('.error', target).hide().slideDown('slow');
//$('.error', target).hide().fadeIn('slow'); //jQuery('.error', target).hide().fadeIn('slow');
}, },
event_handlers: function () { event_handlers: function () {
/* This is called once for page /* This is called once for page
@@ -172,7 +177,8 @@
}); });
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?"; var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
doc.on('click', "input[type='checkbox'].delete", function () { doc.on('click', "input[type='checkbox'].delete", function () {
if(this.checked) if(!web2py.confirm(confirm_message)) this.checked = false; if(this.checked)
if(!web2py.confirm(confirm_message)) this.checked = false;
}); });
doc.ajaxSuccess(function (e, xhr) { doc.ajaxSuccess(function (e, xhr) {
@@ -424,7 +430,7 @@
el.addClass('disabled'); el.addClass('disabled');
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
// store enabled state // store enabled state
el.data('w2p:enable-with', el[method]); el.data('w2p:enable-with', el[method]());
/* little addition by default*/ /* little addition by default*/
if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
el.data('w2p_disable_with', 'Working...'); el.data('w2p_disable_with', 'Working...');
@@ -441,7 +447,7 @@
enableElement: function (el) { enableElement: function (el) {
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
if(el.data('w2p:enable-with') !== undefined) { if(el.data('w2p:enable-with') !== undefined) {
// set to old enabled state // set to old enabled state
el[method](el.data('w2p:enable-with')); el[method](el.data('w2p:enable-with'));
el.removeData('w2p:enable-with'); // clean up cache el.removeData('w2p:enable-with'); // clean up cache
} }
@@ -453,39 +459,39 @@
web2py.component(action, target, 0, 1, element); web2py.component(action, target, 0, 1, element);
}, },
//helper for flash messages //helper for flash messages
flash: function(message, status) { flash: function (message, status) {
var flash = $('.flash'); var flash = $('.flash');
web2py.hide_flash(); web2py.hide_flash();
flash.html(message).addClass(status); flash.html(message).addClass(status);
if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown(); if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown();
}, },
hide_flash: function() { hide_flash: function () {
$('.flash').hide().html(''); $('.flash').hide().html('');
}, },
show_if_handler: function(target) { show_if_handler: function (target) {
var triggers = {}; var triggers = {};
var show_if = function () { var show_if = function () {
var t = $(this); var t = $(this);
var id = t.attr('id'); var id = t.attr('id');
t.attr('value', t.val()); t.attr('value', t.val());
for(var k = 0; k < triggers[id].length; k++) { for(var k = 0; k < triggers[id].length; k++) {
var dep = $('#' + triggers[id][k], target); var dep = $('#' + triggers[id][k], target);
var tr = $('#' + triggers[id][k] + '__row', target); var tr = $('#' + triggers[id][k] + '__row', target);
if(t.is(dep.attr('data-show-if'))) tr.slideDown(); if(t.is(dep.attr('data-show-if'))) tr.slideDown();
else tr.hide(); else tr.hide();
} }
}; };
$('[data-show-trigger]', target).each(function () { $('[data-show-trigger]', target).each(function () {
var name = $(this).attr('data-show-trigger'); var name = $(this).attr('data-show-trigger');
if(!triggers[name]) triggers[name] = []; if(!triggers[name]) triggers[name] = [];
triggers[name].push($(this).attr('id')); triggers[name].push($(this).attr('id'));
}); });
for(var name in triggers) { for(var name in triggers) {
$('#' + name, target).change(show_if).keyup(show_if); $('#' + name, target).change(show_if).keyup(show_if);
show_if.call($('#' + name, target)); show_if.call($('#' + name, target));
}; };
}, },
component_handler : function (target) { component_handler: function (target) {
$('div[data-w2p_remote]', target).each(function () { $('div[data-w2p_remote]', target).each(function () {
var remote, times, timeout, target; var remote, times, timeout, target;
var el = $(this); var el = $(this);
@@ -494,8 +500,7 @@
timeout = el.data('w2p_timeout'); timeout = el.data('w2p_timeout');
target = el.attr('id'); target = el.attr('id');
web2py.component(remote, target, timeout, times, $(this)); web2py.component(remote, target, timeout, times, $(this));
} })
)
}, },
a_handler: function (el, e) { a_handler: function (el, e) {
e.preventDefault(); e.preventDefault();
@@ -517,14 +522,16 @@
} }
if(target == undefined) { if(target == undefined) {
if(method == 'GET') { if(method == 'GET') {
web2py.simple_component(action, el.attr('id'), el); //not working with original web2py.ajax_page('get', action, [], 'bogus', el); //fixme?
//web2py.simple_component(action, el.attr('id'), el); //not working with original
} else if(method == 'POST') { } else if(method == 'POST') {
//should be web2py.ajax(action, [], ''); but it's too simple //should be web2py.ajax(action, [], ''); but it's too simple
web2py.ajax_page('post', action, [], 'bogus', el); //fixme? web2py.ajax_page('post', action, [], 'bogus', el); //fixme?
} }
} else { } else {
if(method == 'GET') { if(method == 'GET') {
web2py.simple_component(action, target, el); web2py.ajax_page('get', action, [], target, el);
//web2py.simple_component(action, target, el);
} else if(method == 'POST') { } else if(method == 'POST') {
//should be web2py.ajax(action, [], target); but it's too simple //should be web2py.ajax(action, [], target); but it's too simple
web2py.ajax_page('post', action, [], target, el); web2py.ajax_page('post', action, [], target, el);
@@ -539,7 +546,7 @@
toremove = el.closest(toremove); toremove = el.closest(toremove);
if(!toremove.length) { if(!toremove.length) {
//this enables removal of whatever selector if a closest is not found //this enables removal of whatever selector if a closest is not found
toremove = $(toremove); toremove = jQuery(toremove);
} }
toremove.remove(); toremove.remove();
} }
@@ -571,16 +578,17 @@
web2py.enableElement($(this)); web2py.enableElement($(this));
}); });
}, },
/* Disables form elements: /* Disables form elements:
- Caches element value in 'ujs:enable-with' data store - Caches element value in 'ujs:enable-with' data store
- Replaces element text with value of 'data-disable-with' attribute - Replaces element text with value of 'data-disable-with' attribute
- Sets disabled property to true - Sets disabled property to true
*/ */
disableFormElements: function(form) { disableFormElements: function (form) {
form.find(web2py.disableSelector).each(function() { form.find(web2py.disableSelector).each(function () {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this),
method = element.is('button') ? 'html' : 'val';
var disable_with = element.data('w2p_disable_with'); var disable_with = element.data('w2p_disable_with');
if (disable_with == undefined) { if(disable_with == undefined) {
element.data('w2p_disable_with', element[method]()) element.data('w2p_disable_with', element[method]())
} }
element.data('w2p:enable-with', element[method]()); element.data('w2p:enable-with', element[method]());
@@ -593,14 +601,15 @@
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Sets disabled property to false - Sets disabled property to false
*/ */
enableFormElements: function(form) { enableFormElements: function (form) {
form.find(web2py.enableSelector).each(function() { form.find(web2py.enableSelector).each(function () {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this),
if (element.data('w2p:enable-with')) element[method](element.data('w2p:enable-with')); method = element.is('button') ? 'html' : 'val';
if(element.data('w2p:enable-with')) element[method](element.data('w2p:enable-with'));
element.prop('disabled', false); element.prop('disabled', false);
}); });
}, },
form_handlers: function() { form_handlers: function () {
var el = $(document); var el = $(document);
el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) {
web2py.disableFormElements($(this)); web2py.disableFormElements($(this));
@@ -626,28 +635,28 @@
})(jQuery); })(jQuery);
/* compatibility code - start */ /* compatibility code - start */
ajax = $.web2py.ajax; ajax = jQuery.web2py.ajax;
web2py_component = $.web2py.component; web2py_component = jQuery.web2py.component;
web2py_websocket = $.web2py.websocket; web2py_websocket = jQuery.web2py.websocket;
web2py_ajax_page = $.web2py.ajax_page; web2py_ajax_page = jQuery.web2py.ajax_page;
//needed for IS_STRONG(entropy) //needed for IS_STRONG(entropy)
web2py_validate_entropy = $.web2py.validate_entropy; web2py_validate_entropy = jQuery.web2py.validate_entropy;
//needed for crud.search and SQLFORM.grid's search //needed for crud.search and SQLFORM.grid's search
web2py_ajax_fields = $.web2py.ajax_fields; web2py_ajax_fields = jQuery.web2py.ajax_fields;
//used for LOAD(ajax=False) //used for LOAD(ajax=False)
web2py_trap_form = $.web2py.trap_form; web2py_trap_form = jQuery.web2py.trap_form;
/*undocumented - rare*/ /*undocumented - rare*/
popup = $.web2py.popup; popup = jQuery.web2py.popup;
collapse = $.web2py.collapse; collapse = jQuery.web2py.collapse;
fade = $.web2py.fade; fade = jQuery.web2py.fade;
/* internals - shouldn't be needed /* internals - shouldn't be needed
web2py_ajax_init = $.web2py.ajax_init; web2py_ajax_init = jQuery.web2py.ajax_init;
web2py_event_handlers = $.web2py.event_handlers; web2py_event_handlers = jQuery.web2py.event_handlers;
web2py_trap_link = $.web2py.trap_link; web2py_trap_link = jQuery.web2py.trap_link;
web2py_calc_entropy = $.web2py.calc_entropy; web2py_calc_entropy = jQuery.web2py.calc_entropy;
*/ */
/* compatibility code - end*/ /* compatibility code - end*/
+6 -3
View File
@@ -623,7 +623,10 @@ def manage():
orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None
elif table == auth.table_permission(): elif table == auth.table_permission():
orderby = 'group_id' orderby = 'group_id'
grid = SQLFORM.smartgrid(table, args=request.args[:2], user_signature=True, kwargs = dict(user_signature=True, maxtextlength=1000,
orderby=orderby, linked_tables=linked_tables, orderby=orderby, linked_tables=linked_tables)
maxtextlength=1000, formname=formname) smartgrid_args = manager_action.get('smartgrid_args', {})
kwargs.update(**smartgrid_args.get('DEFAULT', {}))
kwargs.update(**smartgrid_args.get(table._tablename, {}))
grid = SQLFORM.smartgrid(table, args=request.args[:2], formname=formname, **kwargs)
return grid return grid
@@ -223,16 +223,21 @@ td.w2p_fw ul{margin-left:0px;}
/* auth_user_remember checkbox extrapadding in IE fix */ /* auth_user_remember checkbox extrapadding in IE fix */
.ie-lte9 input#auth_user_remember.checkbox {padding-left:0;} .ie-lte9 input#auth_user_remember.checkbox {padding-left:0;}
div.controls .error {
width: auto;
}
/*============================================================= /*=============================================================
MEDIA QUERIES MEDIA QUERIES
==============================================================*/ ==============================================================*/
@media only screen and (max-width:979px){ @media only screen and (max-width:979px){
body{padding-top:0px;} body{padding-top:0px;}
#navbar{top:5px;} #navbar{/*top:5px;*/}
div.flash{right:5px;} div.flash{right:5px;}
.dropdown-menu ul{visibility:visible;} .dropdown-menu ul{visibility:visible;}
} }
@media only screen and (max-width:479px){ @media only screen and (max-width:479px){
body{ body{
padding-left:10px; padding-left:10px;
@@ -246,3 +251,10 @@ td.w2p_fw ul{margin-left:0px;}
width:95%; width:95%;
} }
} }
@media (max-width: 767px) {
.navbar {
margin-right: -20px;
margin-left: -20px;
}
}
+70 -61
View File
@@ -7,6 +7,10 @@
* Released under the MIT license * Released under the MIT license
* *
*/ */
if($.web2py !== undefined) {
$.error('web2py.js has already been loaded!');
}
String.prototype.reverse = function () { String.prototype.reverse = function () {
return this.split('').reverse().join(''); return this.split('').reverse().join('');
@@ -36,12 +40,13 @@
} }
} else { } else {
pcs = []; pcs = [];
if(s != null && s != undefined) for(i = 0; i < s.length; i++) { if(s != null && s != undefined)
for(i = 0; i < s.length; i++) {
q = $("[name=" + s[i] + "]").serialize(); q = $("[name=" + s[i] + "]").serialize();
if(q) { if(q) {
pcs.push(q); pcs.push(q);
} }
} }
if(pcs.length > 0) { if(pcs.length > 0) {
query = pcs.join("&"); query = pcs.join("&");
} }
@@ -147,9 +152,9 @@
web2py.component_handler(target); web2py.component_handler(target);
}, },
//manage errors in forms //manage errors in forms
manage_errors: function(target) { manage_errors: function (target) {
$('.error', target).hide().slideDown('slow'); $('.error', target).hide().slideDown('slow');
//$('.error', target).hide().fadeIn('slow'); //jQuery('.error', target).hide().fadeIn('slow');
}, },
event_handlers: function () { event_handlers: function () {
/* This is called once for page /* This is called once for page
@@ -172,7 +177,8 @@
}); });
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?"; var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
doc.on('click', "input[type='checkbox'].delete", function () { doc.on('click', "input[type='checkbox'].delete", function () {
if(this.checked) if(!web2py.confirm(confirm_message)) this.checked = false; if(this.checked)
if(!web2py.confirm(confirm_message)) this.checked = false;
}); });
doc.ajaxSuccess(function (e, xhr) { doc.ajaxSuccess(function (e, xhr) {
@@ -424,7 +430,7 @@
el.addClass('disabled'); el.addClass('disabled');
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
// store enabled state // store enabled state
el.data('w2p:enable-with', el[method]); el.data('w2p:enable-with', el[method]());
/* little addition by default*/ /* little addition by default*/
if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) { if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
el.data('w2p_disable_with', 'Working...'); el.data('w2p_disable_with', 'Working...');
@@ -441,7 +447,7 @@
enableElement: function (el) { enableElement: function (el) {
var method = el.prop('type') == 'submit' ? 'val' : 'html'; var method = el.prop('type') == 'submit' ? 'val' : 'html';
if(el.data('w2p:enable-with') !== undefined) { if(el.data('w2p:enable-with') !== undefined) {
// set to old enabled state // set to old enabled state
el[method](el.data('w2p:enable-with')); el[method](el.data('w2p:enable-with'));
el.removeData('w2p:enable-with'); // clean up cache el.removeData('w2p:enable-with'); // clean up cache
} }
@@ -453,39 +459,39 @@
web2py.component(action, target, 0, 1, element); web2py.component(action, target, 0, 1, element);
}, },
//helper for flash messages //helper for flash messages
flash: function(message, status) { flash: function (message, status) {
var flash = $('.flash'); var flash = $('.flash');
web2py.hide_flash(); web2py.hide_flash();
flash.html(message).addClass(status); flash.html(message).addClass(status);
if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown(); if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown();
}, },
hide_flash: function() { hide_flash: function () {
$('.flash').hide().html(''); $('.flash').hide().html('');
}, },
show_if_handler: function(target) { show_if_handler: function (target) {
var triggers = {}; var triggers = {};
var show_if = function () { var show_if = function () {
var t = $(this); var t = $(this);
var id = t.attr('id'); var id = t.attr('id');
t.attr('value', t.val()); t.attr('value', t.val());
for(var k = 0; k < triggers[id].length; k++) { for(var k = 0; k < triggers[id].length; k++) {
var dep = $('#' + triggers[id][k], target); var dep = $('#' + triggers[id][k], target);
var tr = $('#' + triggers[id][k] + '__row', target); var tr = $('#' + triggers[id][k] + '__row', target);
if(t.is(dep.attr('data-show-if'))) tr.slideDown(); if(t.is(dep.attr('data-show-if'))) tr.slideDown();
else tr.hide(); else tr.hide();
} }
}; };
$('[data-show-trigger]', target).each(function () { $('[data-show-trigger]', target).each(function () {
var name = $(this).attr('data-show-trigger'); var name = $(this).attr('data-show-trigger');
if(!triggers[name]) triggers[name] = []; if(!triggers[name]) triggers[name] = [];
triggers[name].push($(this).attr('id')); triggers[name].push($(this).attr('id'));
}); });
for(var name in triggers) { for(var name in triggers) {
$('#' + name, target).change(show_if).keyup(show_if); $('#' + name, target).change(show_if).keyup(show_if);
show_if.call($('#' + name, target)); show_if.call($('#' + name, target));
}; };
}, },
component_handler : function (target) { component_handler: function (target) {
$('div[data-w2p_remote]', target).each(function () { $('div[data-w2p_remote]', target).each(function () {
var remote, times, timeout, target; var remote, times, timeout, target;
var el = $(this); var el = $(this);
@@ -494,8 +500,7 @@
timeout = el.data('w2p_timeout'); timeout = el.data('w2p_timeout');
target = el.attr('id'); target = el.attr('id');
web2py.component(remote, target, timeout, times, $(this)); web2py.component(remote, target, timeout, times, $(this));
} })
)
}, },
a_handler: function (el, e) { a_handler: function (el, e) {
e.preventDefault(); e.preventDefault();
@@ -517,14 +522,16 @@
} }
if(target == undefined) { if(target == undefined) {
if(method == 'GET') { if(method == 'GET') {
web2py.simple_component(action, el.attr('id'), el); //not working with original web2py.ajax_page('get', action, [], 'bogus', el); //fixme?
//web2py.simple_component(action, el.attr('id'), el); //not working with original
} else if(method == 'POST') { } else if(method == 'POST') {
//should be web2py.ajax(action, [], ''); but it's too simple //should be web2py.ajax(action, [], ''); but it's too simple
web2py.ajax_page('post', action, [], 'bogus', el); //fixme? web2py.ajax_page('post', action, [], 'bogus', el); //fixme?
} }
} else { } else {
if(method == 'GET') { if(method == 'GET') {
web2py.simple_component(action, target, el); web2py.ajax_page('get', action, [], target, el);
//web2py.simple_component(action, target, el);
} else if(method == 'POST') { } else if(method == 'POST') {
//should be web2py.ajax(action, [], target); but it's too simple //should be web2py.ajax(action, [], target); but it's too simple
web2py.ajax_page('post', action, [], target, el); web2py.ajax_page('post', action, [], target, el);
@@ -539,7 +546,7 @@
toremove = el.closest(toremove); toremove = el.closest(toremove);
if(!toremove.length) { if(!toremove.length) {
//this enables removal of whatever selector if a closest is not found //this enables removal of whatever selector if a closest is not found
toremove = $(toremove); toremove = jQuery(toremove);
} }
toremove.remove(); toremove.remove();
} }
@@ -571,16 +578,17 @@
web2py.enableElement($(this)); web2py.enableElement($(this));
}); });
}, },
/* Disables form elements: /* Disables form elements:
- Caches element value in 'ujs:enable-with' data store - Caches element value in 'ujs:enable-with' data store
- Replaces element text with value of 'data-disable-with' attribute - Replaces element text with value of 'data-disable-with' attribute
- Sets disabled property to true - Sets disabled property to true
*/ */
disableFormElements: function(form) { disableFormElements: function (form) {
form.find(web2py.disableSelector).each(function() { form.find(web2py.disableSelector).each(function () {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this),
method = element.is('button') ? 'html' : 'val';
var disable_with = element.data('w2p_disable_with'); var disable_with = element.data('w2p_disable_with');
if (disable_with == undefined) { if(disable_with == undefined) {
element.data('w2p_disable_with', element[method]()) element.data('w2p_disable_with', element[method]())
} }
element.data('w2p:enable-with', element[method]()); element.data('w2p:enable-with', element[method]());
@@ -593,14 +601,15 @@
- Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
- Sets disabled property to false - Sets disabled property to false
*/ */
enableFormElements: function(form) { enableFormElements: function (form) {
form.find(web2py.enableSelector).each(function() { form.find(web2py.enableSelector).each(function () {
var element = $(this), method = element.is('button') ? 'html' : 'val'; var element = $(this),
if (element.data('w2p:enable-with')) element[method](element.data('w2p:enable-with')); method = element.is('button') ? 'html' : 'val';
if(element.data('w2p:enable-with')) element[method](element.data('w2p:enable-with'));
element.prop('disabled', false); element.prop('disabled', false);
}); });
}, },
form_handlers: function() { form_handlers: function () {
var el = $(document); var el = $(document);
el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) { el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) {
web2py.disableFormElements($(this)); web2py.disableFormElements($(this));
@@ -626,28 +635,28 @@
})(jQuery); })(jQuery);
/* compatibility code - start */ /* compatibility code - start */
ajax = $.web2py.ajax; ajax = jQuery.web2py.ajax;
web2py_component = $.web2py.component; web2py_component = jQuery.web2py.component;
web2py_websocket = $.web2py.websocket; web2py_websocket = jQuery.web2py.websocket;
web2py_ajax_page = $.web2py.ajax_page; web2py_ajax_page = jQuery.web2py.ajax_page;
//needed for IS_STRONG(entropy) //needed for IS_STRONG(entropy)
web2py_validate_entropy = $.web2py.validate_entropy; web2py_validate_entropy = jQuery.web2py.validate_entropy;
//needed for crud.search and SQLFORM.grid's search //needed for crud.search and SQLFORM.grid's search
web2py_ajax_fields = $.web2py.ajax_fields; web2py_ajax_fields = jQuery.web2py.ajax_fields;
//used for LOAD(ajax=False) //used for LOAD(ajax=False)
web2py_trap_form = $.web2py.trap_form; web2py_trap_form = jQuery.web2py.trap_form;
/*undocumented - rare*/ /*undocumented - rare*/
popup = $.web2py.popup; popup = jQuery.web2py.popup;
collapse = $.web2py.collapse; collapse = jQuery.web2py.collapse;
fade = $.web2py.fade; fade = jQuery.web2py.fade;
/* internals - shouldn't be needed /* internals - shouldn't be needed
web2py_ajax_init = $.web2py.ajax_init; web2py_ajax_init = jQuery.web2py.ajax_init;
web2py_event_handlers = $.web2py.event_handlers; web2py_event_handlers = jQuery.web2py.event_handlers;
web2py_trap_link = $.web2py.trap_link; web2py_trap_link = jQuery.web2py.trap_link;
web2py_calc_entropy = $.web2py.calc_entropy; web2py_calc_entropy = jQuery.web2py.calc_entropy;
*/ */
/* compatibility code - end*/ /* compatibility code - end*/
+2 -2
View File
@@ -58,8 +58,8 @@
}} }}
<!-- uncomment here to load jquery-ui <!-- uncomment here to load jquery-ui
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" /> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/base/jquery-ui.css" type="text/css" media="all" />
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js" type="text/javascript"></script>
uncomment to load jquery-ui //--> uncomment to load jquery-ui //-->
<noscript><link href="{{=URL('static', 'css/web2py_bootstrap_nojs.css')}}" rel="stylesheet" type="text/css" /></noscript> <noscript><link href="{{=URL('static', 'css/web2py_bootstrap_nojs.css')}}" rel="stylesheet" type="text/css" /></noscript>
{{block head}}{{end}} {{block head}}{{end}}
+92
View File
@@ -81,6 +81,8 @@ _charsets.add(Charset(41, 'latin7', 'latin7_general_ci', 'Yes'))
_charsets.add(Charset(42, 'latin7', 'latin7_general_cs', '')) _charsets.add(Charset(42, 'latin7', 'latin7_general_cs', ''))
_charsets.add(Charset(43, 'macce', 'macce_bin', '')) _charsets.add(Charset(43, 'macce', 'macce_bin', ''))
_charsets.add(Charset(44, 'cp1250', 'cp1250_croatian_ci', '')) _charsets.add(Charset(44, 'cp1250', 'cp1250_croatian_ci', ''))
_charsets.add(Charset(45, 'utf8mb4', 'utf8mb4_general_ci', 'Yes'))
_charsets.add(Charset(46, 'utf8mb4', 'utf8mb4_bin', ''))
_charsets.add(Charset(47, 'latin1', 'latin1_bin', '')) _charsets.add(Charset(47, 'latin1', 'latin1_bin', ''))
_charsets.add(Charset(48, 'latin1', 'latin1_general_ci', '')) _charsets.add(Charset(48, 'latin1', 'latin1_general_ci', ''))
_charsets.add(Charset(49, 'latin1', 'latin1_general_cs', '')) _charsets.add(Charset(49, 'latin1', 'latin1_general_cs', ''))
@@ -88,9 +90,15 @@ _charsets.add(Charset(50, 'cp1251', 'cp1251_bin', ''))
_charsets.add(Charset(51, 'cp1251', 'cp1251_general_ci', 'Yes')) _charsets.add(Charset(51, 'cp1251', 'cp1251_general_ci', 'Yes'))
_charsets.add(Charset(52, 'cp1251', 'cp1251_general_cs', '')) _charsets.add(Charset(52, 'cp1251', 'cp1251_general_cs', ''))
_charsets.add(Charset(53, 'macroman', 'macroman_bin', '')) _charsets.add(Charset(53, 'macroman', 'macroman_bin', ''))
_charsets.add(Charset(54, 'utf16', 'utf16_general_ci', 'Yes'))
_charsets.add(Charset(55, 'utf16', 'utf16_bin', ''))
_charsets.add(Charset(56, 'utf16le', 'utf16le_general_ci', 'Yes'))
_charsets.add(Charset(57, 'cp1256', 'cp1256_general_ci', 'Yes')) _charsets.add(Charset(57, 'cp1256', 'cp1256_general_ci', 'Yes'))
_charsets.add(Charset(58, 'cp1257', 'cp1257_bin', '')) _charsets.add(Charset(58, 'cp1257', 'cp1257_bin', ''))
_charsets.add(Charset(59, 'cp1257', 'cp1257_general_ci', 'Yes')) _charsets.add(Charset(59, 'cp1257', 'cp1257_general_ci', 'Yes'))
_charsets.add(Charset(60, 'utf32', 'utf32_general_ci', 'Yes'))
_charsets.add(Charset(61, 'utf32', 'utf32_bin', ''))
_charsets.add(Charset(62, 'utf16le', 'utf16le_bin', ''))
_charsets.add(Charset(63, 'binary', 'binary', 'Yes')) _charsets.add(Charset(63, 'binary', 'binary', 'Yes'))
_charsets.add(Charset(64, 'armscii8', 'armscii8_bin', '')) _charsets.add(Charset(64, 'armscii8', 'armscii8_bin', ''))
_charsets.add(Charset(65, 'ascii', 'ascii_bin', '')) _charsets.add(Charset(65, 'ascii', 'ascii_bin', ''))
@@ -127,6 +135,30 @@ _charsets.add(Charset(96, 'cp932', 'cp932_bin', ''))
_charsets.add(Charset(97, 'eucjpms', 'eucjpms_japanese_ci', 'Yes')) _charsets.add(Charset(97, 'eucjpms', 'eucjpms_japanese_ci', 'Yes'))
_charsets.add(Charset(98, 'eucjpms', 'eucjpms_bin', '')) _charsets.add(Charset(98, 'eucjpms', 'eucjpms_bin', ''))
_charsets.add(Charset(99, 'cp1250', 'cp1250_polish_ci', '')) _charsets.add(Charset(99, 'cp1250', 'cp1250_polish_ci', ''))
_charsets.add(Charset(101, 'utf16', 'utf16_unicode_ci', ''))
_charsets.add(Charset(102, 'utf16', 'utf16_icelandic_ci', ''))
_charsets.add(Charset(103, 'utf16', 'utf16_latvian_ci', ''))
_charsets.add(Charset(104, 'utf16', 'utf16_romanian_ci', ''))
_charsets.add(Charset(105, 'utf16', 'utf16_slovenian_ci', ''))
_charsets.add(Charset(106, 'utf16', 'utf16_polish_ci', ''))
_charsets.add(Charset(107, 'utf16', 'utf16_estonian_ci', ''))
_charsets.add(Charset(108, 'utf16', 'utf16_spanish_ci', ''))
_charsets.add(Charset(109, 'utf16', 'utf16_swedish_ci', ''))
_charsets.add(Charset(110, 'utf16', 'utf16_turkish_ci', ''))
_charsets.add(Charset(111, 'utf16', 'utf16_czech_ci', ''))
_charsets.add(Charset(112, 'utf16', 'utf16_danish_ci', ''))
_charsets.add(Charset(113, 'utf16', 'utf16_lithuanian_ci', ''))
_charsets.add(Charset(114, 'utf16', 'utf16_slovak_ci', ''))
_charsets.add(Charset(115, 'utf16', 'utf16_spanish2_ci', ''))
_charsets.add(Charset(116, 'utf16', 'utf16_roman_ci', ''))
_charsets.add(Charset(117, 'utf16', 'utf16_persian_ci', ''))
_charsets.add(Charset(118, 'utf16', 'utf16_esperanto_ci', ''))
_charsets.add(Charset(119, 'utf16', 'utf16_hungarian_ci', ''))
_charsets.add(Charset(120, 'utf16', 'utf16_sinhala_ci', ''))
_charsets.add(Charset(121, 'utf16', 'utf16_german2_ci', ''))
_charsets.add(Charset(122, 'utf16', 'utf16_croatian_ci', ''))
_charsets.add(Charset(123, 'utf16', 'utf16_unicode_520_ci', ''))
_charsets.add(Charset(124, 'utf16', 'utf16_vietnamese_ci', ''))
_charsets.add(Charset(128, 'ucs2', 'ucs2_unicode_ci', '')) _charsets.add(Charset(128, 'ucs2', 'ucs2_unicode_ci', ''))
_charsets.add(Charset(129, 'ucs2', 'ucs2_icelandic_ci', '')) _charsets.add(Charset(129, 'ucs2', 'ucs2_icelandic_ci', ''))
_charsets.add(Charset(130, 'ucs2', 'ucs2_latvian_ci', '')) _charsets.add(Charset(130, 'ucs2', 'ucs2_latvian_ci', ''))
@@ -146,6 +178,36 @@ _charsets.add(Charset(143, 'ucs2', 'ucs2_roman_ci', ''))
_charsets.add(Charset(144, 'ucs2', 'ucs2_persian_ci', '')) _charsets.add(Charset(144, 'ucs2', 'ucs2_persian_ci', ''))
_charsets.add(Charset(145, 'ucs2', 'ucs2_esperanto_ci', '')) _charsets.add(Charset(145, 'ucs2', 'ucs2_esperanto_ci', ''))
_charsets.add(Charset(146, 'ucs2', 'ucs2_hungarian_ci', '')) _charsets.add(Charset(146, 'ucs2', 'ucs2_hungarian_ci', ''))
_charsets.add(Charset(147, 'ucs2', 'ucs2_sinhala_ci', ''))
_charsets.add(Charset(148, 'ucs2', 'ucs2_german2_ci', ''))
_charsets.add(Charset(149, 'ucs2', 'ucs2_croatian_ci', ''))
_charsets.add(Charset(150, 'ucs2', 'ucs2_unicode_520_ci', ''))
_charsets.add(Charset(151, 'ucs2', 'ucs2_vietnamese_ci', ''))
_charsets.add(Charset(159, 'ucs2', 'ucs2_general_mysql500_ci', ''))
_charsets.add(Charset(160, 'utf32', 'utf32_unicode_ci', ''))
_charsets.add(Charset(161, 'utf32', 'utf32_icelandic_ci', ''))
_charsets.add(Charset(162, 'utf32', 'utf32_latvian_ci', ''))
_charsets.add(Charset(163, 'utf32', 'utf32_romanian_ci', ''))
_charsets.add(Charset(164, 'utf32', 'utf32_slovenian_ci', ''))
_charsets.add(Charset(165, 'utf32', 'utf32_polish_ci', ''))
_charsets.add(Charset(166, 'utf32', 'utf32_estonian_ci', ''))
_charsets.add(Charset(167, 'utf32', 'utf32_spanish_ci', ''))
_charsets.add(Charset(168, 'utf32', 'utf32_swedish_ci', ''))
_charsets.add(Charset(169, 'utf32', 'utf32_turkish_ci', ''))
_charsets.add(Charset(170, 'utf32', 'utf32_czech_ci', ''))
_charsets.add(Charset(171, 'utf32', 'utf32_danish_ci', ''))
_charsets.add(Charset(172, 'utf32', 'utf32_lithuanian_ci', ''))
_charsets.add(Charset(173, 'utf32', 'utf32_slovak_ci', ''))
_charsets.add(Charset(174, 'utf32', 'utf32_spanish2_ci', ''))
_charsets.add(Charset(175, 'utf32', 'utf32_roman_ci', ''))
_charsets.add(Charset(176, 'utf32', 'utf32_persian_ci', ''))
_charsets.add(Charset(177, 'utf32', 'utf32_esperanto_ci', ''))
_charsets.add(Charset(178, 'utf32', 'utf32_hungarian_ci', ''))
_charsets.add(Charset(179, 'utf32', 'utf32_sinhala_ci', ''))
_charsets.add(Charset(180, 'utf32', 'utf32_german2_ci', ''))
_charsets.add(Charset(181, 'utf32', 'utf32_croatian_ci', ''))
_charsets.add(Charset(182, 'utf32', 'utf32_unicode_520_ci', ''))
_charsets.add(Charset(183, 'utf32', 'utf32_vietnamese_ci', ''))
_charsets.add(Charset(192, 'utf8', 'utf8_unicode_ci', '')) _charsets.add(Charset(192, 'utf8', 'utf8_unicode_ci', ''))
_charsets.add(Charset(193, 'utf8', 'utf8_icelandic_ci', '')) _charsets.add(Charset(193, 'utf8', 'utf8_icelandic_ci', ''))
_charsets.add(Charset(194, 'utf8', 'utf8_latvian_ci', '')) _charsets.add(Charset(194, 'utf8', 'utf8_latvian_ci', ''))
@@ -165,6 +227,36 @@ _charsets.add(Charset(207, 'utf8', 'utf8_roman_ci', ''))
_charsets.add(Charset(208, 'utf8', 'utf8_persian_ci', '')) _charsets.add(Charset(208, 'utf8', 'utf8_persian_ci', ''))
_charsets.add(Charset(209, 'utf8', 'utf8_esperanto_ci', '')) _charsets.add(Charset(209, 'utf8', 'utf8_esperanto_ci', ''))
_charsets.add(Charset(210, 'utf8', 'utf8_hungarian_ci', '')) _charsets.add(Charset(210, 'utf8', 'utf8_hungarian_ci', ''))
_charsets.add(Charset(211, 'utf8', 'utf8_sinhala_ci', ''))
_charsets.add(Charset(212, 'utf8', 'utf8_german2_ci', ''))
_charsets.add(Charset(213, 'utf8', 'utf8_croatian_ci', ''))
_charsets.add(Charset(214, 'utf8', 'utf8_unicode_520_ci', ''))
_charsets.add(Charset(215, 'utf8', 'utf8_vietnamese_ci', ''))
_charsets.add(Charset(223, 'utf8', 'utf8_general_mysql500_ci', ''))
_charsets.add(Charset(224, 'utf8mb4', 'utf8mb4_unicode_ci', ''))
_charsets.add(Charset(225, 'utf8mb4', 'utf8mb4_icelandic_ci', ''))
_charsets.add(Charset(226, 'utf8mb4', 'utf8mb4_latvian_ci', ''))
_charsets.add(Charset(227, 'utf8mb4', 'utf8mb4_romanian_ci', ''))
_charsets.add(Charset(228, 'utf8mb4', 'utf8mb4_slovenian_ci', ''))
_charsets.add(Charset(229, 'utf8mb4', 'utf8mb4_polish_ci', ''))
_charsets.add(Charset(230, 'utf8mb4', 'utf8mb4_estonian_ci', ''))
_charsets.add(Charset(231, 'utf8mb4', 'utf8mb4_spanish_ci', ''))
_charsets.add(Charset(232, 'utf8mb4', 'utf8mb4_swedish_ci', ''))
_charsets.add(Charset(233, 'utf8mb4', 'utf8mb4_turkish_ci', ''))
_charsets.add(Charset(234, 'utf8mb4', 'utf8mb4_czech_ci', ''))
_charsets.add(Charset(235, 'utf8mb4', 'utf8mb4_danish_ci', ''))
_charsets.add(Charset(236, 'utf8mb4', 'utf8mb4_lithuanian_ci', ''))
_charsets.add(Charset(237, 'utf8mb4', 'utf8mb4_slovak_ci', ''))
_charsets.add(Charset(238, 'utf8mb4', 'utf8mb4_spanish2_ci', ''))
_charsets.add(Charset(239, 'utf8mb4', 'utf8mb4_roman_ci', ''))
_charsets.add(Charset(240, 'utf8mb4', 'utf8mb4_persian_ci', ''))
_charsets.add(Charset(241, 'utf8mb4', 'utf8mb4_esperanto_ci', ''))
_charsets.add(Charset(242, 'utf8mb4', 'utf8mb4_hungarian_ci', ''))
_charsets.add(Charset(243, 'utf8mb4', 'utf8mb4_sinhala_ci', ''))
_charsets.add(Charset(244, 'utf8mb4', 'utf8mb4_german2_ci', ''))
_charsets.add(Charset(245, 'utf8mb4', 'utf8mb4_croatian_ci', ''))
_charsets.add(Charset(246, 'utf8mb4', 'utf8mb4_unicode_520_ci', ''))
_charsets.add(Charset(247, 'utf8mb4', 'utf8mb4_vietnamese_ci', ''))
def charset_by_name(name): def charset_by_name(name):
return _charsets.by_name(name) return _charsets.by_name(name)
+10 -12
View File
@@ -1857,7 +1857,7 @@ class BaseAdapter(ConnectionPool):
if isinstance(obj, datetime.datetime): if isinstance(obj, datetime.datetime):
obj = obj.isoformat(self.T_SEP)[:19] obj = obj.isoformat(self.T_SEP)[:19]
elif isinstance(obj, datetime.date): elif isinstance(obj, datetime.date):
obj = obj.isoformat()[:10]+' 00:00:00' obj = obj.isoformat()[:10]+self.T_SEP+'00:00:00'
else: else:
obj = str(obj) obj = str(obj)
elif fieldtype == 'time': elif fieldtype == 'time':
@@ -6872,7 +6872,7 @@ class Row(object):
_extra = self.__dict__.get('_extra', None) _extra = self.__dict__.get('_extra', None)
if _extra is not None: if _extra is not None:
v = _extra.get(key, None) v = _extra.get(key, None)
if v: if v is not None:
return v return v
m = REGEX_TABLE_DOT_FIELD.match(key) m = REGEX_TABLE_DOT_FIELD.match(key)
if m: if m:
@@ -8307,8 +8307,9 @@ class Table(object):
field_type = self if same_db else 'bigint' field_type = self if same_db else 'bigint'
clones = [] clones = []
for field in self: for field in self:
nfk = same_db or not field.type.startswith('reference')
clones.append(field.clone( clones.append(field.clone(
unique=False, type=field.type if same_db else 'bigint')) unique=False, type=field.type if nfk else 'bigint'))
archive_db.define_table( archive_db.define_table(
archive_name, Field(current_record,field_type), *clones) archive_name, Field(current_record,field_type), *clones)
self._before_update.append( self._before_update.append(
@@ -8386,10 +8387,7 @@ class Table(object):
elif isinstance(key, dict): elif isinstance(key, dict):
""" for keyed table """ """ for keyed table """
query = self._build_query(key) query = self._build_query(key)
rows = self._db(query).select() return self._db(query).select(limitby=(0,1), orderby_on_limitby=False).first()
if rows:
return rows[0]
return None
elif str(key).isdigit() or 'google' in DRIVERS and isinstance(key, Key): elif str(key).isdigit() or 'google' in DRIVERS and isinstance(key, Key):
return self._db(self._id == key).select(limitby=(0,1), orderby_on_limitby=False).first() return self._db(self._id == key).select(limitby=(0,1), orderby_on_limitby=False).first()
elif key: elif key:
@@ -10308,7 +10306,7 @@ class Rows(object):
if i is None: if i is None:
return (self.repr(i, fields=fields) for i in range(len(self))) return (self.repr(i, fields=fields) for i in range(len(self)))
import sqlhtml import sqlhtml
row = copy.copy(self.records[i]) row = copy.deepcopy(self.records[i])
keys = row.keys() keys = row.keys()
tables = [f.tablename for f in fields] if fields \ tables = [f.tablename for f in fields] if fields \
else [k for k in keys if k != '_extra'] else [k for k in keys if k != '_extra']
@@ -10328,12 +10326,12 @@ class Rows(object):
def as_list(self, def as_list(self,
compact=True, compact=True,
storage_to_dict=True, storage_to_dict=True,
datetime_to_str=True, datetime_to_str=False,
custom_types=None): custom_types=None):
""" """
returns the data as a list or dictionary. returns the data as a list or dictionary.
:param storage_to_dict: when True returns a dict, otherwise a list(default True) :param storage_to_dict: when True returns a dict, otherwise a list(default True)
:param datetime_to_str: convert datetime fields as strings (default True) :param datetime_to_str: convert datetime fields as strings (default False)
""" """
(oc, self.compact) = (self.compact, compact) (oc, self.compact) = (self.compact, compact)
if storage_to_dict: if storage_to_dict:
@@ -10348,7 +10346,7 @@ class Rows(object):
key='id', key='id',
compact=True, compact=True,
storage_to_dict=True, storage_to_dict=True,
datetime_to_str=True, datetime_to_str=False,
custom_types=None): custom_types=None):
""" """
returns the data as a dictionary of dictionaries (storage_to_dict=True) or records (False) returns the data as a dictionary of dictionaries (storage_to_dict=True) or records (False)
@@ -10356,7 +10354,7 @@ class Rows(object):
:param key: the name of the field to be used as dict key, normally the id :param key: the name of the field to be used as dict key, normally the id
:param compact: ? (default True) :param compact: ? (default True)
:param storage_to_dict: when True returns a dict, otherwise a list(default True) :param storage_to_dict: when True returns a dict, otherwise a list(default True)
:param datetime_to_str: convert datetime fields as strings (default True) :param datetime_to_str: convert datetime fields as strings (default False)
""" """
# test for multiple rows # test for multiple rows
+4 -3
View File
@@ -506,7 +506,7 @@ class Session(Storage):
#check if session is separate #check if session is separate
separate = None separate = None
if response.session_id[2:3] == "/": if response.session and response.session_id[2:3] == "/":
separate = lambda session_name: session_name[-2:] separate = lambda session_name: session_name[-2:]
self._unlock(response) self._unlock(response)
@@ -589,8 +589,9 @@ class Session(Storage):
response.session_db_unique_key = unique_key response.session_db_unique_key = unique_key
rcookies = response.cookies rcookies = response.cookies
rcookies[response.session_id_name] = response.session_id if response.session_id_name:
rcookies[response.session_id_name]['path'] = '/' rcookies[response.session_id_name] = response.session_id
rcookies[response.session_id_name]['path'] = '/'
if clear_session: if clear_session:
self.clear() self.clear()
+1 -1
View File
@@ -333,7 +333,7 @@ def highlight(
== '_' and value]) == '_' and value])
if fa: if fa:
fa = ' ' + fa fa = ' ' + fa
return '<table%s><tr valign="top"><td style="width:40px; text-align: right;"><pre style="%s">%s</pre></td><td><pre style="%s">%s</pre></td></tr></table>'\ return '<table%s><tr style="vertical-align:top;"><td style="width:40px; text-align: right;"><pre style="%s">%s</pre></td><td><pre style="%s">%s</pre></td></tr></table>'\
% (fa, linenumbers_style, numbers, code_style, code) % (fa, linenumbers_style, numbers, code_style, code)
+26 -7
View File
@@ -1198,12 +1198,12 @@ def TAG_pickler(data):
return (TAG_unpickler, (marshal_dump,)) return (TAG_unpickler, (marshal_dump,))
class __tag__(DIV): class __tag_div__(DIV):
def __init__(self,name,*a,**b): def __init__(self,name,*a,**b):
DIV.__init__(self,*a,**b) DIV.__init__(self,*a,**b)
self.tag = name self.tag = name
copy_reg.pickle(__tag__, TAG_pickler, TAG_unpickler) copy_reg.pickle(__tag_div__, TAG_pickler, TAG_unpickler)
class __TAG__(XmlComponent): class __TAG__(XmlComponent):
@@ -1223,7 +1223,7 @@ class __TAG__(XmlComponent):
name = name[:-1] + '/' name = name[:-1] + '/'
if isinstance(name, unicode): if isinstance(name, unicode):
name = name.encode('utf-8') name = name.encode('utf-8')
return lambda *a,**b: __tag__(name,*a,**b) return lambda *a,**b: __tag_div__(name,*a,**b)
def __call__(self, html): def __call__(self, html):
return web2pyHTMLParser(decoder.decoder(html)).tree return web2pyHTMLParser(decoder.decoder(html)).tree
@@ -1481,9 +1481,13 @@ class A(DIV):
self.append(self['_href']) self.append(self['_href'])
if not self['_disable_with']: if not self['_disable_with']:
self['_data-w2p_disable_with'] = 'default' self['_data-w2p_disable_with'] = 'default'
if self['callback'] and not self['_id']:
self['_id'] = web2py_uuid()
if self['delete']: if self['delete']:
self['_data-w2p_remove'] = self['delete'] self['_data-w2p_remove'] = self['delete']
if self['target']: if self['target']:
if self['target'] == '<self>':
self['target'] = self['_id']
self['_data-w2p_target'] = self['target'] self['_data-w2p_target'] = self['target']
if self['component']: if self['component']:
self['_data-w2p_method'] = 'GET' self['_data-w2p_method'] = 'GET'
@@ -1636,12 +1640,27 @@ class TR(DIV):
self._wrap_components((TD, TH), TD) self._wrap_components((TD, TH), TD)
class __TRHEAD__(DIV):
"""
__TRHEAD__ Component, internal only
If subcomponents are not TD/TH-components they will be wrapped in a TH
see also :class:`DIV`
"""
tag = 'tr'
def _fixup(self):
self._wrap_components((TD, TH), TH)
class THEAD(DIV): class THEAD(DIV):
tag = 'thead' tag = 'thead'
def _fixup(self): def _fixup(self):
self._wrap_components(TR, TR) self._wrap_components((__TRHEAD__, TR), __TRHEAD__)
class TBODY(DIV): class TBODY(DIV):
@@ -2283,7 +2302,7 @@ class BEAUTIFY(DIV):
example:: example::
>>> BEAUTIFY(['a', 'b', {'hello': 'world'}]).xml() >>> BEAUTIFY(['a', 'b', {'hello': 'world'}]).xml()
'<div><table><tr><td><div>a</div></td></tr><tr><td><div>b</div></td></tr><tr><td><div><table><tr><td style="font-weight:bold;vertical-align:top">hello</td><td valign="top">:</td><td><div>world</div></td></tr></table></div></td></tr></table></div>' '<div><table><tr><td><div>a</div></td></tr><tr><td><div>b</div></td></tr><tr><td><div><table><tr><td style="font-weight:bold;vertical-align:top;">hello</td><td style="vertical-align:top;">:</td><td><div>world</div></td></tr></table></div></td></tr></table></div>'
turns any list, dictionary, etc into decent looking html. turns any list, dictionary, etc into decent looking html.
Two special attributes are Two special attributes are
@@ -2335,8 +2354,8 @@ class BEAUTIFY(DIV):
continue continue
rows.append( rows.append(
TR( TR(
TD(filtered_key, _style='font-weight:bold;vertical-align:top'), TD(filtered_key, _style='font-weight:bold;vertical-align:top;'),
TD(':', _valign='top'), TD(':', _style='vertical-align:top;'),
TD(BEAUTIFY(value, **attributes)))) TD(BEAUTIFY(value, **attributes))))
components.append(TABLE(*rows, **attributes)) components.append(TABLE(*rows, **attributes))
continue continue
+7 -1
View File
@@ -29,6 +29,7 @@ import tempfile
import random import random
import string import string
import urllib2 import urllib2
try: try:
import simplejson as sj #external installed library import simplejson as sj #external installed library
except: except:
@@ -71,8 +72,13 @@ import logging.config
# This needed to prevent exception on Python 2.5: # This needed to prevent exception on Python 2.5:
# NameError: name 'gluon' is not defined # NameError: name 'gluon' is not defined
# See http://bugs.python.org/issue1436 # See http://bugs.python.org/issue1436
# attention!, the import Tkinter in messageboxhandler, changes locale ...
import gluon.messageboxhandler import gluon.messageboxhandler
logging.gluon = gluon logging.gluon = gluon
# so we must restore it! Thanks ozancag
import locale
locale.setlocale(locale.LC_CTYPE, "C") # IMPORTANT, web2py requires locale "C"
exists = os.path.exists exists = os.path.exists
pjoin = os.path.join pjoin = os.path.join
@@ -166,7 +172,7 @@ def copystream_progress(request, chunk_size=10 ** 5):
size = int(env.content_length) size = int(env.content_length)
except ValueError: except ValueError:
raise HTTP(400, "Invalid Content-Length header") raise HTTP(400, "Invalid Content-Length header")
dest = tempfile.TemporaryFile() dest = tempfile.NamedTemporaryFile()
if not 'X-Progress-ID' in request.vars: if not 'X-Progress-ID' in request.vars:
copystream(source, dest, size, chunk_size) copystream(source, dest, size, chunk_size)
return dest return dest
+39 -12
View File
@@ -37,13 +37,15 @@ import datetime
import urllib import urllib
import re import re
import cStringIO import cStringIO
from gluon import current, redirect from globals import current
from http import redirect
import inspect import inspect
import settings
is_gae = settings.global_settings.web2py_runtime_gae
try:
import settings
is_gae = settings.global_settings.web2py_runtime_gae
except ImportError:
is_gae = False # this is an assumption (if settings missing)
table_field = re.compile('[\w_]+\.[\w_]+') table_field = re.compile('[\w_]+\.[\w_]+')
widget_class = re.compile('^\w*') widget_class = re.compile('^\w*')
@@ -773,7 +775,7 @@ def formstyle_bootstrap(form, fields):
_submit = False _submit = False
if isinstance(controls, INPUT): if isinstance(controls, INPUT):
controls.add_class('input-xlarge') controls.add_class('span4')
if controls['_type'] == 'submit': if controls['_type'] == 'submit':
# flag submit button # flag submit button
_submit = True _submit = True
@@ -783,13 +785,13 @@ def formstyle_bootstrap(form, fields):
# For password fields, which are wrapped in a CAT object. # For password fields, which are wrapped in a CAT object.
if isinstance(controls, CAT) and isinstance(controls[0], INPUT): if isinstance(controls, CAT) and isinstance(controls[0], INPUT):
controls[0].add_class('input-xlarge') controls[0].add_class('span4')
if isinstance(controls, SELECT): if isinstance(controls, SELECT):
controls.add_class('input-xlarge') controls.add_class('span4')
if isinstance(controls, TEXTAREA): if isinstance(controls, TEXTAREA):
controls.add_class('input-xlarge') controls.add_class('span4')
if isinstance(label, LABEL): if isinstance(label, LABEL):
label['_class'] = 'control-label' label['_class'] = 'control-label'
@@ -2413,13 +2415,38 @@ class SQLFORM(FORM):
htmltable, _class='web2py_htmltable', htmltable, _class='web2py_htmltable',
_style='width:100%;overflow-x:auto;-ms-overflow-x:scroll') _style='width:100%;overflow-x:auto;-ms-overflow-x:scroll')
if selectable: if selectable:
htmltable = FORM(htmltable, INPUT( if not callable(selectable):
_type="submit", _value=T(selectable_submit_button))) #now expect that selectable and related parameters are iterator (list, tuple, etc)
inputs = []
for i, submit_info in enumerate(selectable):
submit_text = submit_info[0]
submit_class = submit_info[2] if len(submit_info) > 2 else ''
input_ctrl = INPUT(_type="submit", _name='submit_%d' % i, _value=T(submit_text))
input_ctrl.add_class(submit_class)
inputs.append(input_ctrl)
else:
inputs = [INPUT(_type="submit", _value=T(selectable_submit_button))]
if formstyle == 'bootstrap':
# add space between buttons
#inputs = sum([[inp, ' '] for inp in inputs], [])[:-1]
htmltable = FORM(htmltable, DIV(_class='form-actions', *inputs))
else:
htmltable = FORM(htmltable, *inputs)
if htmltable.process(formname=formname).accepted: if htmltable.process(formname=formname).accepted:
htmltable.vars.records = htmltable.vars.records or [] htmltable.vars.records = htmltable.vars.records or []
htmltable.vars.records = htmltable.vars.records if type(htmltable.vars.records) == list else [htmltable.vars.records] htmltable.vars.records = htmltable.vars.records if type(htmltable.vars.records) == list else [htmltable.vars.records]
records = [int(r) for r in htmltable.vars.records] records = [int(r) for r in htmltable.vars.records]
selectable(records) if not callable(selectable):
for i, submit_info in enumerate(selectable):
submit_callback = submit_info[1]
if htmltable.vars.get('submit_%d' % i, False):
submit_callback(records)
break
else:
selectable(records)
redirect(referrer) redirect(referrer)
else: else:
htmltable = DIV(T('No records found')) htmltable = DIV(T('No records found'))
-1
View File
@@ -178,7 +178,6 @@ class Messages(Settings):
return str(self.T(value)) return str(self.T(value))
return value return value
class FastStorage(dict): class FastStorage(dict):
""" """
Eventually this should replace class Storage but causes memory leak Eventually this should replace class Storage but causes memory leak
+2 -2
View File
@@ -800,8 +800,8 @@ class DummyResponse():
def write(self, data, escape=True): def write(self, data, escape=True):
if not escape: if not escape:
self.body.write(str(data)) self.body.write(str(data))
elif hasattr(data, 'as_html') and callable(data.as_html): elif hasattr(data, 'xml') and callable(data.xml):
self.body.write(data.as_html()) self.body.write(data.xml())
else: else:
# make it a string # make it a string
if not isinstance(data, (str, unicode)): if not isinstance(data, (str, unicode)):
+4
View File
@@ -188,6 +188,10 @@ class TestBareHelpers(unittest.TestCase):
def testTHEAD(self): def testTHEAD(self):
self.assertEqual(THEAD('<>', _a='1', _b='2').xml(), self.assertEqual(THEAD('<>', _a='1', _b='2').xml(),
'<thead a="1" b="2"><tr><th>&lt;&gt;</th></tr></thead>')
#self.assertEqual(THEAD(TRHEAD('<>'), _a='1', _b='2').xml(),
# '<thead a="1" b="2"><tr><th>&lt;&gt;</th></tr></thead>')
self.assertEqual(THEAD(TR('<>'), _a='1', _b='2').xml(),
'<thead a="1" b="2"><tr><td>&lt;&gt;</td></tr></thead>') '<thead a="1" b="2"><tr><td>&lt;&gt;</td></tr></thead>')
def testTITLE(self): def testTITLE(self):
+25 -22
View File
@@ -1116,7 +1116,7 @@ class Auth(object):
f=f, args=args, vars=vars, scheme=scheme) f=f, args=args, vars=vars, scheme=scheme)
def here(self): def here(self):
return URL(args=current.request.args, vars=current.request.vars) return current.request.env.request_uri
def __init__(self, environment=None, db=None, mailer=True, def __init__(self, environment=None, db=None, mailer=True,
hmac_key=None, controller='default', function='user', hmac_key=None, controller='default', function='user',
@@ -1747,6 +1747,9 @@ class Auth(object):
else: else:
user_id = None # user unknown user_id = None # user unknown
vars = vars or {} vars = vars or {}
# log messages should not be translated
if type(descrption).__name__ == 'lazyT':
description = description.m
self.table_event().insert( self.table_event().insert(
description=str(description % vars), description=str(description % vars),
origin=origin, user_id=user_id) origin=origin, user_id=user_id)
@@ -2044,7 +2047,7 @@ class Auth(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.login_onaccept onaccept = self.settings.login_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.login_log log = self.messages['login_log']
onfail = self.settings.login_onfail onfail = self.settings.login_onfail
@@ -2158,7 +2161,7 @@ class Auth(object):
form.vars, self.settings.update_fields) form.vars, self.settings.update_fields)
break break
if not user: if not user:
self.log_event(self.messages.login_failed_log, self.log_event(self.messages['login_failed_log'],
request.post_vars) request.post_vars)
# invalid login # invalid login
session.flash = self.messages.invalid_login session.flash = self.messages.invalid_login
@@ -2233,7 +2236,7 @@ class Auth(object):
if onlogout: if onlogout:
onlogout(self.user) onlogout(self.user)
if log is DEFAULT: if log is DEFAULT:
log = self.messages.logout_log log = self.messages['logout_log']
if self.user: if self.user:
self.log_event(log, self.user) self.log_event(log, self.user)
if self.settings.login_form != self: if self.settings.login_form != self:
@@ -2278,7 +2281,7 @@ class Auth(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.register_onaccept onaccept = self.settings.register_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.register_log log = self.messages['register_log']
table_user = self.table_user() table_user = self.table_user()
if self.settings.login_userfield: if self.settings.login_userfield:
@@ -2327,7 +2330,7 @@ class Auth(object):
if formstyle == 'bootstrap': if formstyle == 'bootstrap':
form.custom.widget.password_two[ form.custom.widget.password_two[
'_class'] = 'input-xlarge' '_class'] = 'span4'
addrow( addrow(
form, self.messages.verify_password + form, self.messages.verify_password +
@@ -2430,7 +2433,7 @@ class Auth(object):
if current.session.auth and current.session.auth.user: if current.session.auth and current.session.auth.user:
current.session.auth.user.registration_key = user.registration_key current.session.auth.user.registration_key = user.registration_key
if log is DEFAULT: if log is DEFAULT:
log = self.messages.verify_email_log log = self.messages['verify_email_log']
if next is DEFAULT: if next is DEFAULT:
next = self.settings.verify_email_next next = self.settings.verify_email_next
if onaccept is DEFAULT: if onaccept is DEFAULT:
@@ -2473,7 +2476,7 @@ class Auth(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.retrieve_username_onaccept onaccept = self.settings.retrieve_username_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.retrieve_username_log log = self.messages['retrieve_username_log']
old_requires = table_user.email.requires old_requires = table_user.email.requires
table_user.email.requires = [IS_IN_DB(self.db, table_user.email, table_user.email.requires = [IS_IN_DB(self.db, table_user.email,
error_message=self.messages.invalid_email)] error_message=self.messages.invalid_email)]
@@ -2555,7 +2558,7 @@ class Auth(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.retrieve_password_onaccept onaccept = self.settings.retrieve_password_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.retrieve_password_log log = self.messages['retrieve_password_log']
old_requires = table_user.email.requires old_requires = table_user.email.requires
table_user.email.requires = [IS_IN_DB(self.db, table_user.email, table_user.email.requires = [IS_IN_DB(self.db, table_user.email,
error_message=self.messages.invalid_email)] error_message=self.messages.invalid_email)]
@@ -2695,7 +2698,7 @@ class Auth(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.reset_password_onaccept onaccept = self.settings.reset_password_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.reset_password_log log = self.messages['reset_password_log']
table_user.email.requires = [ table_user.email.requires = [
IS_EMAIL(error_message=self.messages.invalid_email), IS_EMAIL(error_message=self.messages.invalid_email),
IS_IN_DB(self.db, table_user.email, IS_IN_DB(self.db, table_user.email,
@@ -2795,7 +2798,7 @@ class Auth(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.change_password_onaccept onaccept = self.settings.change_password_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.change_password_log log = self.messages['change_password_log']
passfield = self.settings.password_field passfield = self.settings.password_field
form = SQLFORM.factory( form = SQLFORM.factory(
Field('old_password', 'password', Field('old_password', 'password',
@@ -2864,7 +2867,7 @@ class Auth(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.profile_onaccept onaccept = self.settings.profile_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.profile_log log = self.messages['profile_log']
form = SQLFORM( form = SQLFORM(
table_user, table_user,
self.user.id, self.user.id,
@@ -2930,7 +2933,7 @@ class Auth(object):
self.user = auth.user self.user = auth.user
self.update_groups() self.update_groups()
onaccept = self.settings.login_onaccept onaccept = self.settings.login_onaccept
log = self.messages.impersonate_log log = self.messages['impersonate_log']
self.log_event(log, dict(id=current_id, other_id=auth.user.id)) self.log_event(log, dict(id=current_id, other_id=auth.user.id))
if onaccept: if onaccept:
form = Storage(dict(vars=self.user)) form = Storage(dict(vars=self.user))
@@ -3086,7 +3089,7 @@ class Auth(object):
group_id = self.table_group().insert( group_id = self.table_group().insert(
role=role, description=description) role=role, description=description)
self.log_event(self.messages.add_group_log, self.log_event(self.messages['add_group_log'],
dict(group_id=group_id, role=role)) dict(group_id=group_id, role=role))
return group_id return group_id
@@ -3143,7 +3146,7 @@ class Auth(object):
r = True r = True
else: else:
r = False r = False
self.log_event(self.messages.has_membership_log, self.log_event(self.messages['has_membership_log'],
dict(user_id=user_id, group_id=group_id, check=r)) dict(user_id=user_id, group_id=group_id, check=r))
return r return r
@@ -3167,7 +3170,7 @@ class Auth(object):
else: else:
id = membership.insert(group_id=group_id, user_id=user_id) id = membership.insert(group_id=group_id, user_id=user_id)
self.update_groups() self.update_groups()
self.log_event(self.messages.add_membership_log, self.log_event(self.messages['add_membership_log'],
dict(user_id=user_id, group_id=group_id)) dict(user_id=user_id, group_id=group_id))
return id return id
@@ -3181,7 +3184,7 @@ class Auth(object):
if not user_id and self.user: if not user_id and self.user:
user_id = self.user.id user_id = self.user.id
membership = self.table_membership() membership = self.table_membership()
self.log_event(self.messages.del_membership_log, self.log_event(self.messages['del_membership_log'],
dict(user_id=user_id, group_id=group_id)) dict(user_id=user_id, group_id=group_id))
ret = self.db(membership.user_id ret = self.db(membership.user_id
== user_id)(membership.group_id == user_id)(membership.group_id
@@ -3237,7 +3240,7 @@ class Auth(object):
else: else:
r = False r = False
if user_id: if user_id:
self.log_event(self.messages.has_permission_log, self.log_event(self.messages['has_permission_log'],
dict(user_id=user_id, name=name, dict(user_id=user_id, name=name,
table_name=table_name, record_id=record_id)) table_name=table_name, record_id=record_id))
return r return r
@@ -3264,7 +3267,7 @@ class Auth(object):
id = permission.insert(group_id=group_id, name=name, id = permission.insert(group_id=group_id, name=name,
table_name=str(table_name), table_name=str(table_name),
record_id=long(record_id)) record_id=long(record_id))
self.log_event(self.messages.add_permission_log, self.log_event(self.messages['add_permission_log'],
dict(permission_id=id, group_id=group_id, dict(permission_id=id, group_id=group_id,
name=name, table_name=table_name, name=name, table_name=table_name,
record_id=record_id)) record_id=record_id))
@@ -3282,7 +3285,7 @@ class Auth(object):
""" """
permission = self.table_permission() permission = self.table_permission()
self.log_event(self.messages.del_permission_log, self.log_event(self.messages['del_permission_log'],
dict(group_id=group_id, name=name, dict(group_id=group_id, name=name,
table_name=table_name, record_id=record_id)) table_name=table_name, record_id=record_id))
return self.db(permission.group_id == group_id)(permission.name return self.db(permission.group_id == group_id)(permission.name
@@ -3633,7 +3636,7 @@ class Crud(object):
if ondelete is DEFAULT: if ondelete is DEFAULT:
ondelete = self.settings.update_ondelete ondelete = self.settings.update_ondelete
if log is DEFAULT: if log is DEFAULT:
log = self.messages.update_log log = self.messages['update_log']
if deletable is DEFAULT: if deletable is DEFAULT:
deletable = self.settings.update_deletable deletable = self.settings.update_deletable
if message is DEFAULT: if message is DEFAULT:
@@ -3724,7 +3727,7 @@ class Crud(object):
if onaccept is DEFAULT: if onaccept is DEFAULT:
onaccept = self.settings.create_onaccept onaccept = self.settings.create_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.create_log log = self.messages['create_log']
if message is DEFAULT: if message is DEFAULT:
message = self.messages.record_created message = self.messages.record_created
return self.update( return self.update(
+2 -2
View File
@@ -2665,8 +2665,8 @@ class IS_EMPTY_OR(Validator):
if hasattr(other, 'options'): if hasattr(other, 'options'):
self.options = self._options self.options = self._options
def _options(self, zero=False): def _options(self):
options = self.other.options(zero=zero) options = self.other.options()
if (not options or options[0][0] != '') and not self.multiple: if (not options or options[0][0] != '') and not self.multiple:
options.insert(0, ('', '')) options.insert(0, ('', ''))
return options return options
+10 -11
View File
@@ -29,15 +29,6 @@ from settings import global_settings
from shell import run, test from shell import run, test
from utils import is_valid_ip_address, is_loopback_ip_address, getipaddrinfo from utils import is_valid_ip_address, is_loopback_ip_address, getipaddrinfo
try:
import Tkinter
import tkMessageBox
import contrib.taskbar_widget
from winservice import register_service_handler, Web2pyService
have_winservice = True
except:
have_winservice = False
ProgramName = 'web2py Web Framework' ProgramName = 'web2py Web Framework'
ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-' + str( ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-' + str(
@@ -138,6 +129,7 @@ def start_browser(url, startup=False):
def presentation(root): def presentation(root):
""" Draw the splash screen """ """ Draw the splash screen """
import Tkinter
root.withdraw() root.withdraw()
@@ -194,6 +186,9 @@ class web2pyDialog(object):
def __init__(self, root, options): def __init__(self, root, options):
""" web2pyDialog constructor """ """ web2pyDialog constructor """
import Tkinter
import tkMessageBox
root.title('web2py server') root.title('web2py server')
self.root = Tkinter.Toplevel(root) self.root = Tkinter.Toplevel(root)
self.options = options self.options = options
@@ -321,6 +316,7 @@ class web2pyDialog(object):
self.button_stop.configure(state='disabled') self.button_stop.configure(state='disabled')
if options.taskbar: if options.taskbar:
import contrib.taskbar_widget
self.tb = contrib.taskbar_widget.TaskBarIcon() self.tb = contrib.taskbar_widget.TaskBarIcon()
self.checkTaskBar() self.checkTaskBar()
@@ -460,6 +456,7 @@ class web2pyDialog(object):
def error(self, message): def error(self, message):
""" Show error message """ """ Show error message """
import tkMessageBox
tkMessageBox.showerror('web2py start server', message) tkMessageBox.showerror('web2py start server', message)
def start(self): def start(self):
@@ -1142,12 +1139,13 @@ def start(cron=True):
# ## if -W install/start/stop web2py as service # ## if -W install/start/stop web2py as service
if options.winservice: if options.winservice:
if os.name == 'nt': if os.name == 'nt':
if have_winservice: try:
from winservice import register_service_handler, Web2pyService
register_service_handler( register_service_handler(
argv=['', options.winservice], argv=['', options.winservice],
opt_file=options.config, opt_file=options.config,
cls=Web2pyService) cls=Web2pyService)
else: except ImportError:
print 'Error: Missing python module winservice' print 'Error: Missing python module winservice'
sys.exit(1) sys.exit(1)
else: else:
@@ -1188,6 +1186,7 @@ def start(cron=True):
logger.warn( logger.warn(
'GUI not available because Tk library is not installed') 'GUI not available because Tk library is not installed')
havetk = False havetk = False
options.nogui = True
if options.password == '<ask>' and havetk or options.taskbar and havetk: if options.password == '<ask>' and havetk or options.taskbar and havetk:
try: try:
+3 -3
View File
@@ -43,19 +43,19 @@ echo 'server {
listen 80; listen 80;
server_name $hostname; server_name $hostname;
###to enable correct use of response.static_version ###to enable correct use of response.static_version
#location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { #location ~* ^/(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ {
# alias /home/www-data/web2py/applications/$1/static/$2; # alias /home/www-data/web2py/applications/$1/static/$2;
# expires max; # expires max;
#} #}
### ###
###if you use something like myapp = dict(languages=['en', 'it', 'jp'], default_language='en') in your routes.py ###if you use something like myapp = dict(languages=['en', 'it', 'jp'], default_language='en') in your routes.py
#location ~* /(\w+)/(en|it|jp)/static/(.*)$ { #location ~* ^/(\w+)/(en|it|jp)/static/(.*)$ {
# alias /home/www-data/web2py/applications/$1/; # alias /home/www-data/web2py/applications/$1/;
# try_files static/$2/$3 static/$3 =404; # try_files static/$2/$3 static/$3 =404;
#} #}
### ###
location ~* /(\w+)/static/ { location ~* ^/(\w+)/static/ {
root /home/www-data/web2py/applications/; root /home/www-data/web2py/applications/;
#remove next comment on production #remove next comment on production
#expires max; #expires max;