diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index 500431eb..5e0e3ce5 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -586,6 +586,24 @@ def edit(): """ File edit handler """ # Load json only if it is ajax edited... app = get_app(request.vars.app) + + if not(request.ajax): + # return the scaffolding, the rest will be through ajax requests + response.title = T('Editing %s' % app) + editarea_preferences = {} + editarea_preferences['FONT_SIZE'] = '10' + editarea_preferences['FULL_SCREEN'] = 'false' + editarea_preferences['ALLOW_TOGGLE'] = 'true' + editarea_preferences['REPLACE_TAB_BY_SPACES'] = '4' + editarea_preferences['DISPLAY'] = 'onload' + for key in editarea_preferences: + if key in globals(): + editarea_preferences[key] = globals()[key] + return response.render ('default/edit.html', dict(app=request.args[0], editarea_preferences=editarea_preferences)) + + """ File edit handler """ + # Load json only if it is ajax edited... + app = get_app(request.vars.app) filename = '/'.join(request.args) response.title = request.args[-1] if request.vars.app: @@ -708,7 +726,7 @@ def edit(): cfilename = os.path.join(request.args[0], 'controllers', request.args[2] + '.py') if os.path.exists(apath(cfilename, r=request)): - edit_controller = URL('edit',args=[cfilename.replace(os.sep, "/")]) + edit_controller = URL('edit', args=[cfilename.replace(os.sep, "/")]) view = request.args[3].replace('.html', '') view_link = URL(request.args[0], request.args[2], view) elif filetype == 'python' and request.args[1] == 'controllers': @@ -730,6 +748,7 @@ def edit(): vf = os.path.split(v)[-1] vargs = "/".join([viewpath.replace(os.sep, "/"), vf]) editviewlinks.append(A(vf.split(".")[0], + _class="editor_filelink", _href=URL('edit', args=[vargs]))) if len(request.args) > 2 and request.args[1] == 'controllers': @@ -741,17 +760,7 @@ def edit(): if 'from_ajax' in request.vars: return response.json({'file_hash': file_hash, 'saved_on': saved_on, 'functions': functions, 'controller': controller, 'application': request.args[0], 'highlight': highlight}) else: - - editarea_preferences = {} - editarea_preferences['FONT_SIZE'] = '10' - editarea_preferences['FULL_SCREEN'] = 'false' - editarea_preferences['ALLOW_TOGGLE'] = 'true' - editarea_preferences['REPLACE_TAB_BY_SPACES'] = '4' - editarea_preferences['DISPLAY'] = 'onload' - for key in editarea_preferences: - if key in globals(): - editarea_preferences[key] = globals()[key] - return dict(app=request.args[0], + file_details = dict(app=request.args[0], filename=filename, filetype=filetype, data=data, @@ -761,9 +770,13 @@ def edit(): controller=controller, functions=functions, view_link=view_link, - editarea_preferences=editarea_preferences, - editviewlinks=editviewlinks) - + editviewlinks=editviewlinks, + id=IS_SLUG()(filename)[0], + force= True if (request.vars.restore or request.vars.revert) else False) + plain_html = response.render('default/edit_js.html', file_details) + file_details['plain_html'] = plain_html + return response.json(file_details) + def resolve(): """ diff --git a/applications/admin/static/js/ajax_editor.js b/applications/admin/static/js/ajax_editor.js index 168236d4..7b123268 100644 --- a/applications/admin/static/js/ajax_editor.js +++ b/applications/admin/static/js/ajax_editor.js @@ -11,12 +11,12 @@ function prepareMultiPartPOST(data) { var reqdata = '--' + boundary + '\r\n'; //console.log(data.length); for (var i=0;i < data.length;i++) { - reqdata += 'content-disposition: form-data; name="'; - reqdata += data[i].Name + '"'; - reqdata += "\r\n\r\n" ; - reqdata += data[i].Data; - reqdata += "\r\n" ; - reqdata += '--' + boundary + '\r\n'; + reqdata += 'content-disposition: form-data; name="'; + reqdata += data[i].Name + '"'; + reqdata += "\r\n\r\n" ; + reqdata += data[i].Data; + reqdata += "\r\n" ; + reqdata += '--' + boundary + '\r\n'; } return new Array(reqdata,boundary); } @@ -26,53 +26,29 @@ function on_error() { jQuery("input[name='saved_on']").val('communication error'); } -function getData() { - if (window.ace_editor) { - var data = window.ace_editor.getSession().getValue(); - } else if (window.mirror) { - var data = window.mirror.getValue(); - } else if (window.eamy) { - var data = window.eamy.instances[0].getText(); - } else if (window.textarea) { - var data = textarea.value; - } - return data; -} - -function doHighlight(highlight) { - if (window.ace_editor) { - window.ace_editor.gotoLine(highlight.lineno); - } else if (window.mirror) { - // Put the cursor at the offending line: - window.mirror.setCursor({line:highlight.lineno-1, - ch:highlight.offset+1}); - } else if (window.eamy) { - // not implemented - } else if (window.textarea) { - editAreaLoader.setSelectionRange('body', highlight.start, highlight.end); - } -} - function doClickSave() { - var data = getData(); + var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id'); + var editor = jQuery (currentTabID + ' textarea').data('editor'); + var data = editor.getValue(); var dataForPost = prepareMultiPartPOST(new Array( prepareDataForSave('data', data), prepareDataForSave('file_hash', - jQuery("input[name='file_hash']").val()), + jQuery(currentTabID + " input[name='file_hash']").val()), prepareDataForSave('saved_on', - jQuery("input[name='saved_on']").val()), + jQuery(currentTabID + " input[name='saved_on']").val()), prepareDataForSave('saved_on', - jQuery("input[name='saved_on']").val()), + jQuery(currentTabID + " input[name='saved_on']").val()), prepareDataForSave('from_ajax','true'))); // console.info(area.textarea.value); - jQuery("input[name='saved_on']").attr('style', + jQuery(currentTabID + " input[name='saved_on']").attr('style', 'background-color:yellow'); - jQuery("input[name='saved_on']").val('saving now...') + jQuery(currentTabID + " input[name='saved_on']").val('saving now...') + currentUrl = jQuery(currentTabID + ' form').attr('action'); jQuery.ajax({ type: "POST", contentType: 'multipart/form-data;boundary="' + dataForPost[1] + '"', - url: self.location.href, + url: currentUrl, dataType: "json", data: dataForPost[0], timeout: 5000, @@ -84,12 +60,7 @@ function doClickSave() { }, success: function(json,text,xhr){ - // show flash message (if any) - var flash=xhr.getResponseHeader('web2py-component-flash'); - if (flash) { - var flashhtml = decodeURIComponent(flash); - jQuery('.flash').html(flashhtml).slideDown(); - } else jQuery('.flash').hide(); + // reenable disabled submit button var t=jQuery("input[name='save']"); @@ -97,24 +68,25 @@ function doClickSave() { t.attr('disabled',''); try { if (json.error) { - window.location.href=json.redirect; + window.location.href=json.redirect; } else { // console.info( json.file_hash ); - jQuery("input[name='file_hash']").val(json.file_hash); - jQuery("input[name='saved_on']").val(json.saved_on); + jQuery(currentTabID + " input[name='file_hash']").val(json.file_hash); + jQuery(currentTabID + " input[name='saved_on']").val(json.saved_on); if (json.highlight) { - doHighlight(json.highlight); + // Put the cursor at the offending line: + editor.setCursor({line:highlight.lineno-1, ch:highlight.offset+1}); } else { - jQuery("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'); } // console.info(jQuery("input[name='file_hash']").val()); var output = 'exposes: '; for ( var i in json.functions) { - output += ' ' + json.functions[i] + ','; + output += ' ' + json.functions[i] + ','; } if(output!='exposes: ') { - jQuery("#exposed").html( output.substring(0, output.length-1)); + jQuery(currentTabID + " .exposed").html( output.substring(0, output.length-1)); } } } catch(e) { on_error();} @@ -124,32 +96,23 @@ function doClickSave() { return false; } +function getActiveEditor() { + var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id'); + var editor = jQuery (currentTabID + ' textarea').data('editor'); + return editor; +} + function getSelectionRange() { - var sel; - if (window.ace_editor) { - sel = {}; - range = window.ace_editor.getSelectionRange(); - // passing the line number directly, no need to read the text - sel['start'] = range.start.row; - sel['end'] = range.end.row; - sel['data'] = ''; - } else if (window.mirror) { - sel = {}; - sel['start'] = window.mirror.getCursor(true).line; - sel['end'] = window.mirror.getCursor(false).line; + var editor = getActiveEditor(); + var sel = {}; + sel['start'] = editor.getCursor(true).line; + sel['end'] = editor.getCursor(false).line; sel['data'] = ''; - } else if (window.eamy) { - sel = {}; - // not implemented - } else if (window.textarea) { - // passing offset, needs the text to calculate the line: - sel = editAreaLoader.getSelectionRange('body'); - sel['data'] = getData(); - } - return sel; + return sel; } function doToggleBreakpoint(filename, url, sel) { + var editor = getActiveEditor(); if (sel==null) { // use cursor position to determine the breakpoint line // (gutter already tell us the selected line) @@ -185,17 +148,14 @@ function doToggleBreakpoint(filename, url, sel) { if (json.error) { window.location.href=json.redirect; } else { - if (json.ok==true && window.mirror) { + if (json.ok==true) { // mark the breakpoint if ok=True editor.setMarker(json.lineno-1, "● %N%") - } else if (json.ok==false && window.mirror) { + } else if (json.ok==false) { // remove mark if ok=False editor.setMarker(json.lineno-1, "%N%") - } else { - // do nothing if ok = null - } - // alert(json.ok + json.lineno); + } } } catch(e) { on_error(); } }, @@ -205,7 +165,7 @@ function doToggleBreakpoint(filename, url, sel) { } // on load, update all breakpoints markers: -function doListBreakpoints(filename, url) { +function doListBreakpoints(filename, url, editor) { var dataForPost = prepareMultiPartPOST(new Array( prepareDataForSave('filename', filename) )); @@ -222,19 +182,17 @@ function doListBreakpoints(filename, url) { xhr.setRequestHeader('web2py-component-element', 'doListBreakpoints');}, success: function(json,text,xhr){ - try { - if (json.error) { - window.location.href=json.redirect; - } else { - if (window.mirror) { - for (i in json.breakpoints) { - lineno = json.breakpoints[i]; - // mark the breakpoint if ok=True - editor.setMarker(lineno-1, - "● %N%"); - } - } - } + try { + if (json.error) { + window.location.href=json.redirect; + } else { + var editor = getActiveEditor(); + for (i in json.breakpoints) { + lineno = json.breakpoints[i]; + // mark the breakpoint if ok=True + editor.setMarker(lineno-1, "● %N%"); + } + } } catch(e) { on_error(); } }, error: function(json) { on_error(); } @@ -250,3 +208,29 @@ function keepalive(url) { success: function(){}, error: function(x) { on_error(); } }); } + +function load_file (url) { + jQuery.ajax({ + type: "GET", + dataType: 'json', + url: url, + timeout: 1000, + success: function(json){ + if (typeof(json['plain_html']) !== undefined) { + if (jQuery('#' + json['id']).length === 0 || json['force'] === true) { + // Create a tab and put the code in it + var tab_header = '
-
- {{=B(T('exposes:'))}} {{=XML(', '.join([A(f,_href=URL(a=app,c=controller,f=f)).xml() for f in functions]))}}
-
- {{if editviewlinks:}}
- {{=B(T('edit views:'))}}
- {{=XML(', '.join([v.xml() for v in editviewlinks]))}}
- {{pass}}
-
- {{if filetype=='python':}} - {{=A(SPAN(T('toggle breakpoint')), - _value="breakpoint", _name="breakpoint", - _onclick="return doToggleBreakpoint('%s','%s://%s%s',null);" % (filename, - request.env['wsgi_url_scheme'], request.env['http_host'], - URL(c='debug', f='toggle_breakpoint')), - _class="button special btn btn-inverse")}} - {{pass}} +