tinymce-rails 3.5.2 → 3.5.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/lib/tinymce/rails/version.rb +2 -2
  2. data/vendor/assets/javascripts/tinymce/jquery.tinymce.js +1 -1
  3. data/vendor/assets/javascripts/tinymce/plugins/autolink/editor_plugin_src.js +181 -181
  4. data/vendor/assets/javascripts/tinymce/plugins/autoresize/editor_plugin_src.js +119 -119
  5. data/vendor/assets/javascripts/tinymce/plugins/autosave/editor_plugin.js +1 -1
  6. data/vendor/assets/javascripts/tinymce/plugins/autosave/editor_plugin_src.js +4 -2
  7. data/vendor/assets/javascripts/tinymce/plugins/contextmenu/editor_plugin.js +1 -1
  8. data/vendor/assets/javascripts/tinymce/plugins/contextmenu/editor_plugin_src.js +9 -7
  9. data/vendor/assets/javascripts/tinymce/plugins/emotions/langs/en_dlg.js +1 -1
  10. data/vendor/assets/javascripts/tinymce/plugins/example_dependency/editor_plugin_src.js +50 -50
  11. data/vendor/assets/javascripts/tinymce/plugins/lists/editor_plugin.js +1 -1
  12. data/vendor/assets/javascripts/tinymce/plugins/lists/editor_plugin_src.js +952 -951
  13. data/vendor/assets/javascripts/tinymce/plugins/media/editor_plugin.js +1 -1
  14. data/vendor/assets/javascripts/tinymce/plugins/media/editor_plugin_src.js +22 -14
  15. data/vendor/assets/javascripts/tinymce/plugins/media/langs/en_dlg.js +1 -1
  16. data/vendor/assets/javascripts/tinymce/plugins/style/langs/en_dlg.js +1 -1
  17. data/vendor/assets/javascripts/tinymce/plugins/style/props.htm +845 -845
  18. data/vendor/assets/javascripts/tinymce/plugins/style/readme.txt +19 -19
  19. data/vendor/assets/javascripts/tinymce/plugins/tabfocus/editor_plugin_src.js +122 -122
  20. data/vendor/assets/javascripts/tinymce/plugins/table/editor_plugin.js +1 -1
  21. data/vendor/assets/javascripts/tinymce/plugins/table/editor_plugin_src.js +1449 -1446
  22. data/vendor/assets/javascripts/tinymce/plugins/table/js/table.js +4 -1
  23. data/vendor/assets/javascripts/tinymce/themes/advanced/js/color_picker.js +345 -345
  24. data/vendor/assets/javascripts/tinymce/themes/advanced/langs/en_dlg.js +1 -1
  25. data/vendor/assets/javascripts/tinymce/themes/advanced/skins/default/content.css +0 -1
  26. data/vendor/assets/javascripts/tinymce/themes/advanced/skins/highcontrast/content.css +0 -1
  27. data/vendor/assets/javascripts/tinymce/themes/advanced/skins/o2k7/content.css +0 -1
  28. data/vendor/assets/javascripts/tinymce/themes/advanced/source_editor.htm +1 -1
  29. data/vendor/assets/javascripts/tinymce/tiny_mce.js +1 -1
  30. data/vendor/assets/javascripts/tinymce/tiny_mce_jquery.js +1 -1
  31. data/vendor/assets/javascripts/tinymce/tiny_mce_jquery_src.js +394 -158
  32. data/vendor/assets/javascripts/tinymce/tiny_mce_src.js +394 -158
  33. metadata +5 -4
@@ -1 +1 @@
1
- (function(e){var c="autosave",g="restoredraft",b=true,f,d,a=e.util.Dispatcher;e.create("tinymce.plugins.AutoSave",{init:function(i,j){var h=this,l=i.settings;h.editor=i;function k(n){var m={s:1000,m:60000};n=/^(\d+)([ms]?)$/.exec(""+n);return(n[2]?m[n[2]]:1)*parseInt(n)}e.each({ask_before_unload:b,interval:"30s",retention:"20m",minlength:50},function(n,m){m=c+"_"+m;if(l[m]===f){l[m]=n}});l.autosave_interval=k(l.autosave_interval);l.autosave_retention=k(l.autosave_retention);i.addButton(g,{title:c+".restore_content",onclick:function(){if(i.getContent({draft:true}).replace(/\s|&nbsp;|<\/?p[^>]*>|<br[^>]*>/gi,"").length>0){i.windowManager.confirm(c+".warning_message",function(m){if(m){h.restoreDraft()}})}else{h.restoreDraft()}}});i.onNodeChange.add(function(){var m=i.controlManager;if(m.get(g)){m.setDisabled(g,!h.hasDraft())}});i.onInit.add(function(){if(i.controlManager.get(g)){h.setupStorage(i);setInterval(function(){h.storeDraft();i.nodeChanged()},l.autosave_interval)}});h.onStoreDraft=new a(h);h.onRestoreDraft=new a(h);h.onRemoveDraft=new a(h);if(!d){window.onbeforeunload=e.plugins.AutoSave._beforeUnloadHandler;d=b}},getInfo:function(){return{longname:"Auto save",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave",version:e.majorVersion+"."+e.minorVersion}},getExpDate:function(){return new Date(new Date().getTime()+this.editor.settings.autosave_retention).toUTCString()},setupStorage:function(i){var h=this,k=c+"_test",j="OK";h.key=c+i.id;e.each([function(){if(localStorage){localStorage.setItem(k,j);if(localStorage.getItem(k)===j){localStorage.removeItem(k);return localStorage}}},function(){if(sessionStorage){sessionStorage.setItem(k,j);if(sessionStorage.getItem(k)===j){sessionStorage.removeItem(k);return sessionStorage}}},function(){if(e.isIE){i.getElement().style.behavior="url('#default#userData')";return{autoExpires:b,setItem:function(l,n){var m=i.getElement();m.setAttribute(l,n);m.expires=h.getExpDate();try{m.save("TinyMCE")}catch(o){}},getItem:function(l){var m=i.getElement();try{m.load("TinyMCE");return m.getAttribute(l)}catch(n){return null}},removeItem:function(l){i.getElement().removeAttribute(l)}}}},],function(l){try{h.storage=l();if(h.storage){return false}}catch(m){}})},storeDraft:function(){var i=this,l=i.storage,j=i.editor,h,k;if(l){if(!l.getItem(i.key)&&!j.isDirty()){return}k=j.getContent({draft:true});if(k.length>j.settings.autosave_minlength){h=i.getExpDate();if(!i.storage.autoExpires){i.storage.setItem(i.key+"_expires",h)}i.storage.setItem(i.key,k);i.onStoreDraft.dispatch(i,{expires:h,content:k})}}},restoreDraft:function(){var h=this,j=h.storage,i;if(j){i=j.getItem(h.key);if(i){h.editor.setContent(i);h.onRestoreDraft.dispatch(h,{content:i})}}},hasDraft:function(){var h=this,k=h.storage,i,j;if(k){j=!!k.getItem(h.key);if(j){if(!h.storage.autoExpires){i=new Date(k.getItem(h.key+"_expires"));if(new Date().getTime()<i.getTime()){return b}h.removeDraft()}else{return b}}}return false},removeDraft:function(){var h=this,k=h.storage,i=h.key,j;if(k){j=k.getItem(i);k.removeItem(i);k.removeItem(i+"_expires");if(j){h.onRemoveDraft.dispatch(h,{content:j})}}},"static":{_beforeUnloadHandler:function(h){var i;e.each(tinyMCE.editors,function(j){if(j.plugins.autosave){j.plugins.autosave.storeDraft()}if(j.getParam("fullscreen_is_enabled")){return}if(!i&&j.isDirty()&&j.getParam("autosave_ask_before_unload")){i=j.getLang("autosave.unload_msg")}});return i}}});e.PluginManager.add("autosave",e.plugins.AutoSave)})(tinymce);
1
+ (function(e){var c="autosave",g="restoredraft",b=true,f,d,a=e.util.Dispatcher;e.create("tinymce.plugins.AutoSave",{init:function(i,j){var h=this,l=i.settings;h.editor=i;function k(n){var m={s:1000,m:60000};n=/^(\d+)([ms]?)$/.exec(""+n);return(n[2]?m[n[2]]:1)*parseInt(n)}e.each({ask_before_unload:b,interval:"30s",retention:"20m",minlength:50},function(n,m){m=c+"_"+m;if(l[m]===f){l[m]=n}});l.autosave_interval=k(l.autosave_interval);l.autosave_retention=k(l.autosave_retention);i.addButton(g,{title:c+".restore_content",onclick:function(){if(i.getContent({draft:true}).replace(/\s|&nbsp;|<\/?p[^>]*>|<br[^>]*>/gi,"").length>0){i.windowManager.confirm(c+".warning_message",function(m){if(m){h.restoreDraft()}})}else{h.restoreDraft()}}});i.onNodeChange.add(function(){var m=i.controlManager;if(m.get(g)){m.setDisabled(g,!h.hasDraft())}});i.onInit.add(function(){if(i.controlManager.get(g)){h.setupStorage(i);setInterval(function(){if(!i.removed){h.storeDraft();i.nodeChanged()}},l.autosave_interval)}});h.onStoreDraft=new a(h);h.onRestoreDraft=new a(h);h.onRemoveDraft=new a(h);if(!d){window.onbeforeunload=e.plugins.AutoSave._beforeUnloadHandler;d=b}},getInfo:function(){return{longname:"Auto save",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave",version:e.majorVersion+"."+e.minorVersion}},getExpDate:function(){return new Date(new Date().getTime()+this.editor.settings.autosave_retention).toUTCString()},setupStorage:function(i){var h=this,k=c+"_test",j="OK";h.key=c+i.id;e.each([function(){if(localStorage){localStorage.setItem(k,j);if(localStorage.getItem(k)===j){localStorage.removeItem(k);return localStorage}}},function(){if(sessionStorage){sessionStorage.setItem(k,j);if(sessionStorage.getItem(k)===j){sessionStorage.removeItem(k);return sessionStorage}}},function(){if(e.isIE){i.getElement().style.behavior="url('#default#userData')";return{autoExpires:b,setItem:function(l,n){var m=i.getElement();m.setAttribute(l,n);m.expires=h.getExpDate();try{m.save("TinyMCE")}catch(o){}},getItem:function(l){var m=i.getElement();try{m.load("TinyMCE");return m.getAttribute(l)}catch(n){return null}},removeItem:function(l){i.getElement().removeAttribute(l)}}}},],function(l){try{h.storage=l();if(h.storage){return false}}catch(m){}})},storeDraft:function(){var i=this,l=i.storage,j=i.editor,h,k;if(l){if(!l.getItem(i.key)&&!j.isDirty()){return}k=j.getContent({draft:true});if(k.length>j.settings.autosave_minlength){h=i.getExpDate();if(!i.storage.autoExpires){i.storage.setItem(i.key+"_expires",h)}i.storage.setItem(i.key,k);i.onStoreDraft.dispatch(i,{expires:h,content:k})}}},restoreDraft:function(){var h=this,j=h.storage,i;if(j){i=j.getItem(h.key);if(i){h.editor.setContent(i);h.onRestoreDraft.dispatch(h,{content:i})}}},hasDraft:function(){var h=this,k=h.storage,i,j;if(k){j=!!k.getItem(h.key);if(j){if(!h.storage.autoExpires){i=new Date(k.getItem(h.key+"_expires"));if(new Date().getTime()<i.getTime()){return b}h.removeDraft()}else{return b}}}return false},removeDraft:function(){var h=this,k=h.storage,i=h.key,j;if(k){j=k.getItem(i);k.removeItem(i);k.removeItem(i+"_expires");if(j){h.onRemoveDraft.dispatch(h,{content:j})}}},"static":{_beforeUnloadHandler:function(h){var i;e.each(tinyMCE.editors,function(j){if(j.plugins.autosave){j.plugins.autosave.storeDraft()}if(j.getParam("fullscreen_is_enabled")){return}if(!i&&j.isDirty()&&j.getParam("autosave_ask_before_unload")){i=j.getLang("autosave.unload_msg")}});return i}}});e.PluginManager.add("autosave",e.plugins.AutoSave)})(tinymce);
@@ -136,8 +136,10 @@
136
136
 
137
137
  // Auto save contents each interval time
138
138
  setInterval(function() {
139
- self.storeDraft();
140
- ed.nodeChanged();
139
+ if (!ed.removed) {
140
+ self.storeDraft();
141
+ ed.nodeChanged();
142
+ }
141
143
  }, settings.autosave_interval);
142
144
  }
143
145
  });
@@ -1 +1 @@
1
- (function(){var a=tinymce.dom.Event,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.ContextMenu",{init:function(e){var h=this,f,d,i;h.editor=e;d=e.settings.contextmenu_never_use_native;h.onContextMenu=new tinymce.util.Dispatcher(this);f=e.onContextMenu.add(function(j,k){if((i!==0?i:k.ctrlKey)&&!d){return}a.cancel(k);if(k.target.nodeName=="IMG"){j.selection.select(k.target)}h._getMenu(j).showMenu(k.clientX||k.pageX,k.clientY||k.pageY);a.add(j.getDoc(),"click",function(l){g(j,l)});j.nodeChanged()});e.onRemove.add(function(){if(h._menu){h._menu.removeAll()}});function g(j,k){i=0;if(k&&k.button==2){i=k.ctrlKey;return}if(h._menu){h._menu.removeAll();h._menu.destroy();a.remove(j.getDoc(),"click",g);h._menu=null}}e.onMouseDown.add(g);e.onKeyDown.add(g);e.onKeyDown.add(function(j,k){if(k.shiftKey&&!k.ctrlKey&&!k.altKey&&k.keyCode===121){a.cancel(k);f(j,k)}})},getInfo:function(){return{longname:"Contextmenu",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_getMenu:function(e){var g=this,d=g._menu,j=e.selection,f=j.isCollapsed(),h=j.getNode()||e.getBody(),i,k;if(d){d.removeAll();d.destroy()}k=b.getPos(e.getContentAreaContainer());d=e.controlManager.createDropMenu("contextmenu",{offset_x:k.x+e.getParam("contextmenu_offset_x",0),offset_y:k.y+e.getParam("contextmenu_offset_y",0),constrain:1,keyboard_focus:true});g._menu=d;d.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(f);d.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(f);d.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((h.nodeName=="A"&&!e.dom.getAttrib(h,"name"))||!f){d.addSeparator();d.add({title:"advanced.link_desc",icon:"link",cmd:e.plugins.advlink?"mceAdvLink":"mceLink",ui:true});d.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}d.addSeparator();d.add({title:"advanced.image_desc",icon:"image",cmd:e.plugins.advimage?"mceAdvImage":"mceImage",ui:true});d.addSeparator();i=d.addMenu({title:"contextmenu.align"});i.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});i.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});i.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});i.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});g.onContextMenu.dispatch(g,d,h,f);return d}});tinymce.PluginManager.add("contextmenu",tinymce.plugins.ContextMenu)})();
1
+ (function(){var a=tinymce.dom.Event,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.ContextMenu",{init:function(f){var i=this,g,d,j,e;i.editor=f;d=f.settings.contextmenu_never_use_native;i.onContextMenu=new tinymce.util.Dispatcher(this);e=function(k){h(f,k)};g=f.onContextMenu.add(function(k,l){if((j!==0?j:l.ctrlKey)&&!d){return}a.cancel(l);if(l.target.nodeName=="IMG"){k.selection.select(l.target)}i._getMenu(k).showMenu(l.clientX||l.pageX,l.clientY||l.pageY);a.add(k.getDoc(),"click",e);k.nodeChanged()});f.onRemove.add(function(){if(i._menu){i._menu.removeAll()}});function h(k,l){j=0;if(l&&l.button==2){j=l.ctrlKey;return}if(i._menu){i._menu.removeAll();i._menu.destroy();a.remove(k.getDoc(),"click",e);i._menu=null}}f.onMouseDown.add(h);f.onKeyDown.add(h);f.onKeyDown.add(function(k,l){if(l.shiftKey&&!l.ctrlKey&&!l.altKey&&l.keyCode===121){a.cancel(l);g(k,l)}})},getInfo:function(){return{longname:"Contextmenu",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_getMenu:function(e){var g=this,d=g._menu,j=e.selection,f=j.isCollapsed(),h=j.getNode()||e.getBody(),i,k;if(d){d.removeAll();d.destroy()}k=b.getPos(e.getContentAreaContainer());d=e.controlManager.createDropMenu("contextmenu",{offset_x:k.x+e.getParam("contextmenu_offset_x",0),offset_y:k.y+e.getParam("contextmenu_offset_y",0),constrain:1,keyboard_focus:true});g._menu=d;d.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(f);d.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(f);d.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((h.nodeName=="A"&&!e.dom.getAttrib(h,"name"))||!f){d.addSeparator();d.add({title:"advanced.link_desc",icon:"link",cmd:e.plugins.advlink?"mceAdvLink":"mceLink",ui:true});d.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}d.addSeparator();d.add({title:"advanced.image_desc",icon:"image",cmd:e.plugins.advimage?"mceAdvImage":"mceImage",ui:true});d.addSeparator();i=d.addMenu({title:"contextmenu.align"});i.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});i.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});i.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});i.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});g.onContextMenu.dispatch(g,d,h,f);return d}});tinymce.PluginManager.add("contextmenu",tinymce.plugins.ContextMenu)})();
@@ -27,7 +27,7 @@
27
27
  * @param {string} url Absolute URL to where the plugin is located.
28
28
  */
29
29
  init : function(ed) {
30
- var t = this, showMenu, contextmenuNeverUseNative, realCtrlKey;
30
+ var t = this, showMenu, contextmenuNeverUseNative, realCtrlKey, hideMenu;
31
31
 
32
32
  t.editor = ed;
33
33
 
@@ -42,6 +42,10 @@
42
42
  */
43
43
  t.onContextMenu = new tinymce.util.Dispatcher(this);
44
44
 
45
+ hideMenu = function(e) {
46
+ hide(ed, e);
47
+ };
48
+
45
49
  showMenu = ed.onContextMenu.add(function(ed, e) {
46
50
  // Block TinyMCE menu on ctrlKey and work around Safari issue
47
51
  if ((realCtrlKey !== 0 ? realCtrlKey : e.ctrlKey) && !contextmenuNeverUseNative)
@@ -54,13 +58,11 @@
54
58
  ed.selection.select(e.target);
55
59
 
56
60
  t._getMenu(ed).showMenu(e.clientX || e.pageX, e.clientY || e.pageY);
57
- Event.add(ed.getDoc(), 'click', function(e) {
58
- hide(ed, e);
59
- });
61
+ Event.add(ed.getDoc(), 'click', hideMenu);
60
62
 
61
63
  ed.nodeChanged();
62
64
  });
63
-
65
+
64
66
  ed.onRemove.add(function() {
65
67
  if (t._menu)
66
68
  t._menu.removeAll();
@@ -78,8 +80,8 @@
78
80
 
79
81
  if (t._menu) {
80
82
  t._menu.removeAll();
81
- t._menu.destroy();
82
- Event.remove(ed.getDoc(), 'click', hide);
83
+ t._menu.destroy();
84
+ Event.remove(ed.getDoc(), 'click', hideMenu);
83
85
  t._menu = null;
84
86
  }
85
87
  };
@@ -1 +1 @@
1
- tinyMCE.addI18n('en.emotions_dlg',{cry:"Cry",cool:"Cool",desc:"Emotions",title:"Insert Emotion",usage:"Use left and right arrows to navigate.",yell:"Yell",wink:"Wink",undecided:"Undecided","tongue_out":"Tongue Out",surprised:"Surprised",smile:"Smile",sealed:"Sealed","money_mouth":"Money Mouth",laughing:"Laughing",kiss:"Kiss",innocent:"Innocent",frown:"Frown","foot_in_mouth":"Foot in Mouth",embarassed:"Embarassed"});
1
+ tinyMCE.addI18n('en.emotions_dlg',{cry:"Cry",cool:"Cool",desc:"Emotions",title:"Insert Emotion",usage:"Use left and right arrows to navigate.",yell:"Yell",wink:"Wink",undecided:"Undecided","tongue_out":"Tongue Out",surprised:"Surprised",smile:"Smile",sealed:"Sealed","money_mouth":"Money Mouth",laughing:"Laughing",kiss:"Kiss",innocent:"Innocent",frown:"Frown","foot_in_mouth":"Foot in Mouth",embarassed:"Embarassed"});
@@ -1,50 +1,50 @@
1
- /**
2
- * editor_plugin_src.js
3
- *
4
- * Copyright 2009, Moxiecode Systems AB
5
- * Released under LGPL License.
6
- *
7
- * License: http://tinymce.moxiecode.com/license
8
- * Contributing: http://tinymce.moxiecode.com/contributing
9
- */
10
-
11
- (function() {
12
-
13
- tinymce.create('tinymce.plugins.ExampleDependencyPlugin', {
14
- /**
15
- * Initializes the plugin, this will be executed after the plugin has been created.
16
- * This call is done before the editor instance has finished it's initialization so use the onInit event
17
- * of the editor instance to intercept that event.
18
- *
19
- * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
20
- * @param {string} url Absolute URL to where the plugin is located.
21
- */
22
- init : function(ed, url) {
23
- },
24
-
25
-
26
- /**
27
- * Returns information about the plugin as a name/value array.
28
- * The current keys are longname, author, authorurl, infourl and version.
29
- *
30
- * @return {Object} Name/value array containing information about the plugin.
31
- */
32
- getInfo : function() {
33
- return {
34
- longname : 'Example Dependency plugin',
35
- author : 'Some author',
36
- authorurl : 'http://tinymce.moxiecode.com',
37
- infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example_dependency',
38
- version : "1.0"
39
- };
40
- }
41
- });
42
-
43
- /**
44
- * Register the plugin, specifying the list of the plugins that this plugin depends on. They are specified in a list, with the list loaded in order.
45
- * plugins in this list will be initialised when this plugin is initialized. (before the init method is called).
46
- * plugins in a depends list should typically be specified using the short name). If neccesary this can be done
47
- * with an object which has the url to the plugin and the shortname.
48
- */
49
- tinymce.PluginManager.add('example_dependency', tinymce.plugins.ExampleDependencyPlugin, ['example']);
50
- })();
1
+ /**
2
+ * editor_plugin_src.js
3
+ *
4
+ * Copyright 2009, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://tinymce.moxiecode.com/license
8
+ * Contributing: http://tinymce.moxiecode.com/contributing
9
+ */
10
+
11
+ (function() {
12
+
13
+ tinymce.create('tinymce.plugins.ExampleDependencyPlugin', {
14
+ /**
15
+ * Initializes the plugin, this will be executed after the plugin has been created.
16
+ * This call is done before the editor instance has finished it's initialization so use the onInit event
17
+ * of the editor instance to intercept that event.
18
+ *
19
+ * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
20
+ * @param {string} url Absolute URL to where the plugin is located.
21
+ */
22
+ init : function(ed, url) {
23
+ },
24
+
25
+
26
+ /**
27
+ * Returns information about the plugin as a name/value array.
28
+ * The current keys are longname, author, authorurl, infourl and version.
29
+ *
30
+ * @return {Object} Name/value array containing information about the plugin.
31
+ */
32
+ getInfo : function() {
33
+ return {
34
+ longname : 'Example Dependency plugin',
35
+ author : 'Some author',
36
+ authorurl : 'http://tinymce.moxiecode.com',
37
+ infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example_dependency',
38
+ version : "1.0"
39
+ };
40
+ }
41
+ });
42
+
43
+ /**
44
+ * Register the plugin, specifying the list of the plugins that this plugin depends on. They are specified in a list, with the list loaded in order.
45
+ * plugins in this list will be initialised when this plugin is initialized. (before the init method is called).
46
+ * plugins in a depends list should typically be specified using the short name). If neccesary this can be done
47
+ * with an object which has the url to the plugin and the shortname.
48
+ */
49
+ tinymce.PluginManager.add('example_dependency', tinymce.plugins.ExampleDependencyPlugin, ['example']);
50
+ })();
@@ -1 +1 @@
1
- (function(){var e=tinymce.each,r=tinymce.dom.Event,g;function p(t,s){while(t&&(t.nodeType===8||(t.nodeType===3&&/^[ \t\n\r]*$/.test(t.nodeValue)))){t=s(t)}return t}function b(s){return p(s,function(t){return t.previousSibling})}function i(s){return p(s,function(t){return t.nextSibling})}function d(s,u,t){return s.dom.getParent(u,function(v){return tinymce.inArray(t,v)!==-1})}function n(s){return s&&(s.tagName==="OL"||s.tagName==="UL")}function c(u,v){var t,w,s;t=b(u.lastChild);while(n(t)){w=t;t=b(w.previousSibling)}if(w){s=v.create("li",{style:"list-style-type: none;"});v.split(u,w);v.insertAfter(s,w);s.appendChild(w);s.appendChild(w);u=s.previousSibling}return u}function m(t,s,u){t=a(t,s,u);return o(t,s,u)}function a(u,s,v){var t=b(u.previousSibling);if(t){return h(t,u,s?t:false,v)}else{return u}}function o(u,t,v){var s=i(u.nextSibling);if(s){return h(u,s,t?s:false,v)}else{return u}}function h(u,s,t,v){if(l(u,s,!!t,v)){return f(u,s,t)}else{if(u&&u.tagName==="LI"&&n(s)){u.appendChild(s)}}return s}function l(u,t,s,v){if(!u||!t){return false}else{if(u.tagName==="LI"&&t.tagName==="LI"){return t.style.listStyleType==="none"||j(t)}else{if(n(u)){return(u.tagName===t.tagName&&(s||u.style.listStyleType===t.style.listStyleType))||q(t)}else{return v&&u.tagName==="P"&&t.tagName==="P"}}}}function q(t){var s=i(t.firstChild),u=b(t.lastChild);return s&&u&&n(t)&&s===u&&(n(s)||s.style.listStyleType==="none"||j(s))}function j(u){var t=i(u.firstChild),s=b(u.lastChild);return t&&s&&t===s&&n(t)}function f(w,v,s){var u=b(w.lastChild),t=i(v.firstChild);if(w.tagName==="P"){w.appendChild(w.ownerDocument.createElement("br"))}while(v.firstChild){w.appendChild(v.firstChild)}if(s){w.style.listStyleType=s.style.listStyleType}v.parentNode.removeChild(v);h(u,t,false);return w}function k(t,u){var s;if(!u.is(t,"li,ol,ul")){s=u.getParent(t,"li");if(s){t=s}}return t}tinymce.create("tinymce.plugins.Lists",{init:function(y){var v="TABBING";var s="EMPTY";var J="ESCAPE";var z="PARAGRAPH";var N="UNKNOWN";var x=N;function E(U){return U.keyCode===tinymce.VK.TAB&&!(U.altKey||U.ctrlKey)&&(y.queryCommandState("InsertUnorderedList")||y.queryCommandState("InsertOrderedList"))}function w(){var U=B();var W=U.parentNode.parentNode;var V=U.parentNode.lastChild===U;return V&&!t(W)&&P(U)}function t(U){if(n(U)){return U.parentNode&&U.parentNode.tagName==="LI"}else{return U.tagName==="LI"}}function F(){return y.selection.isCollapsed()&&P(B())}function B(){var U=y.selection.getStart();return((U.tagName=="BR"||U.tagName=="")&&U.parentNode.tagName=="LI")?U.parentNode:U}function P(U){var V=U.childNodes.length;if(U.tagName==="LI"){return V==0?true:V==1&&(U.firstChild.tagName==""||U.firstChild.tagName=="BR"||H(U))}return false}function H(U){var V=tinymce.grep(U.parentNode.childNodes,function(Y){return Y.tagName=="LI"});var W=U==V[V.length-1];var X=U.firstChild;return tinymce.isIE9&&W&&(X.nodeValue==String.fromCharCode(160)||X.nodeValue==String.fromCharCode(32))}function T(U){return U.keyCode===tinymce.VK.ENTER}function A(U){return T(U)&&!U.shiftKey}function M(U){if(E(U)){return v}else{if(A(U)&&w()){return N}else{if(A(U)&&F()){return s}else{return N}}}}function D(U,V){if(x==v||x==s||tinymce.isGecko&&x==J){r.cancel(V)}}function C(){var U=y.selection.getRng(true);var V=U.startContainer;if(V.nodeType==3){var W=V.nodeValue;if(tinymce.isIE9&&W.length>1&&W.charCodeAt(W.length-1)==32){return(U.endOffset==W.length-1)}else{return(U.endOffset==W.length)}}else{if(V.nodeType==1){return U.endOffset==V.childNodes.length}}return false}function I(){var W=y.selection.getNode();var V="h1,h2,h3,h4,h5,h6,p,div";var U=y.dom.is(W,V)&&W.parentNode.tagName==="LI"&&W.parentNode.lastChild===W;return y.selection.isCollapsed()&&U&&C()}function K(W,Y){if(A(Y)&&I()){var X=W.selection.getNode();var V=W.dom.create("li");var U=W.dom.getParent(X,"li");W.dom.insertAfter(V,U);if(tinymce.isIE6||tinymce.isIE7||tinyMCE.isIE8){W.selection.setCursorLocation(V,1)}else{W.selection.setCursorLocation(V,0)}Y.preventDefault()}}function u(X,Z){var ac;if(!tinymce.isGecko){return}var V=X.selection.getStart();if(Z.keyCode!=tinymce.VK.BACKSPACE||V.tagName!=="IMG"){return}function W(ag){var ah=ag.firstChild;var af=null;do{if(!ah){break}if(ah.tagName==="LI"){af=ah}}while(ah=ah.nextSibling);return af}function ae(ag,af){while(ag.childNodes.length>0){af.appendChild(ag.childNodes[0])}}ac=V.parentNode.previousSibling;if(!ac){return}var aa;if(ac.tagName==="UL"||ac.tagName==="OL"){aa=ac}else{if(ac.previousSibling&&(ac.previousSibling.tagName==="UL"||ac.previousSibling.tagName==="OL")){aa=ac.previousSibling}else{return}}var ad=W(aa);var U=X.dom.createRng();U.setStart(ad,1);U.setEnd(ad,1);X.selection.setRng(U);X.selection.collapse(true);var Y=X.selection.getBookmark();var ab=V.parentNode.cloneNode(true);if(ab.tagName==="P"||ab.tagName==="DIV"){ae(ab,ad)}else{ad.appendChild(ab)}V.parentNode.parentNode.removeChild(V.parentNode);X.selection.moveToBookmark(Y)}function G(U){var V=y.dom.getParent(U,"ol,ul");if(V!=null){var W=V.lastChild;y.selection.setCursorLocation(W,0)}}this.ed=y;y.addCommand("Indent",this.indent,this);y.addCommand("Outdent",this.outdent,this);y.addCommand("InsertUnorderedList",function(){this.applyList("UL","OL")},this);y.addCommand("InsertOrderedList",function(){this.applyList("OL","UL")},this);y.onInit.add(function(){y.editorCommands.addCommands({outdent:function(){var V=y.selection,W=y.dom;function U(X){X=W.getParent(X,W.isBlock);return X&&(parseInt(y.dom.getStyle(X,"margin-left")||0,10)+parseInt(y.dom.getStyle(X,"padding-left")||0,10))>0}return U(V.getStart())||U(V.getEnd())||y.queryCommandState("InsertOrderedList")||y.queryCommandState("InsertUnorderedList")}},"state")});y.onKeyUp.add(function(V,W){if(x==v){V.execCommand(W.shiftKey?"Outdent":"Indent",true,null);x=N;return r.cancel(W)}else{if(x==s){var U=B();var Y=V.settings.list_outdent_on_enter===true||W.shiftKey;V.execCommand(Y?"Outdent":"Indent",true,null);if(tinymce.isIE){G(U)}return r.cancel(W)}else{if(x==J){if(tinymce.isIE6||tinymce.isIE7||tinymce.isIE8){var X=V.getDoc().createTextNode("\uFEFF");V.selection.getNode().appendChild(X)}else{if(tinymce.isIE9||tinymce.isGecko){V.execCommand("Outdent");return r.cancel(W)}}}}}});function L(V,U){var W=y.getDoc().createTextNode("\uFEFF");V.insertBefore(W,U);y.selection.setCursorLocation(W,0);y.execCommand("mceRepaint")}function R(V,X){if(T(X)){var U=B();if(U){var W=U.parentNode;var Y=W&&W.parentNode;if(Y&&Y.nodeName=="LI"&&Y.firstChild==W&&U==W.firstChild){L(Y,W)}}}}function S(V,X){if(T(X)){var U=B();if(V.dom.select("ul li",U).length===1){var W=U.firstChild;L(U,W)}}}function Q(V,Z){function W(ad,aa){var ac=[];var ae=new tinymce.dom.TreeWalker(aa,ad);for(var ab=ae.current();ab;ab=ae.next()){if(V.dom.is(ab,"ol,ul,li")){ac.push(ab)}}return ac}if(Z.keyCode==tinymce.VK.BACKSPACE){var U=B();if(U){var Y=V.dom.getParent(U,"ol,ul");if(Y&&Y.firstChild===U){var X=W(Y,U);V.execCommand("Outdent",false,X);V.undoManager.add();return r.cancel(Z)}}}}function O(V,X){var U=B();if(X.keyCode===tinymce.VK.BACKSPACE&&V.dom.is(U,"li")&&U.parentNode.firstChild!==U){if(V.dom.select("ul,ol",U).length===1){var Z=U.previousSibling;V.dom.remove(V.dom.select("br",U));V.dom.remove(U,true);var W=tinymce.grep(Z.childNodes,function(aa){return aa.nodeType===3});if(W.length===1){var Y=W[0];V.selection.setCursorLocation(Y,Y.length)}V.undoManager.add();return r.cancel(X)}}}y.onKeyDown.add(function(U,V){x=M(V)});y.onKeyDown.add(D);y.onKeyDown.add(u);y.onKeyDown.add(K);if(tinymce.isGecko){y.onKeyUp.add(R)}if(tinymce.isIE8){y.onKeyUp.add(S)}if(tinymce.isGecko||tinymce.isWebKit){y.onKeyDown.add(Q)}if(tinymce.isWebKit){y.onKeyDown.add(O)}},applyList:function(y,v){var C=this,z=C.ed,I=z.dom,s=[],H=false,u=false,w=false,B,G=z.selection.getSelectedBlocks();function E(t){if(t&&t.tagName==="BR"){I.remove(t)}}function F(M){var N=I.create(y),t;function L(O){if(O.style.marginLeft||O.style.paddingLeft){C.adjustPaddingFunction(false)(O)}}if(M.tagName==="LI"){}else{if(M.tagName==="P"||M.tagName==="DIV"||M.tagName==="BODY"){K(M,function(P,O){J(P,O,M.tagName==="BODY"?null:P.parentNode);t=P.parentNode;L(t);E(O)});if(t){if(t.tagName==="LI"&&(M.tagName==="P"||G.length>1)){I.split(t.parentNode.parentNode,t.parentNode)}m(t.parentNode,true)}return}else{t=I.create("li");I.insertAfter(t,M);t.appendChild(M);L(M);M=t}}I.insertAfter(N,M);N.appendChild(M);m(N,true);s.push(M)}function J(P,L,N){var t,O=P,M;while(!I.isBlock(P.parentNode)&&P.parentNode!==I.getRoot()){P=I.split(P.parentNode,P.previousSibling);P=P.nextSibling;O=P}if(N){t=N.cloneNode(true);P.parentNode.insertBefore(t,P);while(t.firstChild){I.remove(t.firstChild)}t=I.rename(t,"li")}else{t=I.create("li");P.parentNode.insertBefore(t,P)}while(O&&O!=L){M=O.nextSibling;t.appendChild(O);O=M}if(t.childNodes.length===0){t.innerHTML='<br _mce_bogus="1" />'}F(t)}function K(Q,T){var N,R,O=3,L=1,t="br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl";function P(X,U){var V=I.createRng(),W;g.keep=true;z.selection.moveToBookmark(g);g.keep=false;W=z.selection.getRng(true);if(!U){U=X.parentNode.lastChild}V.setStartBefore(X);V.setEndAfter(U);return !(V.compareBoundaryPoints(O,W)>0||V.compareBoundaryPoints(L,W)<=0)}function S(U){if(U.nextSibling){return U.nextSibling}if(!I.isBlock(U.parentNode)&&U.parentNode!==I.getRoot()){return S(U.parentNode)}}N=Q.firstChild;var M=false;e(I.select(t,Q),function(U){if(U.hasAttribute&&U.hasAttribute("_mce_bogus")){return true}if(P(N,U)){I.addClass(U,"_mce_tagged_br");N=S(U)}});M=(N&&P(N,undefined));N=Q.firstChild;e(I.select(t,Q),function(V){var U=S(V);if(V.hasAttribute&&V.hasAttribute("_mce_bogus")){return true}if(I.hasClass(V,"_mce_tagged_br")){T(N,V,R);R=null}else{R=V}N=U});if(M){T(N,undefined,R)}}function D(t){K(t,function(M,L,N){J(M,L);E(L);E(N)})}function A(t){if(tinymce.inArray(s,t)!==-1){return}if(t.parentNode.tagName===v){I.split(t.parentNode,t);F(t);o(t.parentNode,false)}s.push(t)}function x(M){var O,N,L,t;if(tinymce.inArray(s,M)!==-1){return}M=c(M,I);while(I.is(M.parentNode,"ol,ul,li")){I.split(M.parentNode,M)}s.push(M);M=I.rename(M,"p");L=m(M,false,z.settings.force_br_newlines);if(L===M){O=M.firstChild;while(O){if(I.isBlock(O)){O=I.split(O.parentNode,O);t=true;N=O.nextSibling&&O.nextSibling.firstChild}else{N=O.nextSibling;if(t&&O.tagName==="BR"){I.remove(O)}t=false}O=N}}}e(G,function(t){t=k(t,I);if(t.tagName===v||(t.tagName==="LI"&&t.parentNode.tagName===v)){u=true}else{if(t.tagName===y||(t.tagName==="LI"&&t.parentNode.tagName===y)){H=true}else{w=true}}});if(w&&!H||u||G.length===0){B={LI:A,H1:F,H2:F,H3:F,H4:F,H5:F,H6:F,P:F,BODY:F,DIV:G.length>1?F:D,defaultAction:D,elements:this.selectedBlocks()}}else{B={defaultAction:x,elements:this.selectedBlocks()}}this.process(B)},indent:function(){var u=this.ed,w=u.dom,x=[];function s(z){var y=w.create("li",{style:"list-style-type: none;"});w.insertAfter(y,z);return y}function t(B){var y=s(B),D=w.getParent(B,"ol,ul"),C=D.tagName,E=w.getStyle(D,"list-style-type"),A={},z;if(E!==""){A.style="list-style-type: "+E+";"}z=w.create(C,A);y.appendChild(z);return z}function v(z){if(!d(u,z,x)){z=c(z,w);var y=t(z);y.appendChild(z);m(y.parentNode,false);m(y,false);x.push(z)}}this.process({LI:v,defaultAction:this.adjustPaddingFunction(true),elements:this.selectedBlocks()})},outdent:function(y,x){var w=this,u=w.ed,z=u.dom,s=[];function A(t){var C,B,D;if(!d(u,t,s)){if(z.getStyle(t,"margin-left")!==""||z.getStyle(t,"padding-left")!==""){return w.adjustPaddingFunction(false)(t)}D=z.getStyle(t,"text-align",true);if(D==="center"||D==="right"){z.setStyle(t,"text-align","left");return}t=c(t,z);C=t.parentNode;B=t.parentNode.parentNode;if(B.tagName==="P"){z.split(B,t.parentNode)}else{z.split(C,t);if(B.tagName==="LI"){z.split(B,t)}else{if(!z.is(B,"ol,ul")){z.rename(t,"p")}}}s.push(t)}}var v=x&&tinymce.is(x,"array")?x:this.selectedBlocks();this.process({LI:A,defaultAction:this.adjustPaddingFunction(false),elements:v});e(s,m)},process:function(y){var F=this,w=F.ed.selection,z=F.ed.dom,E,u;function B(t){var s=tinymce.grep(t.childNodes,function(H){return !(H.nodeName==="BR"||H.nodeName==="SPAN"&&z.getAttrib(H,"data-mce-type")=="bookmark"||H.nodeType==3&&(H.nodeValue==String.fromCharCode(160)||H.nodeValue==""))});return s.length===0}function x(s){z.removeClass(s,"_mce_act_on");if(!s||s.nodeType!==1||E.length>1&&B(s)){return}s=k(s,z);var t=y[s.tagName];if(!t){t=y.defaultAction}t(s)}function v(s){F.splitSafeEach(s.childNodes,x)}function C(s,t){return t>=0&&s.hasChildNodes()&&t<s.childNodes.length&&s.childNodes[t].tagName==="BR"}function D(){var t=w.getNode();var s=z.getParent(t,"td");return s!==null}E=y.elements;u=w.getRng(true);if(!u.collapsed){if(C(u.endContainer,u.endOffset-1)){u.setEnd(u.endContainer,u.endOffset-1);w.setRng(u)}if(C(u.startContainer,u.startOffset)){u.setStart(u.startContainer,u.startOffset+1);w.setRng(u)}}if(tinymce.isIE8){var G=F.ed.selection.getNode();if(G.tagName==="LI"&&!(G.parentNode.lastChild===G)){var A=F.ed.getDoc().createTextNode("\uFEFF");G.appendChild(A)}}g=w.getBookmark();y.OL=y.UL=v;F.splitSafeEach(E,x);w.moveToBookmark(g);g=null;if(!D()){F.ed.execCommand("mceRepaint")}},splitSafeEach:function(t,s){if(tinymce.isGecko&&(/Firefox\/[12]\.[0-9]/.test(navigator.userAgent)||/Firefox\/3\.[0-4]/.test(navigator.userAgent))){this.classBasedEach(t,s)}else{e(t,s)}},classBasedEach:function(v,u){var w=this.ed.dom,s,t;e(v,function(x){w.addClass(x,"_mce_act_on")});s=w.select("._mce_act_on");while(s.length>0){t=s.shift();w.removeClass(t,"_mce_act_on");u(t);s=w.select("._mce_act_on")}},adjustPaddingFunction:function(u){var s,v,t=this.ed;s=t.settings.indentation;v=/[a-z%]+/i.exec(s);s=parseInt(s,10);return function(w){var y,x;y=parseInt(t.dom.getStyle(w,"margin-left")||0,10)+parseInt(t.dom.getStyle(w,"padding-left")||0,10);if(u){x=y+s}else{x=y-s}t.dom.setStyle(w,"padding-left","");t.dom.setStyle(w,"margin-left",x>0?x+v:"")}},selectedBlocks:function(){var s=this.ed;var t=s.selection.getSelectedBlocks();return t.length==0?[s.dom.getRoot()]:t},getInfo:function(){return{longname:"Lists",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("lists",tinymce.plugins.Lists)}());
1
+ (function(){var e=tinymce.each,r=tinymce.dom.Event,g;function p(t,s){while(t&&(t.nodeType===8||(t.nodeType===3&&/^[ \t\n\r]*$/.test(t.nodeValue)))){t=s(t)}return t}function b(s){return p(s,function(t){return t.previousSibling})}function i(s){return p(s,function(t){return t.nextSibling})}function d(s,u,t){return s.dom.getParent(u,function(v){return tinymce.inArray(t,v)!==-1})}function n(s){return s&&(s.tagName==="OL"||s.tagName==="UL")}function c(u,v){var t,w,s;t=b(u.lastChild);while(n(t)){w=t;t=b(w.previousSibling)}if(w){s=v.create("li",{style:"list-style-type: none;"});v.split(u,w);v.insertAfter(s,w);s.appendChild(w);s.appendChild(w);u=s.previousSibling}return u}function m(t,s,u){t=a(t,s,u);return o(t,s,u)}function a(u,s,v){var t=b(u.previousSibling);if(t){return h(t,u,s?t:false,v)}else{return u}}function o(u,t,v){var s=i(u.nextSibling);if(s){return h(u,s,t?s:false,v)}else{return u}}function h(u,s,t,v){if(l(u,s,!!t,v)){return f(u,s,t)}else{if(u&&u.tagName==="LI"&&n(s)){u.appendChild(s)}}return s}function l(u,t,s,v){if(!u||!t){return false}else{if(u.tagName==="LI"&&t.tagName==="LI"){return t.style.listStyleType==="none"||j(t)}else{if(n(u)){return(u.tagName===t.tagName&&(s||u.style.listStyleType===t.style.listStyleType))||q(t)}else{return v&&u.tagName==="P"&&t.tagName==="P"}}}}function q(t){var s=i(t.firstChild),u=b(t.lastChild);return s&&u&&n(t)&&s===u&&(n(s)||s.style.listStyleType==="none"||j(s))}function j(u){var t=i(u.firstChild),s=b(u.lastChild);return t&&s&&t===s&&n(t)}function f(w,v,s){var u=b(w.lastChild),t=i(v.firstChild);if(w.tagName==="P"){w.appendChild(w.ownerDocument.createElement("br"))}while(v.firstChild){w.appendChild(v.firstChild)}if(s){w.style.listStyleType=s.style.listStyleType}v.parentNode.removeChild(v);h(u,t,false);return w}function k(t,u){var s;if(!u.is(t,"li,ol,ul")){s=u.getParent(t,"li");if(s){t=s}}return t}tinymce.create("tinymce.plugins.Lists",{init:function(y){var v="TABBING";var s="EMPTY";var J="ESCAPE";var z="PARAGRAPH";var N="UNKNOWN";var x=N;function E(U){return U.keyCode===tinymce.VK.TAB&&!(U.altKey||U.ctrlKey)&&(y.queryCommandState("InsertUnorderedList")||y.queryCommandState("InsertOrderedList"))}function w(){var U=B();var W=U.parentNode.parentNode;var V=U.parentNode.lastChild===U;return V&&!t(W)&&P(U)}function t(U){if(n(U)){return U.parentNode&&U.parentNode.tagName==="LI"}else{return U.tagName==="LI"}}function F(){return y.selection.isCollapsed()&&P(B())}function B(){var U=y.selection.getStart();return((U.tagName=="BR"||U.tagName=="")&&U.parentNode.tagName=="LI")?U.parentNode:U}function P(U){var V=U.childNodes.length;if(U.tagName==="LI"){return V==0?true:V==1&&(U.firstChild.tagName==""||U.firstChild.tagName=="BR"||H(U))}return false}function H(U){var V=tinymce.grep(U.parentNode.childNodes,function(Y){return Y.tagName=="LI"});var W=U==V[V.length-1];var X=U.firstChild;return tinymce.isIE9&&W&&(X.nodeValue==String.fromCharCode(160)||X.nodeValue==String.fromCharCode(32))}function T(U){return U.keyCode===tinymce.VK.ENTER}function A(U){return T(U)&&!U.shiftKey}function M(U){if(E(U)){return v}else{if(A(U)&&w()){return N}else{if(A(U)&&F()){return s}else{return N}}}}function D(U,V){if(x==v||x==s||tinymce.isGecko&&x==J){r.cancel(V)}}function C(){var U=y.selection.getRng(true);var V=U.startContainer;if(V.nodeType==3){var W=V.nodeValue;if(tinymce.isIE9&&W.length>1&&W.charCodeAt(W.length-1)==32){return(U.endOffset==W.length-1)}else{return(U.endOffset==W.length)}}else{if(V.nodeType==1){return U.endOffset==V.childNodes.length}}return false}function I(){var W=y.selection.getNode();var V="h1,h2,h3,h4,h5,h6,p,div";var U=y.dom.is(W,V)&&W.parentNode.tagName==="LI"&&W.parentNode.lastChild===W;return y.selection.isCollapsed()&&U&&C()}function K(W,Y){if(A(Y)&&I()){var X=W.selection.getNode();var V=W.dom.create("li");var U=W.dom.getParent(X,"li");W.dom.insertAfter(V,U);if(tinymce.isIE6||tinymce.isIE7||tinyMCE.isIE8){W.selection.setCursorLocation(V,1)}else{W.selection.setCursorLocation(V,0)}Y.preventDefault()}}function u(X,Z){var ac;if(!tinymce.isGecko){return}var V=X.selection.getStart();if(Z.keyCode!=tinymce.VK.BACKSPACE||V.tagName!=="IMG"){return}function W(ag){var ah=ag.firstChild;var af=null;do{if(!ah){break}if(ah.tagName==="LI"){af=ah}}while(ah=ah.nextSibling);return af}function ae(ag,af){while(ag.childNodes.length>0){af.appendChild(ag.childNodes[0])}}ac=V.parentNode.previousSibling;if(!ac){return}var aa;if(ac.tagName==="UL"||ac.tagName==="OL"){aa=ac}else{if(ac.previousSibling&&(ac.previousSibling.tagName==="UL"||ac.previousSibling.tagName==="OL")){aa=ac.previousSibling}else{return}}var ad=W(aa);var U=X.dom.createRng();U.setStart(ad,1);U.setEnd(ad,1);X.selection.setRng(U);X.selection.collapse(true);var Y=X.selection.getBookmark();var ab=V.parentNode.cloneNode(true);if(ab.tagName==="P"||ab.tagName==="DIV"){ae(ab,ad)}else{ad.appendChild(ab)}V.parentNode.parentNode.removeChild(V.parentNode);X.selection.moveToBookmark(Y)}function G(U){var V=y.dom.getParent(U,"ol,ul");if(V!=null){var W=V.lastChild;y.selection.setCursorLocation(W,0)}}this.ed=y;y.addCommand("Indent",this.indent,this);y.addCommand("Outdent",this.outdent,this);y.addCommand("InsertUnorderedList",function(){this.applyList("UL","OL")},this);y.addCommand("InsertOrderedList",function(){this.applyList("OL","UL")},this);y.onInit.add(function(){y.editorCommands.addCommands({outdent:function(){var V=y.selection,W=y.dom;function U(X){X=W.getParent(X,W.isBlock);return X&&(parseInt(y.dom.getStyle(X,"margin-left")||0,10)+parseInt(y.dom.getStyle(X,"padding-left")||0,10))>0}return U(V.getStart())||U(V.getEnd())||y.queryCommandState("InsertOrderedList")||y.queryCommandState("InsertUnorderedList")}},"state")});y.onKeyUp.add(function(V,W){if(x==v){V.execCommand(W.shiftKey?"Outdent":"Indent",true,null);x=N;return r.cancel(W)}else{if(x==s){var U=B();var Y=V.settings.list_outdent_on_enter===true||W.shiftKey;V.execCommand(Y?"Outdent":"Indent",true,null);if(tinymce.isIE){G(U)}return r.cancel(W)}else{if(x==J){if(tinymce.isIE6||tinymce.isIE7||tinymce.isIE8){var X=V.getDoc().createTextNode("\uFEFF");V.selection.getNode().appendChild(X)}else{if(tinymce.isIE9||tinymce.isGecko){V.execCommand("Outdent");return r.cancel(W)}}}}}});function L(V,U){var W=y.getDoc().createTextNode("\uFEFF");V.insertBefore(W,U);y.selection.setCursorLocation(W,0);y.execCommand("mceRepaint")}function R(V,X){if(T(X)){var U=B();if(U){var W=U.parentNode;var Y=W&&W.parentNode;if(Y&&Y.nodeName=="LI"&&Y.firstChild==W&&U==W.firstChild){L(Y,W)}}}}function S(V,X){if(T(X)){var U=B();if(V.dom.select("ul li",U).length===1){var W=U.firstChild;L(U,W)}}}function Q(V,Z){function W(ad,aa){var ac=[];var ae=new tinymce.dom.TreeWalker(aa,ad);for(var ab=ae.current();ab;ab=ae.next()){if(V.dom.is(ab,"ol,ul,li")){ac.push(ab)}}return ac}if(Z.keyCode==tinymce.VK.BACKSPACE){var U=B();if(U){var Y=V.dom.getParent(U,"ol,ul");if(Y&&Y.firstChild===U){var X=W(Y,U);V.execCommand("Outdent",false,X);V.undoManager.add();return r.cancel(Z)}}}}function O(V,X){var U=B();if(X.keyCode===tinymce.VK.BACKSPACE&&V.dom.is(U,"li")&&U.parentNode.firstChild!==U){if(V.dom.select("ul,ol",U).length===1){var Z=U.previousSibling;V.dom.remove(V.dom.select("br",U));V.dom.remove(U,true);var W=tinymce.grep(Z.childNodes,function(aa){return aa.nodeType===3});if(W.length===1){var Y=W[0];V.selection.setCursorLocation(Y,Y.length)}V.undoManager.add();return r.cancel(X)}}}y.onKeyDown.add(function(U,V){x=M(V)});y.onKeyDown.add(D);y.onKeyDown.add(u);y.onKeyDown.add(K);if(tinymce.isGecko){y.onKeyUp.add(R)}if(tinymce.isIE8){y.onKeyUp.add(S)}if(tinymce.isGecko||tinymce.isWebKit){y.onKeyDown.add(Q)}if(tinymce.isWebKit){y.onKeyDown.add(O)}},applyList:function(y,v){var C=this,z=C.ed,I=z.dom,s=[],H=false,u=false,w=false,B,G=z.selection.getSelectedBlocks();function E(t){if(t&&t.tagName==="BR"){I.remove(t)}}function F(M){var N=I.create(y),t;function L(O){if(O.style.marginLeft||O.style.paddingLeft){C.adjustPaddingFunction(false)(O)}}if(M.tagName==="LI"){}else{if(M.tagName==="P"||M.tagName==="DIV"||M.tagName==="BODY"){K(M,function(P,O){J(P,O,M.tagName==="BODY"?null:P.parentNode);t=P.parentNode;L(t);E(O)});if(t){if(t.tagName==="LI"&&(M.tagName==="P"||G.length>1)){I.split(t.parentNode.parentNode,t.parentNode)}m(t.parentNode,true)}return}else{t=I.create("li");I.insertAfter(t,M);t.appendChild(M);L(M);M=t}}I.insertAfter(N,M);N.appendChild(M);m(N,true);s.push(M)}function J(P,L,N){var t,O=P,M;while(!I.isBlock(P.parentNode)&&P.parentNode!==I.getRoot()){P=I.split(P.parentNode,P.previousSibling);P=P.nextSibling;O=P}if(N){t=N.cloneNode(true);P.parentNode.insertBefore(t,P);while(t.firstChild){I.remove(t.firstChild)}t=I.rename(t,"li")}else{t=I.create("li");P.parentNode.insertBefore(t,P)}while(O&&O!=L){M=O.nextSibling;t.appendChild(O);O=M}if(t.childNodes.length===0){t.innerHTML='<br _mce_bogus="1" />'}F(t)}function K(Q,T){var N,R,O=3,L=1,t="br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl";function P(X,U){var V=I.createRng(),W;g.keep=true;z.selection.moveToBookmark(g);g.keep=false;W=z.selection.getRng(true);if(!U){U=X.parentNode.lastChild}V.setStartBefore(X);V.setEndAfter(U);return !(V.compareBoundaryPoints(O,W)>0||V.compareBoundaryPoints(L,W)<=0)}function S(U){if(U.nextSibling){return U.nextSibling}if(!I.isBlock(U.parentNode)&&U.parentNode!==I.getRoot()){return S(U.parentNode)}}N=Q.firstChild;var M=false;e(I.select(t,Q),function(U){if(U.hasAttribute&&U.hasAttribute("_mce_bogus")){return true}if(P(N,U)){I.addClass(U,"_mce_tagged_br");N=S(U)}});M=(N&&P(N,undefined));N=Q.firstChild;e(I.select(t,Q),function(V){var U=S(V);if(V.hasAttribute&&V.hasAttribute("_mce_bogus")){return true}if(I.hasClass(V,"_mce_tagged_br")){T(N,V,R);R=null}else{R=V}N=U});if(M){T(N,undefined,R)}}function D(t){K(t,function(M,L,N){J(M,L);E(L);E(N)})}function A(t){if(tinymce.inArray(s,t)!==-1){return}if(t.parentNode.tagName===v){I.split(t.parentNode,t);F(t);o(t.parentNode,false)}s.push(t)}function x(M){var O,N,L,t;if(tinymce.inArray(s,M)!==-1){return}M=c(M,I);while(I.is(M.parentNode,"ol,ul,li")){I.split(M.parentNode,M)}s.push(M);M=I.rename(M,"p");L=m(M,false,z.settings.force_br_newlines);if(L===M){O=M.firstChild;while(O){if(I.isBlock(O)){O=I.split(O.parentNode,O);t=true;N=O.nextSibling&&O.nextSibling.firstChild}else{N=O.nextSibling;if(t&&O.tagName==="BR"){I.remove(O)}t=false}O=N}}}e(G,function(t){t=k(t,I);if(t.tagName===v||(t.tagName==="LI"&&t.parentNode.tagName===v)){u=true}else{if(t.tagName===y||(t.tagName==="LI"&&t.parentNode.tagName===y)){H=true}else{w=true}}});if(w&&!H||u||G.length===0){B={LI:A,H1:F,H2:F,H3:F,H4:F,H5:F,H6:F,P:F,BODY:F,DIV:G.length>1?F:D,defaultAction:D,elements:this.selectedBlocks()}}else{B={defaultAction:x,elements:this.selectedBlocks(),processEvenIfEmpty:true}}this.process(B)},indent:function(){var u=this.ed,w=u.dom,x=[];function s(z){var y=w.create("li",{style:"list-style-type: none;"});w.insertAfter(y,z);return y}function t(B){var y=s(B),D=w.getParent(B,"ol,ul"),C=D.tagName,E=w.getStyle(D,"list-style-type"),A={},z;if(E!==""){A.style="list-style-type: "+E+";"}z=w.create(C,A);y.appendChild(z);return z}function v(z){if(!d(u,z,x)){z=c(z,w);var y=t(z);y.appendChild(z);m(y.parentNode,false);m(y,false);x.push(z)}}this.process({LI:v,defaultAction:this.adjustPaddingFunction(true),elements:this.selectedBlocks()})},outdent:function(y,x){var w=this,u=w.ed,z=u.dom,s=[];function A(t){var C,B,D;if(!d(u,t,s)){if(z.getStyle(t,"margin-left")!==""||z.getStyle(t,"padding-left")!==""){return w.adjustPaddingFunction(false)(t)}D=z.getStyle(t,"text-align",true);if(D==="center"||D==="right"){z.setStyle(t,"text-align","left");return}t=c(t,z);C=t.parentNode;B=t.parentNode.parentNode;if(B.tagName==="P"){z.split(B,t.parentNode)}else{z.split(C,t);if(B.tagName==="LI"){z.split(B,t)}else{if(!z.is(B,"ol,ul")){z.rename(t,"p")}}}s.push(t)}}var v=x&&tinymce.is(x,"array")?x:this.selectedBlocks();this.process({LI:A,defaultAction:this.adjustPaddingFunction(false),elements:v});e(s,m)},process:function(y){var F=this,w=F.ed.selection,z=F.ed.dom,E,u;function B(t){var s=tinymce.grep(t.childNodes,function(H){return !(H.nodeName==="BR"||H.nodeName==="SPAN"&&z.getAttrib(H,"data-mce-type")=="bookmark"||H.nodeType==3&&(H.nodeValue==String.fromCharCode(160)||H.nodeValue==""))});return s.length===0}function x(s){z.removeClass(s,"_mce_act_on");if(!s||s.nodeType!==1||!y.processEvenIfEmpty&&E.length>1&&B(s)){return}s=k(s,z);var t=y[s.tagName];if(!t){t=y.defaultAction}t(s)}function v(s){F.splitSafeEach(s.childNodes,x)}function C(s,t){return t>=0&&s.hasChildNodes()&&t<s.childNodes.length&&s.childNodes[t].tagName==="BR"}function D(){var t=w.getNode();var s=z.getParent(t,"td");return s!==null}E=y.elements;u=w.getRng(true);if(!u.collapsed){if(C(u.endContainer,u.endOffset-1)){u.setEnd(u.endContainer,u.endOffset-1);w.setRng(u)}if(C(u.startContainer,u.startOffset)){u.setStart(u.startContainer,u.startOffset+1);w.setRng(u)}}if(tinymce.isIE8){var G=F.ed.selection.getNode();if(G.tagName==="LI"&&!(G.parentNode.lastChild===G)){var A=F.ed.getDoc().createTextNode("\uFEFF");G.appendChild(A)}}g=w.getBookmark();y.OL=y.UL=v;F.splitSafeEach(E,x);w.moveToBookmark(g);g=null;if(!D()){F.ed.execCommand("mceRepaint")}},splitSafeEach:function(t,s){if(tinymce.isGecko&&(/Firefox\/[12]\.[0-9]/.test(navigator.userAgent)||/Firefox\/3\.[0-4]/.test(navigator.userAgent))){this.classBasedEach(t,s)}else{e(t,s)}},classBasedEach:function(v,u){var w=this.ed.dom,s,t;e(v,function(x){w.addClass(x,"_mce_act_on")});s=w.select("._mce_act_on");while(s.length>0){t=s.shift();w.removeClass(t,"_mce_act_on");u(t);s=w.select("._mce_act_on")}},adjustPaddingFunction:function(u){var s,v,t=this.ed;s=t.settings.indentation;v=/[a-z%]+/i.exec(s);s=parseInt(s,10);return function(w){var y,x;y=parseInt(t.dom.getStyle(w,"margin-left")||0,10)+parseInt(t.dom.getStyle(w,"padding-left")||0,10);if(u){x=y+s}else{x=y-s}t.dom.setStyle(w,"padding-left","");t.dom.setStyle(w,"margin-left",x>0?x+v:"")}},selectedBlocks:function(){var s=this.ed;var t=s.selection.getSelectedBlocks();return t.length==0?[s.dom.getRoot()]:t},getInfo:function(){return{longname:"Lists",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("lists",tinymce.plugins.Lists)}());
@@ -1,951 +1,952 @@
1
- /**
2
- * editor_plugin_src.js
3
- *
4
- * Copyright 2011, Moxiecode Systems AB
5
- * Released under LGPL License.
6
- *
7
- * License: http://tinymce.moxiecode.com/license
8
- * Contributing: http://tinymce.moxiecode.com/contributing
9
- */
10
-
11
- (function() {
12
- var each = tinymce.each, Event = tinymce.dom.Event, bookmark;
13
-
14
- // Skips text nodes that only contain whitespace since they aren't semantically important.
15
- function skipWhitespaceNodes(e, next) {
16
- while (e && (e.nodeType === 8 || (e.nodeType === 3 && /^[ \t\n\r]*$/.test(e.nodeValue)))) {
17
- e = next(e);
18
- }
19
- return e;
20
- }
21
-
22
- function skipWhitespaceNodesBackwards(e) {
23
- return skipWhitespaceNodes(e, function(e) {
24
- return e.previousSibling;
25
- });
26
- }
27
-
28
- function skipWhitespaceNodesForwards(e) {
29
- return skipWhitespaceNodes(e, function(e) {
30
- return e.nextSibling;
31
- });
32
- }
33
-
34
- function hasParentInList(ed, e, list) {
35
- return ed.dom.getParent(e, function(p) {
36
- return tinymce.inArray(list, p) !== -1;
37
- });
38
- }
39
-
40
- function isList(e) {
41
- return e && (e.tagName === 'OL' || e.tagName === 'UL');
42
- }
43
-
44
- function splitNestedLists(element, dom) {
45
- var tmp, nested, wrapItem;
46
- tmp = skipWhitespaceNodesBackwards(element.lastChild);
47
- while (isList(tmp)) {
48
- nested = tmp;
49
- tmp = skipWhitespaceNodesBackwards(nested.previousSibling);
50
- }
51
- if (nested) {
52
- wrapItem = dom.create('li', { style: 'list-style-type: none;'});
53
- dom.split(element, nested);
54
- dom.insertAfter(wrapItem, nested);
55
- wrapItem.appendChild(nested);
56
- wrapItem.appendChild(nested);
57
- element = wrapItem.previousSibling;
58
- }
59
- return element;
60
- }
61
-
62
- function attemptMergeWithAdjacent(e, allowDifferentListStyles, mergeParagraphs) {
63
- e = attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs);
64
- return attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs);
65
- }
66
-
67
- function attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs) {
68
- var prev = skipWhitespaceNodesBackwards(e.previousSibling);
69
- if (prev) {
70
- return attemptMerge(prev, e, allowDifferentListStyles ? prev : false, mergeParagraphs);
71
- } else {
72
- return e;
73
- }
74
- }
75
-
76
- function attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs) {
77
- var next = skipWhitespaceNodesForwards(e.nextSibling);
78
- if (next) {
79
- return attemptMerge(e, next, allowDifferentListStyles ? next : false, mergeParagraphs);
80
- } else {
81
- return e;
82
- }
83
- }
84
-
85
- function attemptMerge(e1, e2, differentStylesMasterElement, mergeParagraphs) {
86
- if (canMerge(e1, e2, !!differentStylesMasterElement, mergeParagraphs)) {
87
- return merge(e1, e2, differentStylesMasterElement);
88
- } else if (e1 && e1.tagName === 'LI' && isList(e2)) {
89
- // Fix invalidly nested lists.
90
- e1.appendChild(e2);
91
- }
92
- return e2;
93
- }
94
-
95
- function canMerge(e1, e2, allowDifferentListStyles, mergeParagraphs) {
96
- if (!e1 || !e2) {
97
- return false;
98
- } else if (e1.tagName === 'LI' && e2.tagName === 'LI') {
99
- return e2.style.listStyleType === 'none' || containsOnlyAList(e2);
100
- } else if (isList(e1)) {
101
- return (e1.tagName === e2.tagName && (allowDifferentListStyles || e1.style.listStyleType === e2.style.listStyleType)) || isListForIndent(e2);
102
- } else return mergeParagraphs && e1.tagName === 'P' && e2.tagName === 'P';
103
- }
104
-
105
- function isListForIndent(e) {
106
- var firstLI = skipWhitespaceNodesForwards(e.firstChild), lastLI = skipWhitespaceNodesBackwards(e.lastChild);
107
- return firstLI && lastLI && isList(e) && firstLI === lastLI && (isList(firstLI) || firstLI.style.listStyleType === 'none' || containsOnlyAList(firstLI));
108
- }
109
-
110
- function containsOnlyAList(e) {
111
- var firstChild = skipWhitespaceNodesForwards(e.firstChild), lastChild = skipWhitespaceNodesBackwards(e.lastChild);
112
- return firstChild && lastChild && firstChild === lastChild && isList(firstChild);
113
- }
114
-
115
- function merge(e1, e2, masterElement) {
116
- var lastOriginal = skipWhitespaceNodesBackwards(e1.lastChild), firstNew = skipWhitespaceNodesForwards(e2.firstChild);
117
- if (e1.tagName === 'P') {
118
- e1.appendChild(e1.ownerDocument.createElement('br'));
119
- }
120
- while (e2.firstChild) {
121
- e1.appendChild(e2.firstChild);
122
- }
123
- if (masterElement) {
124
- e1.style.listStyleType = masterElement.style.listStyleType;
125
- }
126
- e2.parentNode.removeChild(e2);
127
- attemptMerge(lastOriginal, firstNew, false);
128
- return e1;
129
- }
130
-
131
- function findItemToOperateOn(e, dom) {
132
- var item;
133
- if (!dom.is(e, 'li,ol,ul')) {
134
- item = dom.getParent(e, 'li');
135
- if (item) {
136
- e = item;
137
- }
138
- }
139
- return e;
140
- }
141
-
142
- tinymce.create('tinymce.plugins.Lists', {
143
- init: function(ed) {
144
- var LIST_TABBING = 'TABBING';
145
- var LIST_EMPTY_ITEM = 'EMPTY';
146
- var LIST_ESCAPE = 'ESCAPE';
147
- var LIST_PARAGRAPH = 'PARAGRAPH';
148
- var LIST_UNKNOWN = 'UNKNOWN';
149
- var state = LIST_UNKNOWN;
150
-
151
- function isTabInList(e) {
152
- // Don't indent on Ctrl+Tab or Alt+Tab
153
- return e.keyCode === tinymce.VK.TAB && !(e.altKey || e.ctrlKey) &&
154
- (ed.queryCommandState('InsertUnorderedList') || ed.queryCommandState('InsertOrderedList'));
155
- }
156
-
157
- function isOnLastListItem() {
158
- var li = getLi();
159
- var grandParent = li.parentNode.parentNode;
160
- var isLastItem = li.parentNode.lastChild === li;
161
- return isLastItem && !isNestedList(grandParent) && isEmptyListItem(li);
162
- }
163
-
164
- function isNestedList(grandParent) {
165
- if (isList(grandParent)) {
166
- return grandParent.parentNode && grandParent.parentNode.tagName === 'LI';
167
- } else {
168
- return grandParent.tagName === 'LI';
169
- }
170
- }
171
-
172
- function isInEmptyListItem() {
173
- return ed.selection.isCollapsed() && isEmptyListItem(getLi());
174
- }
175
-
176
- function getLi() {
177
- var n = ed.selection.getStart();
178
- // Get start will return BR if the LI only contains a BR or an empty element as we use these to fix caret position
179
- return ((n.tagName == 'BR' || n.tagName == '') && n.parentNode.tagName == 'LI') ? n.parentNode : n;
180
- }
181
-
182
- function isEmptyListItem(li) {
183
- var numChildren = li.childNodes.length;
184
- if (li.tagName === 'LI') {
185
- return numChildren == 0 ? true : numChildren == 1 && (li.firstChild.tagName == '' || li.firstChild.tagName == 'BR' || isEmptyIE9Li(li));
186
- }
187
- return false;
188
- }
189
-
190
- function isEmptyIE9Li(li) {
191
- // only consider this to be last item if there is no list item content or that content is nbsp or space since IE9 creates these
192
- var lis = tinymce.grep(li.parentNode.childNodes, function(n) {return n.tagName == 'LI'});
193
- var isLastLi = li == lis[lis.length - 1];
194
- var child = li.firstChild;
195
- return tinymce.isIE9 && isLastLi && (child.nodeValue == String.fromCharCode(160) || child.nodeValue == String.fromCharCode(32));
196
- }
197
-
198
- function isEnter(e) {
199
- return e.keyCode === tinymce.VK.ENTER;
200
- }
201
-
202
- function isEnterWithoutShift(e) {
203
- return isEnter(e) && !e.shiftKey;
204
- }
205
-
206
- function getListKeyState(e) {
207
- if (isTabInList(e)) {
208
- return LIST_TABBING;
209
- } else if (isEnterWithoutShift(e) && isOnLastListItem()) {
210
- // Returns LIST_UNKNOWN since breaking out of lists is handled by the EnterKey.js logic now
211
- //return LIST_ESCAPE;
212
- return LIST_UNKNOWN;
213
- } else if (isEnterWithoutShift(e) && isInEmptyListItem()) {
214
- return LIST_EMPTY_ITEM;
215
- } else {
216
- return LIST_UNKNOWN;
217
- }
218
- }
219
-
220
- function cancelDefaultEvents(ed, e) {
221
- // list escape is done manually using outdent as it does not create paragraphs correctly in td's
222
- if (state == LIST_TABBING || state == LIST_EMPTY_ITEM || tinymce.isGecko && state == LIST_ESCAPE) {
223
- Event.cancel(e);
224
- }
225
- }
226
-
227
- function isCursorAtEndOfContainer() {
228
- var range = ed.selection.getRng(true);
229
- var startContainer = range.startContainer;
230
- if (startContainer.nodeType == 3) {
231
- var value = startContainer.nodeValue;
232
- if (tinymce.isIE9 && value.length > 1 && value.charCodeAt(value.length-1) == 32) {
233
- // IE9 places a space on the end of the text in some cases so ignore last char
234
- return (range.endOffset == value.length-1);
235
- } else {
236
- return (range.endOffset == value.length);
237
- }
238
- } else if (startContainer.nodeType == 1) {
239
- return range.endOffset == startContainer.childNodes.length;
240
- }
241
- return false;
242
- }
243
-
244
- /*
245
- If we are at the end of a list item surrounded with an element, pressing enter should create a
246
- new list item instead without splitting the element e.g. don't want to create new P or H1 tag
247
- */
248
- function isEndOfListItem() {
249
- var node = ed.selection.getNode();
250
- var validElements = 'h1,h2,h3,h4,h5,h6,p,div';
251
- var isLastParagraphOfLi = ed.dom.is(node, validElements) && node.parentNode.tagName === 'LI' && node.parentNode.lastChild === node;
252
- return ed.selection.isCollapsed() && isLastParagraphOfLi && isCursorAtEndOfContainer();
253
- }
254
-
255
- // Creates a new list item after the current selection's list item parent
256
- function createNewLi(ed, e) {
257
- if (isEnterWithoutShift(e) && isEndOfListItem()) {
258
- var node = ed.selection.getNode();
259
- var li = ed.dom.create("li");
260
- var parentLi = ed.dom.getParent(node, 'li');
261
- ed.dom.insertAfter(li, parentLi);
262
-
263
- // Move caret to new list element.
264
- if (tinymce.isIE6 || tinymce.isIE7 || tinyMCE.isIE8) {
265
- // Removed this line since it would create an odd <&nbsp;> tag and placing the caret inside an empty LI is handled and should be handled by the selection logic
266
- //li.appendChild(ed.dom.create("&nbsp;")); // IE needs an element within the bullet point
267
- ed.selection.setCursorLocation(li, 1);
268
- } else {
269
- ed.selection.setCursorLocation(li, 0);
270
- }
271
- e.preventDefault();
272
- }
273
- }
274
-
275
- function imageJoiningListItem(ed, e) {
276
- var prevSibling;
277
-
278
- if (!tinymce.isGecko)
279
- return;
280
-
281
- var n = ed.selection.getStart();
282
- if (e.keyCode != tinymce.VK.BACKSPACE || n.tagName !== 'IMG')
283
- return;
284
-
285
- function lastLI(node) {
286
- var child = node.firstChild;
287
- var li = null;
288
- do {
289
- if (!child)
290
- break;
291
-
292
- if (child.tagName === 'LI')
293
- li = child;
294
- } while (child = child.nextSibling);
295
-
296
- return li;
297
- }
298
-
299
- function addChildren(parentNode, destination) {
300
- while (parentNode.childNodes.length > 0)
301
- destination.appendChild(parentNode.childNodes[0]);
302
- }
303
-
304
- // Check if there is a previous sibling
305
- prevSibling = n.parentNode.previousSibling;
306
- if (!prevSibling)
307
- return;
308
-
309
- var ul;
310
- if (prevSibling.tagName === 'UL' || prevSibling.tagName === 'OL')
311
- ul = prevSibling;
312
- else if (prevSibling.previousSibling && (prevSibling.previousSibling.tagName === 'UL' || prevSibling.previousSibling.tagName === 'OL'))
313
- ul = prevSibling.previousSibling;
314
- else
315
- return;
316
-
317
- var li = lastLI(ul);
318
-
319
- // move the caret to the end of the list item
320
- var rng = ed.dom.createRng();
321
- rng.setStart(li, 1);
322
- rng.setEnd(li, 1);
323
- ed.selection.setRng(rng);
324
- ed.selection.collapse(true);
325
-
326
- // save a bookmark at the end of the list item
327
- var bookmark = ed.selection.getBookmark();
328
-
329
- // copy the image an its text to the list item
330
- var clone = n.parentNode.cloneNode(true);
331
- if (clone.tagName === 'P' || clone.tagName === 'DIV')
332
- addChildren(clone, li);
333
- else
334
- li.appendChild(clone);
335
-
336
- // remove the old copy of the image
337
- n.parentNode.parentNode.removeChild(n.parentNode);
338
-
339
- // move the caret where we saved the bookmark
340
- ed.selection.moveToBookmark(bookmark);
341
- }
342
-
343
- // fix the cursor position to ensure it is correct in IE
344
- function setCursorPositionToOriginalLi(li) {
345
- var list = ed.dom.getParent(li, 'ol,ul');
346
- if (list != null) {
347
- var lastLi = list.lastChild;
348
- // Removed this line since IE9 would report an DOM character error and placing the caret inside an empty LI is handled and should be handled by the selection logic
349
- //lastLi.appendChild(ed.getDoc().createElement(''));
350
- ed.selection.setCursorLocation(lastLi, 0);
351
- }
352
- }
353
-
354
- this.ed = ed;
355
- ed.addCommand('Indent', this.indent, this);
356
- ed.addCommand('Outdent', this.outdent, this);
357
- ed.addCommand('InsertUnorderedList', function() {
358
- this.applyList('UL', 'OL');
359
- }, this);
360
- ed.addCommand('InsertOrderedList', function() {
361
- this.applyList('OL', 'UL');
362
- }, this);
363
-
364
- ed.onInit.add(function() {
365
- ed.editorCommands.addCommands({
366
- 'outdent': function() {
367
- var sel = ed.selection, dom = ed.dom;
368
-
369
- function hasStyleIndent(n) {
370
- n = dom.getParent(n, dom.isBlock);
371
- return n && (parseInt(ed.dom.getStyle(n, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(n, 'padding-left') || 0, 10)) > 0;
372
- }
373
-
374
- return hasStyleIndent(sel.getStart()) || hasStyleIndent(sel.getEnd()) || ed.queryCommandState('InsertOrderedList') || ed.queryCommandState('InsertUnorderedList');
375
- }
376
- }, 'state');
377
- });
378
-
379
- ed.onKeyUp.add(function(ed, e) {
380
- if (state == LIST_TABBING) {
381
- ed.execCommand(e.shiftKey ? 'Outdent' : 'Indent', true, null);
382
- state = LIST_UNKNOWN;
383
- return Event.cancel(e);
384
- } else if (state == LIST_EMPTY_ITEM) {
385
- var li = getLi();
386
- var shouldOutdent = ed.settings.list_outdent_on_enter === true || e.shiftKey;
387
- ed.execCommand(shouldOutdent ? 'Outdent' : 'Indent', true, null);
388
- if (tinymce.isIE) {
389
- setCursorPositionToOriginalLi(li);
390
- }
391
-
392
- return Event.cancel(e);
393
- } else if (state == LIST_ESCAPE) {
394
- if (tinymce.isIE6 || tinymce.isIE7 || tinymce.isIE8) {
395
- // append a zero sized nbsp so that caret is positioned correctly in IE after escaping and applying formatting.
396
- // if there is no text then applying formatting for e.g a H1 to the P tag immediately following list after
397
- // escaping from it will cause the caret to be positioned on the last li instead of staying the in P tag.
398
- var n = ed.getDoc().createTextNode('\uFEFF');
399
- ed.selection.getNode().appendChild(n);
400
- } else if (tinymce.isIE9 || tinymce.isGecko) {
401
- // IE9 does not escape the list so we use outdent to do this and cancel the default behaviour
402
- // Gecko does not create a paragraph outdenting inside a TD so default behaviour is cancelled and we outdent ourselves
403
- ed.execCommand('Outdent');
404
- return Event.cancel(e);
405
- }
406
- }
407
- });
408
-
409
- function fixListItem(parent, reference) {
410
- // a zero-sized non-breaking space is placed in the empty list item so that the nested list is
411
- // displayed on the below line instead of next to it
412
- var n = ed.getDoc().createTextNode('\uFEFF');
413
- parent.insertBefore(n, reference);
414
- ed.selection.setCursorLocation(n, 0);
415
- // repaint to remove rendering artifact. only visible when creating new list
416
- ed.execCommand('mceRepaint');
417
- }
418
-
419
- function fixIndentedListItemForGecko(ed, e) {
420
- if (isEnter(e)) {
421
- var li = getLi();
422
- if (li) {
423
- var parent = li.parentNode;
424
- var grandParent = parent && parent.parentNode;
425
- if (grandParent && grandParent.nodeName == 'LI' && grandParent.firstChild == parent && li == parent.firstChild) {
426
- fixListItem(grandParent, parent);
427
- }
428
- }
429
- }
430
- }
431
-
432
- function fixIndentedListItemForIE8(ed, e) {
433
- if (isEnter(e)) {
434
- var li = getLi();
435
- if (ed.dom.select('ul li', li).length === 1) {
436
- var list = li.firstChild;
437
- fixListItem(li, list);
438
- }
439
- }
440
- }
441
-
442
- function fixDeletingFirstCharOfList(ed, e) {
443
- function listElements(list, li) {
444
- var elements = [];
445
- var walker = new tinymce.dom.TreeWalker(li, list);
446
- for (var node = walker.current(); node; node = walker.next()) {
447
- if (ed.dom.is(node, 'ol,ul,li')) {
448
- elements.push(node);
449
- }
450
- }
451
- return elements;
452
- }
453
-
454
- if (e.keyCode == tinymce.VK.BACKSPACE) {
455
- var li = getLi();
456
- if (li) {
457
- var list = ed.dom.getParent(li, 'ol,ul');
458
- if (list && list.firstChild === li) {
459
- var elements = listElements(list, li);
460
- ed.execCommand("Outdent", false, elements);
461
- ed.undoManager.add();
462
- return Event.cancel(e);
463
- }
464
- }
465
- }
466
- }
467
-
468
- function fixDeletingEmptyLiInWebkit(ed, e) {
469
- var li = getLi();
470
- if (e.keyCode === tinymce.VK.BACKSPACE && ed.dom.is(li, 'li') && li.parentNode.firstChild!==li) {
471
- if (ed.dom.select('ul,ol', li).length === 1) {
472
- var prevLi = li.previousSibling;
473
- ed.dom.remove(ed.dom.select('br', li));
474
- ed.dom.remove(li, true);
475
- var textNodes = tinymce.grep(prevLi.childNodes, function(n){ return n.nodeType === 3 });
476
- if (textNodes.length === 1) {
477
- var textNode = textNodes[0]
478
- ed.selection.setCursorLocation(textNode, textNode.length);
479
- }
480
- ed.undoManager.add();
481
- return Event.cancel(e);
482
- }
483
- }
484
- }
485
-
486
- ed.onKeyDown.add(function(_, e) { state = getListKeyState(e); });
487
- ed.onKeyDown.add(cancelDefaultEvents);
488
- ed.onKeyDown.add(imageJoiningListItem);
489
- ed.onKeyDown.add(createNewLi);
490
-
491
- if (tinymce.isGecko) {
492
- ed.onKeyUp.add(fixIndentedListItemForGecko);
493
- }
494
- if (tinymce.isIE8) {
495
- ed.onKeyUp.add(fixIndentedListItemForIE8);
496
- }
497
- if (tinymce.isGecko || tinymce.isWebKit) {
498
- ed.onKeyDown.add(fixDeletingFirstCharOfList);
499
- }
500
- if (tinymce.isWebKit) {
501
- ed.onKeyDown.add(fixDeletingEmptyLiInWebkit);
502
- }
503
- },
504
-
505
- applyList: function(targetListType, oppositeListType) {
506
- var t = this, ed = t.ed, dom = ed.dom, applied = [], hasSameType = false, hasOppositeType = false, hasNonList = false, actions,
507
- selectedBlocks = ed.selection.getSelectedBlocks();
508
-
509
- function cleanupBr(e) {
510
- if (e && e.tagName === 'BR') {
511
- dom.remove(e);
512
- }
513
- }
514
-
515
- function makeList(element) {
516
- var list = dom.create(targetListType), li;
517
-
518
- function adjustIndentForNewList(element) {
519
- // If there's a margin-left, outdent one level to account for the extra list margin.
520
- if (element.style.marginLeft || element.style.paddingLeft) {
521
- t.adjustPaddingFunction(false)(element);
522
- }
523
- }
524
-
525
- if (element.tagName === 'LI') {
526
- // No change required.
527
- } else if (element.tagName === 'P' || element.tagName === 'DIV' || element.tagName === 'BODY') {
528
- processBrs(element, function(startSection, br) {
529
- doWrapList(startSection, br, element.tagName === 'BODY' ? null : startSection.parentNode);
530
- li = startSection.parentNode;
531
- adjustIndentForNewList(li);
532
- cleanupBr(br);
533
- });
534
- if (li) {
535
- if (li.tagName === 'LI' && (element.tagName === 'P' || selectedBlocks.length > 1)) {
536
- dom.split(li.parentNode.parentNode, li.parentNode);
537
- }
538
- attemptMergeWithAdjacent(li.parentNode, true);
539
- }
540
- return;
541
- } else {
542
- // Put the list around the element.
543
- li = dom.create('li');
544
- dom.insertAfter(li, element);
545
- li.appendChild(element);
546
- adjustIndentForNewList(element);
547
- element = li;
548
- }
549
- dom.insertAfter(list, element);
550
- list.appendChild(element);
551
- attemptMergeWithAdjacent(list, true);
552
- applied.push(element);
553
- }
554
-
555
- function doWrapList(start, end, template) {
556
- var li, n = start, tmp;
557
- while (!dom.isBlock(start.parentNode) && start.parentNode !== dom.getRoot()) {
558
- start = dom.split(start.parentNode, start.previousSibling);
559
- start = start.nextSibling;
560
- n = start;
561
- }
562
- if (template) {
563
- li = template.cloneNode(true);
564
- start.parentNode.insertBefore(li, start);
565
- while (li.firstChild) dom.remove(li.firstChild);
566
- li = dom.rename(li, 'li');
567
- } else {
568
- li = dom.create('li');
569
- start.parentNode.insertBefore(li, start);
570
- }
571
- while (n && n != end) {
572
- tmp = n.nextSibling;
573
- li.appendChild(n);
574
- n = tmp;
575
- }
576
- if (li.childNodes.length === 0) {
577
- li.innerHTML = '<br _mce_bogus="1" />';
578
- }
579
- makeList(li);
580
- }
581
-
582
- function processBrs(element, callback) {
583
- var startSection, previousBR, END_TO_START = 3, START_TO_END = 1,
584
- breakElements = 'br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl';
585
-
586
- function isAnyPartSelected(start, end) {
587
- var r = dom.createRng(), sel;
588
- bookmark.keep = true;
589
- ed.selection.moveToBookmark(bookmark);
590
- bookmark.keep = false;
591
- sel = ed.selection.getRng(true);
592
- if (!end) {
593
- end = start.parentNode.lastChild;
594
- }
595
- r.setStartBefore(start);
596
- r.setEndAfter(end);
597
- return !(r.compareBoundaryPoints(END_TO_START, sel) > 0 || r.compareBoundaryPoints(START_TO_END, sel) <= 0);
598
- }
599
-
600
- function nextLeaf(br) {
601
- if (br.nextSibling)
602
- return br.nextSibling;
603
- if (!dom.isBlock(br.parentNode) && br.parentNode !== dom.getRoot())
604
- return nextLeaf(br.parentNode);
605
- }
606
-
607
- // Split on BRs within the range and process those.
608
- startSection = element.firstChild;
609
- // First mark the BRs that have any part of the previous section selected.
610
- var trailingContentSelected = false;
611
- each(dom.select(breakElements, element), function(br) {
612
- if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
613
- return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
614
- }
615
- if (isAnyPartSelected(startSection, br)) {
616
- dom.addClass(br, '_mce_tagged_br');
617
- startSection = nextLeaf(br);
618
- }
619
- });
620
- trailingContentSelected = (startSection && isAnyPartSelected(startSection, undefined));
621
- startSection = element.firstChild;
622
- each(dom.select(breakElements, element), function(br) {
623
- // Got a section from start to br.
624
- var tmp = nextLeaf(br);
625
- if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
626
- return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
627
- }
628
- if (dom.hasClass(br, '_mce_tagged_br')) {
629
- callback(startSection, br, previousBR);
630
- previousBR = null;
631
- } else {
632
- previousBR = br;
633
- }
634
- startSection = tmp;
635
- });
636
- if (trailingContentSelected) {
637
- callback(startSection, undefined, previousBR);
638
- }
639
- }
640
-
641
- function wrapList(element) {
642
- processBrs(element, function(startSection, br, previousBR) {
643
- // Need to indent this part
644
- doWrapList(startSection, br);
645
- cleanupBr(br);
646
- cleanupBr(previousBR);
647
- });
648
- }
649
-
650
- function changeList(element) {
651
- if (tinymce.inArray(applied, element) !== -1) {
652
- return;
653
- }
654
- if (element.parentNode.tagName === oppositeListType) {
655
- dom.split(element.parentNode, element);
656
- makeList(element);
657
- attemptMergeWithNext(element.parentNode, false);
658
- }
659
- applied.push(element);
660
- }
661
-
662
- function convertListItemToParagraph(element) {
663
- var child, nextChild, mergedElement, splitLast;
664
- if (tinymce.inArray(applied, element) !== -1) {
665
- return;
666
- }
667
- element = splitNestedLists(element, dom);
668
- while (dom.is(element.parentNode, 'ol,ul,li')) {
669
- dom.split(element.parentNode, element);
670
- }
671
- // Push the original element we have from the selection, not the renamed one.
672
- applied.push(element);
673
- element = dom.rename(element, 'p');
674
- mergedElement = attemptMergeWithAdjacent(element, false, ed.settings.force_br_newlines);
675
- if (mergedElement === element) {
676
- // Now split out any block elements that can't be contained within a P.
677
- // Manually iterate to ensure we handle modifications correctly (doesn't work with tinymce.each)
678
- child = element.firstChild;
679
- while (child) {
680
- if (dom.isBlock(child)) {
681
- child = dom.split(child.parentNode, child);
682
- splitLast = true;
683
- nextChild = child.nextSibling && child.nextSibling.firstChild;
684
- } else {
685
- nextChild = child.nextSibling;
686
- if (splitLast && child.tagName === 'BR') {
687
- dom.remove(child);
688
- }
689
- splitLast = false;
690
- }
691
- child = nextChild;
692
- }
693
- }
694
- }
695
-
696
- each(selectedBlocks, function(e) {
697
- e = findItemToOperateOn(e, dom);
698
- if (e.tagName === oppositeListType || (e.tagName === 'LI' && e.parentNode.tagName === oppositeListType)) {
699
- hasOppositeType = true;
700
- } else if (e.tagName === targetListType || (e.tagName === 'LI' && e.parentNode.tagName === targetListType)) {
701
- hasSameType = true;
702
- } else {
703
- hasNonList = true;
704
- }
705
- });
706
-
707
- if (hasNonList &&!hasSameType || hasOppositeType || selectedBlocks.length === 0) {
708
- actions = {
709
- 'LI': changeList,
710
- 'H1': makeList,
711
- 'H2': makeList,
712
- 'H3': makeList,
713
- 'H4': makeList,
714
- 'H5': makeList,
715
- 'H6': makeList,
716
- 'P': makeList,
717
- 'BODY': makeList,
718
- 'DIV': selectedBlocks.length > 1 ? makeList : wrapList,
719
- defaultAction: wrapList,
720
- elements: this.selectedBlocks()
721
- };
722
- } else {
723
- actions = {
724
- defaultAction: convertListItemToParagraph,
725
- elements: this.selectedBlocks()
726
- };
727
- }
728
- this.process(actions);
729
- },
730
-
731
- indent: function() {
732
- var ed = this.ed, dom = ed.dom, indented = [];
733
-
734
- function createWrapItem(element) {
735
- var wrapItem = dom.create('li', { style: 'list-style-type: none;'});
736
- dom.insertAfter(wrapItem, element);
737
- return wrapItem;
738
- }
739
-
740
- function createWrapList(element) {
741
- var wrapItem = createWrapItem(element),
742
- list = dom.getParent(element, 'ol,ul'),
743
- listType = list.tagName,
744
- listStyle = dom.getStyle(list, 'list-style-type'),
745
- attrs = {},
746
- wrapList;
747
- if (listStyle !== '') {
748
- attrs.style = 'list-style-type: ' + listStyle + ';';
749
- }
750
- wrapList = dom.create(listType, attrs);
751
- wrapItem.appendChild(wrapList);
752
- return wrapList;
753
- }
754
-
755
- function indentLI(element) {
756
- if (!hasParentInList(ed, element, indented)) {
757
- element = splitNestedLists(element, dom);
758
- var wrapList = createWrapList(element);
759
- wrapList.appendChild(element);
760
- attemptMergeWithAdjacent(wrapList.parentNode, false);
761
- attemptMergeWithAdjacent(wrapList, false);
762
- indented.push(element);
763
- }
764
- }
765
-
766
- this.process({
767
- 'LI': indentLI,
768
- defaultAction: this.adjustPaddingFunction(true),
769
- elements: this.selectedBlocks()
770
- });
771
-
772
- },
773
-
774
- outdent: function(ui, elements) {
775
- var t = this, ed = t.ed, dom = ed.dom, outdented = [];
776
-
777
- function outdentLI(element) {
778
- var listElement, targetParent, align;
779
- if (!hasParentInList(ed, element, outdented)) {
780
- if (dom.getStyle(element, 'margin-left') !== '' || dom.getStyle(element, 'padding-left') !== '') {
781
- return t.adjustPaddingFunction(false)(element);
782
- }
783
- align = dom.getStyle(element, 'text-align', true);
784
- if (align === 'center' || align === 'right') {
785
- dom.setStyle(element, 'text-align', 'left');
786
- return;
787
- }
788
- element = splitNestedLists(element, dom);
789
- listElement = element.parentNode;
790
- targetParent = element.parentNode.parentNode;
791
- if (targetParent.tagName === 'P') {
792
- dom.split(targetParent, element.parentNode);
793
- } else {
794
- dom.split(listElement, element);
795
- if (targetParent.tagName === 'LI') {
796
- // Nested list, need to split the LI and go back out to the OL/UL element.
797
- dom.split(targetParent, element);
798
- } else if (!dom.is(targetParent, 'ol,ul')) {
799
- dom.rename(element, 'p');
800
- }
801
- }
802
- outdented.push(element);
803
- }
804
- }
805
-
806
- var listElements = elements && tinymce.is(elements, 'array') ? elements : this.selectedBlocks();
807
- this.process({
808
- 'LI': outdentLI,
809
- defaultAction: this.adjustPaddingFunction(false),
810
- elements: listElements
811
- });
812
-
813
- each(outdented, attemptMergeWithAdjacent);
814
- },
815
-
816
- process: function(actions) {
817
- var t = this, sel = t.ed.selection, dom = t.ed.dom, selectedBlocks, r;
818
-
819
- function isEmptyElement(element) {
820
- var excludeBrsAndBookmarks = tinymce.grep(element.childNodes, function(n) {
821
- return !(n.nodeName === 'BR' || n.nodeName === 'SPAN' && dom.getAttrib(n, 'data-mce-type') == 'bookmark'
822
- || n.nodeType == 3 && (n.nodeValue == String.fromCharCode(160) || n.nodeValue == ''));
823
- });
824
- return excludeBrsAndBookmarks.length === 0;
825
- }
826
-
827
- function processElement(element) {
828
- dom.removeClass(element, '_mce_act_on');
829
- if (!element || element.nodeType !== 1 || selectedBlocks.length > 1 && isEmptyElement(element)) {
830
- return;
831
- }
832
- element = findItemToOperateOn(element, dom);
833
- var action = actions[element.tagName];
834
- if (!action) {
835
- action = actions.defaultAction;
836
- }
837
- action(element);
838
- }
839
-
840
- function recurse(element) {
841
- t.splitSafeEach(element.childNodes, processElement);
842
- }
843
-
844
- function brAtEdgeOfSelection(container, offset) {
845
- return offset >= 0 && container.hasChildNodes() && offset < container.childNodes.length &&
846
- container.childNodes[offset].tagName === 'BR';
847
- }
848
-
849
- function isInTable() {
850
- var n = sel.getNode();
851
- var p = dom.getParent(n, 'td');
852
- return p !== null;
853
- }
854
-
855
- selectedBlocks = actions.elements;
856
-
857
- r = sel.getRng(true);
858
- if (!r.collapsed) {
859
- if (brAtEdgeOfSelection(r.endContainer, r.endOffset - 1)) {
860
- r.setEnd(r.endContainer, r.endOffset - 1);
861
- sel.setRng(r);
862
- }
863
- if (brAtEdgeOfSelection(r.startContainer, r.startOffset)) {
864
- r.setStart(r.startContainer, r.startOffset + 1);
865
- sel.setRng(r);
866
- }
867
- }
868
-
869
-
870
- if (tinymce.isIE8) {
871
- // append a zero sized nbsp so that caret is restored correctly using bookmark
872
- var s = t.ed.selection.getNode();
873
- if (s.tagName === 'LI' && !(s.parentNode.lastChild === s)) {
874
- var i = t.ed.getDoc().createTextNode('\uFEFF');
875
- s.appendChild(i);
876
- }
877
- }
878
-
879
- bookmark = sel.getBookmark();
880
- actions.OL = actions.UL = recurse;
881
- t.splitSafeEach(selectedBlocks, processElement);
882
- sel.moveToBookmark(bookmark);
883
- bookmark = null;
884
-
885
- // we avoid doing repaint in a table as this will move the caret out of the table in Firefox 3.6
886
- if (!isInTable()) {
887
- // Avoids table or image handles being left behind in Firefox.
888
- t.ed.execCommand('mceRepaint');
889
- }
890
- },
891
-
892
- splitSafeEach: function(elements, f) {
893
- if (tinymce.isGecko && (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) ||
894
- /Firefox\/3\.[0-4]/.test(navigator.userAgent))) {
895
- this.classBasedEach(elements, f);
896
- } else {
897
- each(elements, f);
898
- }
899
- },
900
-
901
- classBasedEach: function(elements, f) {
902
- var dom = this.ed.dom, nodes, element;
903
- // Mark nodes
904
- each(elements, function(element) {
905
- dom.addClass(element, '_mce_act_on');
906
- });
907
- nodes = dom.select('._mce_act_on');
908
- while (nodes.length > 0) {
909
- element = nodes.shift();
910
- dom.removeClass(element, '_mce_act_on');
911
- f(element);
912
- nodes = dom.select('._mce_act_on');
913
- }
914
- },
915
-
916
- adjustPaddingFunction: function(isIndent) {
917
- var indentAmount, indentUnits, ed = this.ed;
918
- indentAmount = ed.settings.indentation;
919
- indentUnits = /[a-z%]+/i.exec(indentAmount);
920
- indentAmount = parseInt(indentAmount, 10);
921
- return function(element) {
922
- var currentIndent, newIndentAmount;
923
- currentIndent = parseInt(ed.dom.getStyle(element, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(element, 'padding-left') || 0, 10);
924
- if (isIndent) {
925
- newIndentAmount = currentIndent + indentAmount;
926
- } else {
927
- newIndentAmount = currentIndent - indentAmount;
928
- }
929
- ed.dom.setStyle(element, 'padding-left', '');
930
- ed.dom.setStyle(element, 'margin-left', newIndentAmount > 0 ? newIndentAmount + indentUnits : '');
931
- };
932
- },
933
-
934
- selectedBlocks: function() {
935
- var ed = this.ed
936
- var selectedBlocks = ed.selection.getSelectedBlocks();
937
- return selectedBlocks.length == 0 ? [ ed.dom.getRoot() ] : selectedBlocks;
938
- },
939
-
940
- getInfo: function() {
941
- return {
942
- longname : 'Lists',
943
- author : 'Moxiecode Systems AB',
944
- authorurl : 'http://tinymce.moxiecode.com',
945
- infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists',
946
- version : tinymce.majorVersion + "." + tinymce.minorVersion
947
- };
948
- }
949
- });
950
- tinymce.PluginManager.add("lists", tinymce.plugins.Lists);
951
- }());
1
+ /**
2
+ * editor_plugin_src.js
3
+ *
4
+ * Copyright 2011, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://tinymce.moxiecode.com/license
8
+ * Contributing: http://tinymce.moxiecode.com/contributing
9
+ */
10
+
11
+ (function() {
12
+ var each = tinymce.each, Event = tinymce.dom.Event, bookmark;
13
+
14
+ // Skips text nodes that only contain whitespace since they aren't semantically important.
15
+ function skipWhitespaceNodes(e, next) {
16
+ while (e && (e.nodeType === 8 || (e.nodeType === 3 && /^[ \t\n\r]*$/.test(e.nodeValue)))) {
17
+ e = next(e);
18
+ }
19
+ return e;
20
+ }
21
+
22
+ function skipWhitespaceNodesBackwards(e) {
23
+ return skipWhitespaceNodes(e, function(e) {
24
+ return e.previousSibling;
25
+ });
26
+ }
27
+
28
+ function skipWhitespaceNodesForwards(e) {
29
+ return skipWhitespaceNodes(e, function(e) {
30
+ return e.nextSibling;
31
+ });
32
+ }
33
+
34
+ function hasParentInList(ed, e, list) {
35
+ return ed.dom.getParent(e, function(p) {
36
+ return tinymce.inArray(list, p) !== -1;
37
+ });
38
+ }
39
+
40
+ function isList(e) {
41
+ return e && (e.tagName === 'OL' || e.tagName === 'UL');
42
+ }
43
+
44
+ function splitNestedLists(element, dom) {
45
+ var tmp, nested, wrapItem;
46
+ tmp = skipWhitespaceNodesBackwards(element.lastChild);
47
+ while (isList(tmp)) {
48
+ nested = tmp;
49
+ tmp = skipWhitespaceNodesBackwards(nested.previousSibling);
50
+ }
51
+ if (nested) {
52
+ wrapItem = dom.create('li', { style: 'list-style-type: none;'});
53
+ dom.split(element, nested);
54
+ dom.insertAfter(wrapItem, nested);
55
+ wrapItem.appendChild(nested);
56
+ wrapItem.appendChild(nested);
57
+ element = wrapItem.previousSibling;
58
+ }
59
+ return element;
60
+ }
61
+
62
+ function attemptMergeWithAdjacent(e, allowDifferentListStyles, mergeParagraphs) {
63
+ e = attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs);
64
+ return attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs);
65
+ }
66
+
67
+ function attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs) {
68
+ var prev = skipWhitespaceNodesBackwards(e.previousSibling);
69
+ if (prev) {
70
+ return attemptMerge(prev, e, allowDifferentListStyles ? prev : false, mergeParagraphs);
71
+ } else {
72
+ return e;
73
+ }
74
+ }
75
+
76
+ function attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs) {
77
+ var next = skipWhitespaceNodesForwards(e.nextSibling);
78
+ if (next) {
79
+ return attemptMerge(e, next, allowDifferentListStyles ? next : false, mergeParagraphs);
80
+ } else {
81
+ return e;
82
+ }
83
+ }
84
+
85
+ function attemptMerge(e1, e2, differentStylesMasterElement, mergeParagraphs) {
86
+ if (canMerge(e1, e2, !!differentStylesMasterElement, mergeParagraphs)) {
87
+ return merge(e1, e2, differentStylesMasterElement);
88
+ } else if (e1 && e1.tagName === 'LI' && isList(e2)) {
89
+ // Fix invalidly nested lists.
90
+ e1.appendChild(e2);
91
+ }
92
+ return e2;
93
+ }
94
+
95
+ function canMerge(e1, e2, allowDifferentListStyles, mergeParagraphs) {
96
+ if (!e1 || !e2) {
97
+ return false;
98
+ } else if (e1.tagName === 'LI' && e2.tagName === 'LI') {
99
+ return e2.style.listStyleType === 'none' || containsOnlyAList(e2);
100
+ } else if (isList(e1)) {
101
+ return (e1.tagName === e2.tagName && (allowDifferentListStyles || e1.style.listStyleType === e2.style.listStyleType)) || isListForIndent(e2);
102
+ } else return mergeParagraphs && e1.tagName === 'P' && e2.tagName === 'P';
103
+ }
104
+
105
+ function isListForIndent(e) {
106
+ var firstLI = skipWhitespaceNodesForwards(e.firstChild), lastLI = skipWhitespaceNodesBackwards(e.lastChild);
107
+ return firstLI && lastLI && isList(e) && firstLI === lastLI && (isList(firstLI) || firstLI.style.listStyleType === 'none' || containsOnlyAList(firstLI));
108
+ }
109
+
110
+ function containsOnlyAList(e) {
111
+ var firstChild = skipWhitespaceNodesForwards(e.firstChild), lastChild = skipWhitespaceNodesBackwards(e.lastChild);
112
+ return firstChild && lastChild && firstChild === lastChild && isList(firstChild);
113
+ }
114
+
115
+ function merge(e1, e2, masterElement) {
116
+ var lastOriginal = skipWhitespaceNodesBackwards(e1.lastChild), firstNew = skipWhitespaceNodesForwards(e2.firstChild);
117
+ if (e1.tagName === 'P') {
118
+ e1.appendChild(e1.ownerDocument.createElement('br'));
119
+ }
120
+ while (e2.firstChild) {
121
+ e1.appendChild(e2.firstChild);
122
+ }
123
+ if (masterElement) {
124
+ e1.style.listStyleType = masterElement.style.listStyleType;
125
+ }
126
+ e2.parentNode.removeChild(e2);
127
+ attemptMerge(lastOriginal, firstNew, false);
128
+ return e1;
129
+ }
130
+
131
+ function findItemToOperateOn(e, dom) {
132
+ var item;
133
+ if (!dom.is(e, 'li,ol,ul')) {
134
+ item = dom.getParent(e, 'li');
135
+ if (item) {
136
+ e = item;
137
+ }
138
+ }
139
+ return e;
140
+ }
141
+
142
+ tinymce.create('tinymce.plugins.Lists', {
143
+ init: function(ed) {
144
+ var LIST_TABBING = 'TABBING';
145
+ var LIST_EMPTY_ITEM = 'EMPTY';
146
+ var LIST_ESCAPE = 'ESCAPE';
147
+ var LIST_PARAGRAPH = 'PARAGRAPH';
148
+ var LIST_UNKNOWN = 'UNKNOWN';
149
+ var state = LIST_UNKNOWN;
150
+
151
+ function isTabInList(e) {
152
+ // Don't indent on Ctrl+Tab or Alt+Tab
153
+ return e.keyCode === tinymce.VK.TAB && !(e.altKey || e.ctrlKey) &&
154
+ (ed.queryCommandState('InsertUnorderedList') || ed.queryCommandState('InsertOrderedList'));
155
+ }
156
+
157
+ function isOnLastListItem() {
158
+ var li = getLi();
159
+ var grandParent = li.parentNode.parentNode;
160
+ var isLastItem = li.parentNode.lastChild === li;
161
+ return isLastItem && !isNestedList(grandParent) && isEmptyListItem(li);
162
+ }
163
+
164
+ function isNestedList(grandParent) {
165
+ if (isList(grandParent)) {
166
+ return grandParent.parentNode && grandParent.parentNode.tagName === 'LI';
167
+ } else {
168
+ return grandParent.tagName === 'LI';
169
+ }
170
+ }
171
+
172
+ function isInEmptyListItem() {
173
+ return ed.selection.isCollapsed() && isEmptyListItem(getLi());
174
+ }
175
+
176
+ function getLi() {
177
+ var n = ed.selection.getStart();
178
+ // Get start will return BR if the LI only contains a BR or an empty element as we use these to fix caret position
179
+ return ((n.tagName == 'BR' || n.tagName == '') && n.parentNode.tagName == 'LI') ? n.parentNode : n;
180
+ }
181
+
182
+ function isEmptyListItem(li) {
183
+ var numChildren = li.childNodes.length;
184
+ if (li.tagName === 'LI') {
185
+ return numChildren == 0 ? true : numChildren == 1 && (li.firstChild.tagName == '' || li.firstChild.tagName == 'BR' || isEmptyIE9Li(li));
186
+ }
187
+ return false;
188
+ }
189
+
190
+ function isEmptyIE9Li(li) {
191
+ // only consider this to be last item if there is no list item content or that content is nbsp or space since IE9 creates these
192
+ var lis = tinymce.grep(li.parentNode.childNodes, function(n) {return n.tagName == 'LI'});
193
+ var isLastLi = li == lis[lis.length - 1];
194
+ var child = li.firstChild;
195
+ return tinymce.isIE9 && isLastLi && (child.nodeValue == String.fromCharCode(160) || child.nodeValue == String.fromCharCode(32));
196
+ }
197
+
198
+ function isEnter(e) {
199
+ return e.keyCode === tinymce.VK.ENTER;
200
+ }
201
+
202
+ function isEnterWithoutShift(e) {
203
+ return isEnter(e) && !e.shiftKey;
204
+ }
205
+
206
+ function getListKeyState(e) {
207
+ if (isTabInList(e)) {
208
+ return LIST_TABBING;
209
+ } else if (isEnterWithoutShift(e) && isOnLastListItem()) {
210
+ // Returns LIST_UNKNOWN since breaking out of lists is handled by the EnterKey.js logic now
211
+ //return LIST_ESCAPE;
212
+ return LIST_UNKNOWN;
213
+ } else if (isEnterWithoutShift(e) && isInEmptyListItem()) {
214
+ return LIST_EMPTY_ITEM;
215
+ } else {
216
+ return LIST_UNKNOWN;
217
+ }
218
+ }
219
+
220
+ function cancelDefaultEvents(ed, e) {
221
+ // list escape is done manually using outdent as it does not create paragraphs correctly in td's
222
+ if (state == LIST_TABBING || state == LIST_EMPTY_ITEM || tinymce.isGecko && state == LIST_ESCAPE) {
223
+ Event.cancel(e);
224
+ }
225
+ }
226
+
227
+ function isCursorAtEndOfContainer() {
228
+ var range = ed.selection.getRng(true);
229
+ var startContainer = range.startContainer;
230
+ if (startContainer.nodeType == 3) {
231
+ var value = startContainer.nodeValue;
232
+ if (tinymce.isIE9 && value.length > 1 && value.charCodeAt(value.length-1) == 32) {
233
+ // IE9 places a space on the end of the text in some cases so ignore last char
234
+ return (range.endOffset == value.length-1);
235
+ } else {
236
+ return (range.endOffset == value.length);
237
+ }
238
+ } else if (startContainer.nodeType == 1) {
239
+ return range.endOffset == startContainer.childNodes.length;
240
+ }
241
+ return false;
242
+ }
243
+
244
+ /*
245
+ If we are at the end of a list item surrounded with an element, pressing enter should create a
246
+ new list item instead without splitting the element e.g. don't want to create new P or H1 tag
247
+ */
248
+ function isEndOfListItem() {
249
+ var node = ed.selection.getNode();
250
+ var validElements = 'h1,h2,h3,h4,h5,h6,p,div';
251
+ var isLastParagraphOfLi = ed.dom.is(node, validElements) && node.parentNode.tagName === 'LI' && node.parentNode.lastChild === node;
252
+ return ed.selection.isCollapsed() && isLastParagraphOfLi && isCursorAtEndOfContainer();
253
+ }
254
+
255
+ // Creates a new list item after the current selection's list item parent
256
+ function createNewLi(ed, e) {
257
+ if (isEnterWithoutShift(e) && isEndOfListItem()) {
258
+ var node = ed.selection.getNode();
259
+ var li = ed.dom.create("li");
260
+ var parentLi = ed.dom.getParent(node, 'li');
261
+ ed.dom.insertAfter(li, parentLi);
262
+
263
+ // Move caret to new list element.
264
+ if (tinymce.isIE6 || tinymce.isIE7 || tinyMCE.isIE8) {
265
+ // Removed this line since it would create an odd <&nbsp;> tag and placing the caret inside an empty LI is handled and should be handled by the selection logic
266
+ //li.appendChild(ed.dom.create("&nbsp;")); // IE needs an element within the bullet point
267
+ ed.selection.setCursorLocation(li, 1);
268
+ } else {
269
+ ed.selection.setCursorLocation(li, 0);
270
+ }
271
+ e.preventDefault();
272
+ }
273
+ }
274
+
275
+ function imageJoiningListItem(ed, e) {
276
+ var prevSibling;
277
+
278
+ if (!tinymce.isGecko)
279
+ return;
280
+
281
+ var n = ed.selection.getStart();
282
+ if (e.keyCode != tinymce.VK.BACKSPACE || n.tagName !== 'IMG')
283
+ return;
284
+
285
+ function lastLI(node) {
286
+ var child = node.firstChild;
287
+ var li = null;
288
+ do {
289
+ if (!child)
290
+ break;
291
+
292
+ if (child.tagName === 'LI')
293
+ li = child;
294
+ } while (child = child.nextSibling);
295
+
296
+ return li;
297
+ }
298
+
299
+ function addChildren(parentNode, destination) {
300
+ while (parentNode.childNodes.length > 0)
301
+ destination.appendChild(parentNode.childNodes[0]);
302
+ }
303
+
304
+ // Check if there is a previous sibling
305
+ prevSibling = n.parentNode.previousSibling;
306
+ if (!prevSibling)
307
+ return;
308
+
309
+ var ul;
310
+ if (prevSibling.tagName === 'UL' || prevSibling.tagName === 'OL')
311
+ ul = prevSibling;
312
+ else if (prevSibling.previousSibling && (prevSibling.previousSibling.tagName === 'UL' || prevSibling.previousSibling.tagName === 'OL'))
313
+ ul = prevSibling.previousSibling;
314
+ else
315
+ return;
316
+
317
+ var li = lastLI(ul);
318
+
319
+ // move the caret to the end of the list item
320
+ var rng = ed.dom.createRng();
321
+ rng.setStart(li, 1);
322
+ rng.setEnd(li, 1);
323
+ ed.selection.setRng(rng);
324
+ ed.selection.collapse(true);
325
+
326
+ // save a bookmark at the end of the list item
327
+ var bookmark = ed.selection.getBookmark();
328
+
329
+ // copy the image an its text to the list item
330
+ var clone = n.parentNode.cloneNode(true);
331
+ if (clone.tagName === 'P' || clone.tagName === 'DIV')
332
+ addChildren(clone, li);
333
+ else
334
+ li.appendChild(clone);
335
+
336
+ // remove the old copy of the image
337
+ n.parentNode.parentNode.removeChild(n.parentNode);
338
+
339
+ // move the caret where we saved the bookmark
340
+ ed.selection.moveToBookmark(bookmark);
341
+ }
342
+
343
+ // fix the cursor position to ensure it is correct in IE
344
+ function setCursorPositionToOriginalLi(li) {
345
+ var list = ed.dom.getParent(li, 'ol,ul');
346
+ if (list != null) {
347
+ var lastLi = list.lastChild;
348
+ // Removed this line since IE9 would report an DOM character error and placing the caret inside an empty LI is handled and should be handled by the selection logic
349
+ //lastLi.appendChild(ed.getDoc().createElement(''));
350
+ ed.selection.setCursorLocation(lastLi, 0);
351
+ }
352
+ }
353
+
354
+ this.ed = ed;
355
+ ed.addCommand('Indent', this.indent, this);
356
+ ed.addCommand('Outdent', this.outdent, this);
357
+ ed.addCommand('InsertUnorderedList', function() {
358
+ this.applyList('UL', 'OL');
359
+ }, this);
360
+ ed.addCommand('InsertOrderedList', function() {
361
+ this.applyList('OL', 'UL');
362
+ }, this);
363
+
364
+ ed.onInit.add(function() {
365
+ ed.editorCommands.addCommands({
366
+ 'outdent': function() {
367
+ var sel = ed.selection, dom = ed.dom;
368
+
369
+ function hasStyleIndent(n) {
370
+ n = dom.getParent(n, dom.isBlock);
371
+ return n && (parseInt(ed.dom.getStyle(n, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(n, 'padding-left') || 0, 10)) > 0;
372
+ }
373
+
374
+ return hasStyleIndent(sel.getStart()) || hasStyleIndent(sel.getEnd()) || ed.queryCommandState('InsertOrderedList') || ed.queryCommandState('InsertUnorderedList');
375
+ }
376
+ }, 'state');
377
+ });
378
+
379
+ ed.onKeyUp.add(function(ed, e) {
380
+ if (state == LIST_TABBING) {
381
+ ed.execCommand(e.shiftKey ? 'Outdent' : 'Indent', true, null);
382
+ state = LIST_UNKNOWN;
383
+ return Event.cancel(e);
384
+ } else if (state == LIST_EMPTY_ITEM) {
385
+ var li = getLi();
386
+ var shouldOutdent = ed.settings.list_outdent_on_enter === true || e.shiftKey;
387
+ ed.execCommand(shouldOutdent ? 'Outdent' : 'Indent', true, null);
388
+ if (tinymce.isIE) {
389
+ setCursorPositionToOriginalLi(li);
390
+ }
391
+
392
+ return Event.cancel(e);
393
+ } else if (state == LIST_ESCAPE) {
394
+ if (tinymce.isIE6 || tinymce.isIE7 || tinymce.isIE8) {
395
+ // append a zero sized nbsp so that caret is positioned correctly in IE after escaping and applying formatting.
396
+ // if there is no text then applying formatting for e.g a H1 to the P tag immediately following list after
397
+ // escaping from it will cause the caret to be positioned on the last li instead of staying the in P tag.
398
+ var n = ed.getDoc().createTextNode('\uFEFF');
399
+ ed.selection.getNode().appendChild(n);
400
+ } else if (tinymce.isIE9 || tinymce.isGecko) {
401
+ // IE9 does not escape the list so we use outdent to do this and cancel the default behaviour
402
+ // Gecko does not create a paragraph outdenting inside a TD so default behaviour is cancelled and we outdent ourselves
403
+ ed.execCommand('Outdent');
404
+ return Event.cancel(e);
405
+ }
406
+ }
407
+ });
408
+
409
+ function fixListItem(parent, reference) {
410
+ // a zero-sized non-breaking space is placed in the empty list item so that the nested list is
411
+ // displayed on the below line instead of next to it
412
+ var n = ed.getDoc().createTextNode('\uFEFF');
413
+ parent.insertBefore(n, reference);
414
+ ed.selection.setCursorLocation(n, 0);
415
+ // repaint to remove rendering artifact. only visible when creating new list
416
+ ed.execCommand('mceRepaint');
417
+ }
418
+
419
+ function fixIndentedListItemForGecko(ed, e) {
420
+ if (isEnter(e)) {
421
+ var li = getLi();
422
+ if (li) {
423
+ var parent = li.parentNode;
424
+ var grandParent = parent && parent.parentNode;
425
+ if (grandParent && grandParent.nodeName == 'LI' && grandParent.firstChild == parent && li == parent.firstChild) {
426
+ fixListItem(grandParent, parent);
427
+ }
428
+ }
429
+ }
430
+ }
431
+
432
+ function fixIndentedListItemForIE8(ed, e) {
433
+ if (isEnter(e)) {
434
+ var li = getLi();
435
+ if (ed.dom.select('ul li', li).length === 1) {
436
+ var list = li.firstChild;
437
+ fixListItem(li, list);
438
+ }
439
+ }
440
+ }
441
+
442
+ function fixDeletingFirstCharOfList(ed, e) {
443
+ function listElements(list, li) {
444
+ var elements = [];
445
+ var walker = new tinymce.dom.TreeWalker(li, list);
446
+ for (var node = walker.current(); node; node = walker.next()) {
447
+ if (ed.dom.is(node, 'ol,ul,li')) {
448
+ elements.push(node);
449
+ }
450
+ }
451
+ return elements;
452
+ }
453
+
454
+ if (e.keyCode == tinymce.VK.BACKSPACE) {
455
+ var li = getLi();
456
+ if (li) {
457
+ var list = ed.dom.getParent(li, 'ol,ul');
458
+ if (list && list.firstChild === li) {
459
+ var elements = listElements(list, li);
460
+ ed.execCommand("Outdent", false, elements);
461
+ ed.undoManager.add();
462
+ return Event.cancel(e);
463
+ }
464
+ }
465
+ }
466
+ }
467
+
468
+ function fixDeletingEmptyLiInWebkit(ed, e) {
469
+ var li = getLi();
470
+ if (e.keyCode === tinymce.VK.BACKSPACE && ed.dom.is(li, 'li') && li.parentNode.firstChild!==li) {
471
+ if (ed.dom.select('ul,ol', li).length === 1) {
472
+ var prevLi = li.previousSibling;
473
+ ed.dom.remove(ed.dom.select('br', li));
474
+ ed.dom.remove(li, true);
475
+ var textNodes = tinymce.grep(prevLi.childNodes, function(n){ return n.nodeType === 3 });
476
+ if (textNodes.length === 1) {
477
+ var textNode = textNodes[0]
478
+ ed.selection.setCursorLocation(textNode, textNode.length);
479
+ }
480
+ ed.undoManager.add();
481
+ return Event.cancel(e);
482
+ }
483
+ }
484
+ }
485
+
486
+ ed.onKeyDown.add(function(_, e) { state = getListKeyState(e); });
487
+ ed.onKeyDown.add(cancelDefaultEvents);
488
+ ed.onKeyDown.add(imageJoiningListItem);
489
+ ed.onKeyDown.add(createNewLi);
490
+
491
+ if (tinymce.isGecko) {
492
+ ed.onKeyUp.add(fixIndentedListItemForGecko);
493
+ }
494
+ if (tinymce.isIE8) {
495
+ ed.onKeyUp.add(fixIndentedListItemForIE8);
496
+ }
497
+ if (tinymce.isGecko || tinymce.isWebKit) {
498
+ ed.onKeyDown.add(fixDeletingFirstCharOfList);
499
+ }
500
+ if (tinymce.isWebKit) {
501
+ ed.onKeyDown.add(fixDeletingEmptyLiInWebkit);
502
+ }
503
+ },
504
+
505
+ applyList: function(targetListType, oppositeListType) {
506
+ var t = this, ed = t.ed, dom = ed.dom, applied = [], hasSameType = false, hasOppositeType = false, hasNonList = false, actions,
507
+ selectedBlocks = ed.selection.getSelectedBlocks();
508
+
509
+ function cleanupBr(e) {
510
+ if (e && e.tagName === 'BR') {
511
+ dom.remove(e);
512
+ }
513
+ }
514
+
515
+ function makeList(element) {
516
+ var list = dom.create(targetListType), li;
517
+
518
+ function adjustIndentForNewList(element) {
519
+ // If there's a margin-left, outdent one level to account for the extra list margin.
520
+ if (element.style.marginLeft || element.style.paddingLeft) {
521
+ t.adjustPaddingFunction(false)(element);
522
+ }
523
+ }
524
+
525
+ if (element.tagName === 'LI') {
526
+ // No change required.
527
+ } else if (element.tagName === 'P' || element.tagName === 'DIV' || element.tagName === 'BODY') {
528
+ processBrs(element, function(startSection, br) {
529
+ doWrapList(startSection, br, element.tagName === 'BODY' ? null : startSection.parentNode);
530
+ li = startSection.parentNode;
531
+ adjustIndentForNewList(li);
532
+ cleanupBr(br);
533
+ });
534
+ if (li) {
535
+ if (li.tagName === 'LI' && (element.tagName === 'P' || selectedBlocks.length > 1)) {
536
+ dom.split(li.parentNode.parentNode, li.parentNode);
537
+ }
538
+ attemptMergeWithAdjacent(li.parentNode, true);
539
+ }
540
+ return;
541
+ } else {
542
+ // Put the list around the element.
543
+ li = dom.create('li');
544
+ dom.insertAfter(li, element);
545
+ li.appendChild(element);
546
+ adjustIndentForNewList(element);
547
+ element = li;
548
+ }
549
+ dom.insertAfter(list, element);
550
+ list.appendChild(element);
551
+ attemptMergeWithAdjacent(list, true);
552
+ applied.push(element);
553
+ }
554
+
555
+ function doWrapList(start, end, template) {
556
+ var li, n = start, tmp;
557
+ while (!dom.isBlock(start.parentNode) && start.parentNode !== dom.getRoot()) {
558
+ start = dom.split(start.parentNode, start.previousSibling);
559
+ start = start.nextSibling;
560
+ n = start;
561
+ }
562
+ if (template) {
563
+ li = template.cloneNode(true);
564
+ start.parentNode.insertBefore(li, start);
565
+ while (li.firstChild) dom.remove(li.firstChild);
566
+ li = dom.rename(li, 'li');
567
+ } else {
568
+ li = dom.create('li');
569
+ start.parentNode.insertBefore(li, start);
570
+ }
571
+ while (n && n != end) {
572
+ tmp = n.nextSibling;
573
+ li.appendChild(n);
574
+ n = tmp;
575
+ }
576
+ if (li.childNodes.length === 0) {
577
+ li.innerHTML = '<br _mce_bogus="1" />';
578
+ }
579
+ makeList(li);
580
+ }
581
+
582
+ function processBrs(element, callback) {
583
+ var startSection, previousBR, END_TO_START = 3, START_TO_END = 1,
584
+ breakElements = 'br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl';
585
+
586
+ function isAnyPartSelected(start, end) {
587
+ var r = dom.createRng(), sel;
588
+ bookmark.keep = true;
589
+ ed.selection.moveToBookmark(bookmark);
590
+ bookmark.keep = false;
591
+ sel = ed.selection.getRng(true);
592
+ if (!end) {
593
+ end = start.parentNode.lastChild;
594
+ }
595
+ r.setStartBefore(start);
596
+ r.setEndAfter(end);
597
+ return !(r.compareBoundaryPoints(END_TO_START, sel) > 0 || r.compareBoundaryPoints(START_TO_END, sel) <= 0);
598
+ }
599
+
600
+ function nextLeaf(br) {
601
+ if (br.nextSibling)
602
+ return br.nextSibling;
603
+ if (!dom.isBlock(br.parentNode) && br.parentNode !== dom.getRoot())
604
+ return nextLeaf(br.parentNode);
605
+ }
606
+
607
+ // Split on BRs within the range and process those.
608
+ startSection = element.firstChild;
609
+ // First mark the BRs that have any part of the previous section selected.
610
+ var trailingContentSelected = false;
611
+ each(dom.select(breakElements, element), function(br) {
612
+ if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
613
+ return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
614
+ }
615
+ if (isAnyPartSelected(startSection, br)) {
616
+ dom.addClass(br, '_mce_tagged_br');
617
+ startSection = nextLeaf(br);
618
+ }
619
+ });
620
+ trailingContentSelected = (startSection && isAnyPartSelected(startSection, undefined));
621
+ startSection = element.firstChild;
622
+ each(dom.select(breakElements, element), function(br) {
623
+ // Got a section from start to br.
624
+ var tmp = nextLeaf(br);
625
+ if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
626
+ return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
627
+ }
628
+ if (dom.hasClass(br, '_mce_tagged_br')) {
629
+ callback(startSection, br, previousBR);
630
+ previousBR = null;
631
+ } else {
632
+ previousBR = br;
633
+ }
634
+ startSection = tmp;
635
+ });
636
+ if (trailingContentSelected) {
637
+ callback(startSection, undefined, previousBR);
638
+ }
639
+ }
640
+
641
+ function wrapList(element) {
642
+ processBrs(element, function(startSection, br, previousBR) {
643
+ // Need to indent this part
644
+ doWrapList(startSection, br);
645
+ cleanupBr(br);
646
+ cleanupBr(previousBR);
647
+ });
648
+ }
649
+
650
+ function changeList(element) {
651
+ if (tinymce.inArray(applied, element) !== -1) {
652
+ return;
653
+ }
654
+ if (element.parentNode.tagName === oppositeListType) {
655
+ dom.split(element.parentNode, element);
656
+ makeList(element);
657
+ attemptMergeWithNext(element.parentNode, false);
658
+ }
659
+ applied.push(element);
660
+ }
661
+
662
+ function convertListItemToParagraph(element) {
663
+ var child, nextChild, mergedElement, splitLast;
664
+ if (tinymce.inArray(applied, element) !== -1) {
665
+ return;
666
+ }
667
+ element = splitNestedLists(element, dom);
668
+ while (dom.is(element.parentNode, 'ol,ul,li')) {
669
+ dom.split(element.parentNode, element);
670
+ }
671
+ // Push the original element we have from the selection, not the renamed one.
672
+ applied.push(element);
673
+ element = dom.rename(element, 'p');
674
+ mergedElement = attemptMergeWithAdjacent(element, false, ed.settings.force_br_newlines);
675
+ if (mergedElement === element) {
676
+ // Now split out any block elements that can't be contained within a P.
677
+ // Manually iterate to ensure we handle modifications correctly (doesn't work with tinymce.each)
678
+ child = element.firstChild;
679
+ while (child) {
680
+ if (dom.isBlock(child)) {
681
+ child = dom.split(child.parentNode, child);
682
+ splitLast = true;
683
+ nextChild = child.nextSibling && child.nextSibling.firstChild;
684
+ } else {
685
+ nextChild = child.nextSibling;
686
+ if (splitLast && child.tagName === 'BR') {
687
+ dom.remove(child);
688
+ }
689
+ splitLast = false;
690
+ }
691
+ child = nextChild;
692
+ }
693
+ }
694
+ }
695
+
696
+ each(selectedBlocks, function(e) {
697
+ e = findItemToOperateOn(e, dom);
698
+ if (e.tagName === oppositeListType || (e.tagName === 'LI' && e.parentNode.tagName === oppositeListType)) {
699
+ hasOppositeType = true;
700
+ } else if (e.tagName === targetListType || (e.tagName === 'LI' && e.parentNode.tagName === targetListType)) {
701
+ hasSameType = true;
702
+ } else {
703
+ hasNonList = true;
704
+ }
705
+ });
706
+
707
+ if (hasNonList &&!hasSameType || hasOppositeType || selectedBlocks.length === 0) {
708
+ actions = {
709
+ 'LI': changeList,
710
+ 'H1': makeList,
711
+ 'H2': makeList,
712
+ 'H3': makeList,
713
+ 'H4': makeList,
714
+ 'H5': makeList,
715
+ 'H6': makeList,
716
+ 'P': makeList,
717
+ 'BODY': makeList,
718
+ 'DIV': selectedBlocks.length > 1 ? makeList : wrapList,
719
+ defaultAction: wrapList,
720
+ elements: this.selectedBlocks()
721
+ };
722
+ } else {
723
+ actions = {
724
+ defaultAction: convertListItemToParagraph,
725
+ elements: this.selectedBlocks(),
726
+ processEvenIfEmpty: true
727
+ };
728
+ }
729
+ this.process(actions);
730
+ },
731
+
732
+ indent: function() {
733
+ var ed = this.ed, dom = ed.dom, indented = [];
734
+
735
+ function createWrapItem(element) {
736
+ var wrapItem = dom.create('li', { style: 'list-style-type: none;'});
737
+ dom.insertAfter(wrapItem, element);
738
+ return wrapItem;
739
+ }
740
+
741
+ function createWrapList(element) {
742
+ var wrapItem = createWrapItem(element),
743
+ list = dom.getParent(element, 'ol,ul'),
744
+ listType = list.tagName,
745
+ listStyle = dom.getStyle(list, 'list-style-type'),
746
+ attrs = {},
747
+ wrapList;
748
+ if (listStyle !== '') {
749
+ attrs.style = 'list-style-type: ' + listStyle + ';';
750
+ }
751
+ wrapList = dom.create(listType, attrs);
752
+ wrapItem.appendChild(wrapList);
753
+ return wrapList;
754
+ }
755
+
756
+ function indentLI(element) {
757
+ if (!hasParentInList(ed, element, indented)) {
758
+ element = splitNestedLists(element, dom);
759
+ var wrapList = createWrapList(element);
760
+ wrapList.appendChild(element);
761
+ attemptMergeWithAdjacent(wrapList.parentNode, false);
762
+ attemptMergeWithAdjacent(wrapList, false);
763
+ indented.push(element);
764
+ }
765
+ }
766
+
767
+ this.process({
768
+ 'LI': indentLI,
769
+ defaultAction: this.adjustPaddingFunction(true),
770
+ elements: this.selectedBlocks()
771
+ });
772
+
773
+ },
774
+
775
+ outdent: function(ui, elements) {
776
+ var t = this, ed = t.ed, dom = ed.dom, outdented = [];
777
+
778
+ function outdentLI(element) {
779
+ var listElement, targetParent, align;
780
+ if (!hasParentInList(ed, element, outdented)) {
781
+ if (dom.getStyle(element, 'margin-left') !== '' || dom.getStyle(element, 'padding-left') !== '') {
782
+ return t.adjustPaddingFunction(false)(element);
783
+ }
784
+ align = dom.getStyle(element, 'text-align', true);
785
+ if (align === 'center' || align === 'right') {
786
+ dom.setStyle(element, 'text-align', 'left');
787
+ return;
788
+ }
789
+ element = splitNestedLists(element, dom);
790
+ listElement = element.parentNode;
791
+ targetParent = element.parentNode.parentNode;
792
+ if (targetParent.tagName === 'P') {
793
+ dom.split(targetParent, element.parentNode);
794
+ } else {
795
+ dom.split(listElement, element);
796
+ if (targetParent.tagName === 'LI') {
797
+ // Nested list, need to split the LI and go back out to the OL/UL element.
798
+ dom.split(targetParent, element);
799
+ } else if (!dom.is(targetParent, 'ol,ul')) {
800
+ dom.rename(element, 'p');
801
+ }
802
+ }
803
+ outdented.push(element);
804
+ }
805
+ }
806
+
807
+ var listElements = elements && tinymce.is(elements, 'array') ? elements : this.selectedBlocks();
808
+ this.process({
809
+ 'LI': outdentLI,
810
+ defaultAction: this.adjustPaddingFunction(false),
811
+ elements: listElements
812
+ });
813
+
814
+ each(outdented, attemptMergeWithAdjacent);
815
+ },
816
+
817
+ process: function(actions) {
818
+ var t = this, sel = t.ed.selection, dom = t.ed.dom, selectedBlocks, r;
819
+
820
+ function isEmptyElement(element) {
821
+ var excludeBrsAndBookmarks = tinymce.grep(element.childNodes, function(n) {
822
+ return !(n.nodeName === 'BR' || n.nodeName === 'SPAN' && dom.getAttrib(n, 'data-mce-type') == 'bookmark'
823
+ || n.nodeType == 3 && (n.nodeValue == String.fromCharCode(160) || n.nodeValue == ''));
824
+ });
825
+ return excludeBrsAndBookmarks.length === 0;
826
+ }
827
+
828
+ function processElement(element) {
829
+ dom.removeClass(element, '_mce_act_on');
830
+ if (!element || element.nodeType !== 1 || ! actions.processEvenIfEmpty && selectedBlocks.length > 1 && isEmptyElement(element)) {
831
+ return;
832
+ }
833
+ element = findItemToOperateOn(element, dom);
834
+ var action = actions[element.tagName];
835
+ if (!action) {
836
+ action = actions.defaultAction;
837
+ }
838
+ action(element);
839
+ }
840
+
841
+ function recurse(element) {
842
+ t.splitSafeEach(element.childNodes, processElement);
843
+ }
844
+
845
+ function brAtEdgeOfSelection(container, offset) {
846
+ return offset >= 0 && container.hasChildNodes() && offset < container.childNodes.length &&
847
+ container.childNodes[offset].tagName === 'BR';
848
+ }
849
+
850
+ function isInTable() {
851
+ var n = sel.getNode();
852
+ var p = dom.getParent(n, 'td');
853
+ return p !== null;
854
+ }
855
+
856
+ selectedBlocks = actions.elements;
857
+
858
+ r = sel.getRng(true);
859
+ if (!r.collapsed) {
860
+ if (brAtEdgeOfSelection(r.endContainer, r.endOffset - 1)) {
861
+ r.setEnd(r.endContainer, r.endOffset - 1);
862
+ sel.setRng(r);
863
+ }
864
+ if (brAtEdgeOfSelection(r.startContainer, r.startOffset)) {
865
+ r.setStart(r.startContainer, r.startOffset + 1);
866
+ sel.setRng(r);
867
+ }
868
+ }
869
+
870
+
871
+ if (tinymce.isIE8) {
872
+ // append a zero sized nbsp so that caret is restored correctly using bookmark
873
+ var s = t.ed.selection.getNode();
874
+ if (s.tagName === 'LI' && !(s.parentNode.lastChild === s)) {
875
+ var i = t.ed.getDoc().createTextNode('\uFEFF');
876
+ s.appendChild(i);
877
+ }
878
+ }
879
+
880
+ bookmark = sel.getBookmark();
881
+ actions.OL = actions.UL = recurse;
882
+ t.splitSafeEach(selectedBlocks, processElement);
883
+ sel.moveToBookmark(bookmark);
884
+ bookmark = null;
885
+
886
+ // we avoid doing repaint in a table as this will move the caret out of the table in Firefox 3.6
887
+ if (!isInTable()) {
888
+ // Avoids table or image handles being left behind in Firefox.
889
+ t.ed.execCommand('mceRepaint');
890
+ }
891
+ },
892
+
893
+ splitSafeEach: function(elements, f) {
894
+ if (tinymce.isGecko && (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) ||
895
+ /Firefox\/3\.[0-4]/.test(navigator.userAgent))) {
896
+ this.classBasedEach(elements, f);
897
+ } else {
898
+ each(elements, f);
899
+ }
900
+ },
901
+
902
+ classBasedEach: function(elements, f) {
903
+ var dom = this.ed.dom, nodes, element;
904
+ // Mark nodes
905
+ each(elements, function(element) {
906
+ dom.addClass(element, '_mce_act_on');
907
+ });
908
+ nodes = dom.select('._mce_act_on');
909
+ while (nodes.length > 0) {
910
+ element = nodes.shift();
911
+ dom.removeClass(element, '_mce_act_on');
912
+ f(element);
913
+ nodes = dom.select('._mce_act_on');
914
+ }
915
+ },
916
+
917
+ adjustPaddingFunction: function(isIndent) {
918
+ var indentAmount, indentUnits, ed = this.ed;
919
+ indentAmount = ed.settings.indentation;
920
+ indentUnits = /[a-z%]+/i.exec(indentAmount);
921
+ indentAmount = parseInt(indentAmount, 10);
922
+ return function(element) {
923
+ var currentIndent, newIndentAmount;
924
+ currentIndent = parseInt(ed.dom.getStyle(element, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(element, 'padding-left') || 0, 10);
925
+ if (isIndent) {
926
+ newIndentAmount = currentIndent + indentAmount;
927
+ } else {
928
+ newIndentAmount = currentIndent - indentAmount;
929
+ }
930
+ ed.dom.setStyle(element, 'padding-left', '');
931
+ ed.dom.setStyle(element, 'margin-left', newIndentAmount > 0 ? newIndentAmount + indentUnits : '');
932
+ };
933
+ },
934
+
935
+ selectedBlocks: function() {
936
+ var ed = this.ed
937
+ var selectedBlocks = ed.selection.getSelectedBlocks();
938
+ return selectedBlocks.length == 0 ? [ ed.dom.getRoot() ] : selectedBlocks;
939
+ },
940
+
941
+ getInfo: function() {
942
+ return {
943
+ longname : 'Lists',
944
+ author : 'Moxiecode Systems AB',
945
+ authorurl : 'http://tinymce.moxiecode.com',
946
+ infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists',
947
+ version : tinymce.majorVersion + "." + tinymce.minorVersion
948
+ };
949
+ }
950
+ });
951
+ tinymce.PluginManager.add("lists", tinymce.plugins.Lists);
952
+ }());