tinymce-rails 3.5.2 → 3.5.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/jquery.tinymce.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autolink/editor_plugin_src.js +181 -181
- data/vendor/assets/javascripts/tinymce/plugins/autoresize/editor_plugin_src.js +119 -119
- data/vendor/assets/javascripts/tinymce/plugins/autosave/editor_plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autosave/editor_plugin_src.js +4 -2
- data/vendor/assets/javascripts/tinymce/plugins/contextmenu/editor_plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/contextmenu/editor_plugin_src.js +9 -7
- data/vendor/assets/javascripts/tinymce/plugins/emotions/langs/en_dlg.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/example_dependency/editor_plugin_src.js +50 -50
- data/vendor/assets/javascripts/tinymce/plugins/lists/editor_plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/lists/editor_plugin_src.js +952 -951
- data/vendor/assets/javascripts/tinymce/plugins/media/editor_plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/media/editor_plugin_src.js +22 -14
- data/vendor/assets/javascripts/tinymce/plugins/media/langs/en_dlg.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/style/langs/en_dlg.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/style/props.htm +845 -845
- data/vendor/assets/javascripts/tinymce/plugins/style/readme.txt +19 -19
- data/vendor/assets/javascripts/tinymce/plugins/tabfocus/editor_plugin_src.js +122 -122
- data/vendor/assets/javascripts/tinymce/plugins/table/editor_plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/editor_plugin_src.js +1449 -1446
- data/vendor/assets/javascripts/tinymce/plugins/table/js/table.js +4 -1
- data/vendor/assets/javascripts/tinymce/themes/advanced/js/color_picker.js +345 -345
- data/vendor/assets/javascripts/tinymce/themes/advanced/langs/en_dlg.js +1 -1
- data/vendor/assets/javascripts/tinymce/themes/advanced/skins/default/content.css +0 -1
- data/vendor/assets/javascripts/tinymce/themes/advanced/skins/highcontrast/content.css +0 -1
- data/vendor/assets/javascripts/tinymce/themes/advanced/skins/o2k7/content.css +0 -1
- data/vendor/assets/javascripts/tinymce/themes/advanced/source_editor.htm +1 -1
- data/vendor/assets/javascripts/tinymce/tiny_mce.js +1 -1
- data/vendor/assets/javascripts/tinymce/tiny_mce_jquery.js +1 -1
- data/vendor/assets/javascripts/tinymce/tiny_mce_jquery_src.js +394 -158
- data/vendor/assets/javascripts/tinymce/tiny_mce_src.js +394 -158
- 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| |<\/?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| |<\/?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
|
-
|
140
|
-
|
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(
|
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',
|
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
|
-
|
82
|
-
Event.remove(ed.getDoc(), 'click',
|
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 < > 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(" ")); // 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
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
dom.
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
wrapList
|
760
|
-
|
761
|
-
attemptMergeWithAdjacent(wrapList, false);
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
this.
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
var
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
bookmark
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
indentAmount = ed
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
currentIndent
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
ed.dom.setStyle(element, '
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
var
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
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 < > 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(" ")); // 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
|
+
}());
|