annotate js/tinymce/forcecontainer/editor_plugin_src.js @ 31:767ebf925654

Added forcecontainer tinymce plugin, lots and lots and lots of refactorizing.
author David Eads <eads@chicagotech.org>
date Thu, 19 Mar 2009 15:58:36 -0500
parents
children
rev   line source
eads@31 1 /**
eads@31 2 * $Id$
eads@31 3 *
eads@31 4 * A plugin to handle forcing a selection to an outer container with a given
eads@31 5 * class.
eads@31 6 *
eads@31 7 * Options
eads@31 8 *
eads@31 9 * forcecontainer_class:
eads@31 10 *
eads@31 11 * Elements with this class will be forced to the outer container on certain
eads@31 12 * events.
eads@31 13 *
eads@31 14 * forcecontainer_trigger_dnd:
eads@31 15 *
eads@31 16 * Custom option -- enables triggering of a custom event via jQuery for the
eads@31 17 * Drag and Drop Library.
eads@31 18 */
eads@31 19
eads@31 20 (function() {
eads@31 21 var Event = tinymce.dom.Event;
eads@31 22
eads@31 23 tinymce.create('tinymce.plugins.ForceContainerPlugin', {
eads@31 24 getInfo : function() {
eads@31 25 return {
eads@31 26 longname : 'Force an element to its outer container',
eads@31 27 author : 'David Eads',
eads@31 28 authorurl : 'http://invisibleinstitute.com/eads',
eads@31 29 infourl : '',
eads@31 30 version : tinymce.majorVersion + "." + tinymce.minorVersion
eads@31 31 };
eads@31 32 },
eads@31 33
eads@31 34 init : function(ed, url) {
eads@31 35 var t = this, forceContainerClass;
eads@31 36
eads@31 37 t.editor = ed;
eads@31 38 forceContainerClass = ed.getParam("forcecontainer_class", "mceForceContainer");
eads@31 39
eads@31 40 ed.onNodeChange.addToTop(function(ed, cm, n) {
eads@31 41 var sc, ec, c;
eads@31 42
eads@31 43 // Block if start or end is inside a non editable element
eads@31 44 sc = ed.dom.getParent(ed.selection.getStart(), function(n) {
eads@31 45 return ed.dom.hasClass(n, forceContainerClass) && !ed.dom.hasClass(n, 'force-container-processed');
eads@31 46 });
eads@31 47
eads@31 48 ec = ed.dom.getParent(ed.selection.getEnd(), function(n) {
eads@31 49 return ed.dom.hasClass(n, forceContainerClass) && !ed.dom.hasClass(n, 'force-container-processed');
eads@31 50 });
eads@31 51
eads@31 52 // Block or unblock
eads@31 53 if (sc || ec) {
eads@31 54 c = sc ? sc : ec;
eads@31 55 ed.selection.select(c);
eads@31 56 t._setDisabled(1);
eads@31 57 return false;
eads@31 58 } else
eads@31 59 t._setDisabled(0);
eads@31 60 });
eads@31 61 },
eads@31 62
eads@31 63 _block : function(ed, e) {
eads@31 64 var k = e.keyCode, s = ed.selection, n = s.getNode(), reparent, forceContainerClass;
eads@31 65
eads@31 66 // Reparent node
eads@31 67 forceContainerClass = ed.getParam("forcecontainer_class", "mceForceContainer");
eads@31 68
eads@31 69 // Block if start or end is inside a non editable element
eads@31 70 sc = ed.dom.getParent(ed.selection.getStart(), function(n) {
eads@31 71 return ed.dom.hasClass(n, forceContainerClass) && !ed.dom.hasClass(n, 'force-container-processed');
eads@31 72 });
eads@31 73
eads@31 74 ec = ed.dom.getParent(ed.selection.getEnd(), function(n) {
eads@31 75 return ed.dom.hasClass(n, forceContainerClass) && !ed.dom.hasClass(n, 'force-container-processed');
eads@31 76 });
eads@31 77
eads@31 78 if (sc || ec) {
eads@31 79 n = (sc) ? sc : ec;
eads@31 80 }
eads@31 81
eads@31 82 // Pass F1-F12, alt, ctrl, shift, page up, page down, arrow keys
eads@31 83 if ((k > 111 && k < 124) || k == 16 || k == 17 || k == 18 || k == 27 || (k > 32 && k < 41)) {
eads@31 84 return;
eads@31 85 }
eads@31 86
eads@31 87 // Step out to parent and delete
eads@31 88 if (k == 8 || k == 46) {
eads@31 89 if (ed.getParam("forcecontainer_trigger_dnd", false)) {
eads@31 90 // @TODO -- this is getting called twice!!!
eads@31 91 $('#' + ed.id + '-wrapper iframe').trigger('dnd_delete', { 'node' : n });
eads@31 92 }
eads@31 93 ed.execCommand('Delete', false, null);
eads@31 94 }
eads@31 95
eads@31 96 // Typing some common characters
eads@31 97 if (k == 13 || (k > 47 && k < 91) || (k > 95 && k < 112) || (k > 185 && k < 223)) {
eads@31 98 var c = ed.dom.get('__caret'), p;
eads@31 99 if (!c) {
eads@31 100 p = ed.dom.create('p', {}, ((k != 13) ? String.fromCharCode(k) : '') + '<span id="__caret">_</span>');
eads@31 101 ed.dom.insertAfter(p, n);
eads@31 102 s.select(c);
eads@31 103 } else {
eads@31 104 s.select(c);
eads@31 105 ed.execCommand('Delete', false, null);
eads@31 106 }
eads@31 107 }
eads@31 108
eads@31 109 return Event.cancel(e);
eads@31 110 },
eads@31 111
eads@31 112
eads@31 113 _setDisabled : function(s) {
eads@31 114 var t = this, ed = t.editor, n = t.container;
eads@31 115
eads@31 116 tinymce.each(ed.controlManager.controls, function(c) {
eads@31 117 c.setDisabled(s);
eads@31 118 });
eads@31 119
eads@31 120 if (s !== t.disabled) {
eads@31 121 if (s) {
eads@31 122 ed.onClick.addToTop(t._block);
eads@31 123 ed.onMouseDown.addToTop(t._block);
eads@31 124 ed.onKeyDown.addToTop(t._block);
eads@31 125 ed.onKeyPress.addToTop(t._block);
eads@31 126 ed.onKeyUp.addToTop(t._block);
eads@31 127 ed.onPaste.addToTop(t._block);
eads@31 128 } else {
eads@31 129 ed.onClick.remove(t._block); // @TODO causing buggy behavior if you click twice
eads@31 130 ed.onMouseDown.remove(t._block);
eads@31 131 ed.onKeyDown.remove(t._block);
eads@31 132 ed.onKeyPress.remove(t._block);
eads@31 133 ed.onKeyUp.remove(t._block);
eads@31 134 ed.onPaste.remove(t._block);
eads@31 135 }
eads@31 136
eads@31 137 t.disabled = s;
eads@31 138 }
eads@31 139 }
eads@31 140 });
eads@31 141
eads@31 142 // Register plugin
eads@31 143 tinymce.PluginManager.add('forcecontainer', tinymce.plugins.ForceContainerPlugin);
eads@31 144 })();