tinymce-rails 3.5.4.1 → 3.5.5

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