[Checkins] SVN: z3c.listjs/trunk/ * make sure javascript is executed when doing a renumbering.
Martijn Faassen
faassen at startifact.com
Thu Jun 4 09:51:51 EDT 2009
Log message for revision 100632:
* make sure javascript is executed when doing a renumbering.
* renumber javascript. Scary but will mostly be reliable.
* disconnect TinyMCE editors in things being moved.
Changed:
U z3c.listjs/trunk/CHANGES.txt
U z3c.listjs/trunk/src/z3c/listjs/resources/listjs.js
-=-
Modified: z3c.listjs/trunk/CHANGES.txt
===================================================================
--- z3c.listjs/trunk/CHANGES.txt 2009-06-04 11:46:22 UTC (rev 100631)
+++ z3c.listjs/trunk/CHANGES.txt 2009-06-04 13:51:51 UTC (rev 100632)
@@ -4,6 +4,19 @@
1.0b1 (unreleased)
==================
+* Javascript in ``<script>`` blocks and ``onclick`` handlers are also
+ renumbered so that references to the element id in question are
+ updated. This won't be reliable in the (assumed to uncommon) case
+ where a widget id is referenced within the HTML that is *not* the
+ field of the widget being rendered.
+
+* If TinyMCE is installed, care is taken to disconnect TinyMCE editors
+ before moving. Reconnection of the moved editors is assumed to take
+ place in the included HTML for the new element, using something
+ like::
+
+ tinyMCE.execCommand('mceAddControl', false, 'id_of_element');
+
* A few small bugfixes:
* prefix is passed along to update_numbers
Modified: z3c.listjs/trunk/src/z3c/listjs/resources/listjs.js
===================================================================
--- z3c.listjs/trunk/src/z3c/listjs/resources/listjs.js 2009-06-04 11:46:22 UTC (rev 100631)
+++ z3c.listjs/trunk/src/z3c/listjs/resources/listjs.js 2009-06-04 13:51:51 UTC (rev 100632)
@@ -20,7 +20,9 @@
(function() {
Z3C.namespace('listjs');
-
+
+ var disconnected_editor_ids = [];
+
// return true if string starts with a prefix
var startswith = function(s, prefix) {
return (s.substring(0, prefix.length) == prefix);
@@ -51,7 +53,17 @@
return result.join('.');
};
-
+ var renumberScript = function(s, nr, prefix) {
+ var tomatch = new RegExp(prefix + '[^"\']*', 'g');
+ var potentials = s.match(tomatch);
+ if (potentials == null) {
+ return s; // nothing to replace
+ }
+ var original = potentials[0];
+ var renumbered = renumber(original, nr);
+ return s.replace(original, renumbered);
+ };
+
// simplistic implementation that doesn't understand
// multiple classes per element
var getElementsByClassName = function(class_name, root_el, tag) {
@@ -74,6 +86,13 @@
if (el.nodeType != 1) {
return;
}
+
+ // if this is a script tag, do textual replace
+ if (el.tagName.toLowerCase() == 'script') {
+ el.text = renumberScript(el.text, nr, prefix);
+ return;
+ }
+
var i;
var attributes = ['id', 'name', 'for'];
for (i = 0; i < attributes.length; i++) {
@@ -82,6 +101,12 @@
el.setAttribute(attributes[i], renumber(attr, nr));
}
}
+
+ var onclick_attr = el.getAttribute('onclick');
+ if (onclick_attr) {
+ el.setAttribute('onclick', renumberScript(onclick_attr, nr, prefix));
+ }
+
// recursion
var node = el.firstChild;
while (node) {
@@ -98,12 +123,97 @@
var i;
for (i = 0; i < els.length; i++) {
updateNumbers(els[i], i, prefix);
+ runScripts(els[i]);
}
// update count
var count_el = document.getElementById(prefix + '.count');
count_el.value = els.length;
};
+
+ // disconnect all editors in affected elements
+ var disconnectEditors = function(affected_elements) {
+ // if tinyMCE is installed, disconnect all editors
+ if (tinyMCE) {
+ //tinyMCE.triggerSave();
+ disconnected_editor_ids = [];
+ for (var n in tinyMCE.editors) {
+ var inst = tinyMCE.editors[n];
+ if (!inAffectedElements(inst.getElement(),
+ affected_elements)) {
+ continue;
+ }
+ disconnected_editor_ids.push(inst.id);
+ tinyMCE.execCommand('mceFocus', false, inst.id);
+ tinyMCE.execCommand('mceRemoveControl', false, inst.id);
+ }
+ }
+ };
+ // reconnect all editors that aren't reconnected already
+ var reconnectEditors = function() {
+ // reconnect all editors
+ if (tinyMCE) {
+ for (i = 0; i < disconnected_editor_ids.length; i++) {
+ var editor_id = disconnected_editor_ids[i];
+ if (!tinyMCE.get(editor_id)) {
+ tinyMCE.execCommand('mceAddControl', false, editor_id);
+ }
+ }
+ }
+ };
+
+ // return true if el is inside one of affected_elements
+ var inAffectedElements = function(el, affected_elements) {
+ for (var i = 0; i < affected_elements.length; i++) {
+ if (isAncestor(affected_elements[i], el)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ // return true if a is an ancestor of b
+ var isAncestor = function(a, b) {
+ while (b) {
+ if (a === b) {
+ return true;
+ }
+ b = b.parentNode;
+ }
+ return false;
+ }
+
+
+ // run all embedded scripts (after setting innerHTML)
+ // see http://brightbyte.de/page/Loading_script_tags_via_AJAX
+ // combined with
+ // http://caih.org/open-source-software/loading-javascript-execscript-and-testing/
+ // to eval in the global scope
+ var runScripts = function(e) {
+ if (e.nodeType != 1) {
+ return;
+ }
+
+ // run any script tag
+ if (e.tagName.toLowerCase() == 'script') {
+ if (window.execScript) {
+ window.execScript(e.text);
+ } else {
+ with (window) {
+ window.eval(e.text);
+ }
+ }
+ } else {
+ var n = e.firstChild;
+ while (n) {
+ if (n.nodeType == 1) {
+ runScripts(n);
+ }
+ n = n.nextSibling;
+ }
+ }
+ };
+
// add a new repeating element to the list
Z3C.listjs.add = function(prefix) {
var table_el = document.getElementById(prefix + '.table');
@@ -186,8 +296,13 @@
if (previous_el == null) {
return;
}
+
+ disconnectEditors([el, previous_el]);
+
previous_el.parentNode.insertBefore(el, previous_el);
updateAllNumbers(prefix);
+
+ reconnectEditors();
};
Z3C.listjs.down = function(prefix, el) {
@@ -202,8 +317,12 @@
if (next_el == null) {
return;
}
+ disconnectEditors([el, next_el]);
+
next_el.parentNode.insertBefore(el, next_el.nextSibling);
updateAllNumbers(prefix);
+
+ reconnectEditors();
};
})();
More information about the Checkins
mailing list