Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

ENHANCEMENT Lazy-loading image and link dialogs for HtmlEditorField, …

…to avoid unnecessary processing overhead on initial CMS load (also means they'll never get loaded if not required, e.g. in ReportAdmin)
  • Loading branch information...
commit b025b95ede67d5178524c88e3909d44fa59b65d6 1 parent c73b800
@chillu chillu authored
View
7 admin/templates/LeftAndMain.ss
@@ -24,12 +24,7 @@
</div>
- <div id="cms-editor-dialogs" class="hide">
- <% control EditorToolbar %>
- $MediaForm
- $LinkForm
- <% end_control %>
- </div>
+ $EditorToolbar
<!-- <div class="ss-cms-bottom-bar">
<div class="holder">
View
9 forms/HtmlEditorField.php
@@ -267,6 +267,14 @@ function __construct($controller, $name) {
$this->name = $name;
}
+ public function forTemplate() {
+ return sprintf(
+ '<div id="cms-editor-dialogs" data-url-linkform="%s" data-url-mediaform="%s"></div>',
+ Controller::join_links($this->controller->Link($this->name), 'LinkForm', 'forTemplate'),
+ Controller::join_links($this->controller->Link($this->name), 'MediaForm', 'forTemplate')
+ );
+ }
+
/**
* Searches the SiteTree for display in the dropdown
*
@@ -627,6 +635,7 @@ protected function getAllowedExtensions() {
$this->extend('updateAllowedExtensions', $exts);
return $exts;
}
+
}
/**
View
130 javascript/HtmlEditorField.js
@@ -251,12 +251,10 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
this._super();
},
-
isChanged: function() {
var ed = this.getEditor();
return (ed && ed.getInstance() && ed.isDirty());
},
-
resetChanged: function() {
var ed = this.getEditor();
if(typeof tinyMCE == 'undefined') return;
@@ -265,7 +263,35 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
var inst = tinyMCE.getInstanceById(this.attr('id'));
if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1}));
},
+ openLinkDialog: function() {
+ this.openDialog('link');
+ },
+ openMediaDialog: function() {
+ this.openDialog('media');
+ },
+ openDialog: function(type) {
+ var capitalize = function(text) {
+ return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
+ };
+
+ var url = $('#cms-editor-dialogs').data('url' + capitalize(type) + 'form'),
+ dialog = $('.htmleditorfield-' + type + 'dialog');
+ if(dialog.length) {
+ dialog.open();
+ } else {
+ // Show a placeholder for instant feedback. Will be replaced with actual
+ // form dialog once its loaded.
+ dialog = $('<div class="htmleditorfield-dialog htmleditorfield-' + type + 'dialog loading">');
+ $('body').append(dialog);
+ $.ajax({
+ url: url,
+ success: function(html) {
+ dialog.html(html);
+ }
+ });
+ }
+ },
onunmatch: function() {
// TODO Throws exceptions in Firefox, most likely due to the element being removed from the DOM at this point
// var ed = tinyMCE.get(this.attr('id'));
@@ -275,6 +301,35 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
}
});
+ $('.htmleditorfield-dialog').entwine({
+ onmatch: function() {
+ // Create jQuery dialog
+ this.dialog({autoOpen: true, bgiframe: true, modal: true, height: 500, width: '80%', ghost: true});
+
+ this._super();
+ },
+ getForm: function() {
+ return this.find('form');
+ },
+ open: function() {
+ this.dialog('open');
+ },
+ close: function() {
+ this.dialog('close');
+ },
+ toggle: function(bool) {
+ if(this.is(':visible')) this.close();
+ else this.open();
+ },
+ ondialogopen: function(e) {
+ this.getForm().updateFromEditor();
+ this.redraw();
+ },
+ ondialogclose: function(e) {
+ this.getForm().resetFields();
+ }
+ });
+
/**
* Base form implementation for interactions with an editor instance,
* mostly geared towards modification and insertion of content.
@@ -286,40 +341,30 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
// TODO Figure out how to keep bookmark reference in entwine, and still be allowed to delete the JS object
// Bookmark: null,
-
onmatch: function() {
// Move title from headline to (jQuery compatible) title attribute
var titleEl = this.find(':header:first');
- this.attr('title', titleEl.text());
+ this.getDialog().attr('title', titleEl.text());
titleEl.remove();
- // Create jQuery dialog
- this.dialog({autoOpen: false, bgiframe: true, modal: true, height: 500, width: '80%', ghost: true});
-
this.setEditor(ss.editorWrappers['default']());
},
redraw: function() {
},
- toggle: function() {
- if(this.is(':visible')) this.close();
- else this.open();
- },
- close: function() {
- this.dialog('close');
- this.getEditor().onclose();
+ resetFields: function() {
if(typeof window._ss_htmleditorfield_bookmark != 'undefined') window._ss_htmleditorfield_bookmark = null;
+ this.getEditor().onclose();
},
- open: function() {
- this.updateFromEditor();
- this.dialog('open');
- this.redraw();
- this.getEditor().onopen();
- window._ss_htmleditorfield_bookmark = this.getEditor().createBookmark();
+ getDialog: function() {
+ // TODO Refactor to listen to form events to remove two-way coupling
+ return this.closest('.htmleditorfield-dialog');
},
/**
* Update the view state based on the current editor selection.
*/
updateFromEditor: function() {
+ this.getEditor().onopen();
+ window._ss_htmleditorfield_bookmark = this.getEditor().createBookmark();
}
});
@@ -331,23 +376,16 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
*/
$('form.htmleditorfield-linkform').entwine({
- close: function() {
- this._super();
-
- this.resetFields();
- },
-
// TODO Entwine doesn't respect submits triggered by ENTER key
onsubmit: function(e) {
this.insertLink();
- this.close();
+ this.getDialog().close();
return false;
},
-
resetFields: function() {
+ this._super();
this.find('fieldset :input:not(:radio)').val('').change();
},
-
redraw: function(setDefaults) {
this._super();
@@ -377,7 +415,6 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
this.find(':input[name=TargetBlank]').attr('checked', (linkType == 'file'));
}
},
-
insertLink: function() {
var href, target = null, anchor = this.find(':input[name=Anchor]').val(), ed = this.getEditor();
@@ -428,12 +465,10 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
this.trigger('onafterinsert', attributes);
this.updateFromEditor();
},
-
removeLink: function() {
this.getEditor().removeLink();
this.close();
},
-
addAnchorSelector: function() {
// Avoid adding twice
if(this.find(':input[name=AnchorSelector]').length) return;
@@ -466,7 +501,6 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
self.find(':input[name="Anchor"]').val($(this).val());
});
},
-
// this function collects the anchors in the currently active editor and regenerates the dropdown
refreshAnchors: function() {
var selector = this.find(':input[name=AnchorSelector]'), anchors = [];
@@ -485,7 +519,6 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
selector.append($('<option value="'+anchors[j]+'">'+anchors[j]+'</option>'));
}
},
-
updateFromEditor: function() {
var htmlTagPattern = /<\S[^><]*>/g, fieldName, data = this.getCurrentLink();
@@ -502,7 +535,6 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
}
}
},
-
/**
* Return information about the currently selected link, suitable for population of the link
* form.
@@ -623,13 +655,11 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
$(this).insertHTML();
});
ed.repaint();
- this.close();
+ this.getDialog().close();
return false;
},
- ondialogopen: function() {
- this.redraw();
-
+ updateFromEditor: function() {
var self = this, ed = this.getEditor(), node = $(ed.getSelectedNode());
// TODO Depends on managed mime type
if(node.is('img')) {
@@ -645,16 +675,6 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
// don't respect the z-index of the dialog overlay.
// jQuery(ed.getContainer()).hide();
},
- ondialogclose: function() {
- var ed = this.getEditor(), node = $(ed.getSelectedNode());
-
- // HACK: See ondialogopen()
- // jQuery(ed.getContainer()).show();
-
- this.find('.ss-htmleditorfield-file').remove(); // Remove any existing views
- this.find('.ss-gridfield-items .ui-selected').removeClass('ui-selected'); // Unselect all items
- this.redraw();
- },
redraw: function() {
this._super();
@@ -673,6 +693,18 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
// Hide file selection and step labels when editing an existing file
this.find('#MediaFormInsertImageTabs,.header-edit')[editingSelected ? 'hide' : 'show']();
},
+ resetFields: function() {
+ var ed = this.getEditor(), node = $(ed.getSelectedNode());
+
+ // HACK: See ondialogopen()
+ // jQuery(ed.getContainer()).show();
+
+ this.find('.ss-htmleditorfield-file').remove(); // Remove any existing views
+ this.find('.ss-gridfield-items .ui-selected').removeClass('ui-selected'); // Unselect all items
+ this.redraw();
+
+ this._super();
+ },
getFileView: function(idOrUrl) {
return this.find('.ss-htmleditorfield-file[data-id=' + idOrUrl + ']');
},
Please sign in to comment.
Something went wrong with that request. Please try again.