From 69d05c371029b7915cf2a87d6e552d9853244644 Mon Sep 17 00:00:00 2001 From: alecpl Date: Fri, 19 Mar 2010 14:53:30 +0000 Subject: - TinyMCE 3.3.1 --- CHANGELOG | 1 + program/js/tiny_mce/langs/en.js | 19 +- .../plugins/contextmenu/editor_plugin_src.js | 38 +- .../plugins/directionality/editor_plugin_src.js | 9 +- .../js/tiny_mce/plugins/emotions/editor_plugin.js | 2 +- .../tiny_mce/plugins/emotions/editor_plugin_src.js | 13 +- program/js/tiny_mce/plugins/media/editor_plugin.js | 2 +- .../js/tiny_mce/plugins/media/editor_plugin_src.js | 17 +- program/js/tiny_mce/plugins/media/media.htm | 9 +- .../plugins/nonbreaking/editor_plugin_src.js | 9 +- program/js/tiny_mce/plugins/paste/editor_plugin.js | 2 +- .../js/tiny_mce/plugins/paste/editor_plugin_src.js | 620 +- program/js/tiny_mce/plugins/paste/pastetext.htm | 10 +- program/js/tiny_mce/plugins/paste/pasteword.htm | 10 +- .../plugins/searchreplace/editor_plugin.js | 2 +- .../plugins/searchreplace/editor_plugin_src.js | 11 +- .../plugins/searchreplace/js/searchreplace.js | 4 + .../plugins/searchreplace/searchreplace.htm | 13 +- program/js/tiny_mce/plugins/table/cell.htm | 9 +- program/js/tiny_mce/plugins/table/editor_plugin.js | 2 +- .../js/tiny_mce/plugins/table/editor_plugin_src.js | 1862 ++--- program/js/tiny_mce/plugins/table/js/cell.js | 63 +- .../js/tiny_mce/plugins/table/js/merge_cells.js | 38 +- program/js/tiny_mce/plugins/table/js/row.js | 69 +- program/js/tiny_mce/plugins/table/js/table.js | 25 +- program/js/tiny_mce/plugins/table/merge_cells.htm | 11 +- program/js/tiny_mce/plugins/table/row.htm | 9 +- program/js/tiny_mce/plugins/table/table.htm | 9 +- .../plugins/visualchars/editor_plugin_src.js | 9 +- program/js/tiny_mce/plugins/xhtmlxtras/abbr.htm | 13 +- program/js/tiny_mce/plugins/xhtmlxtras/acronym.htm | 13 +- .../js/tiny_mce/plugins/xhtmlxtras/attributes.htm | 9 +- program/js/tiny_mce/plugins/xhtmlxtras/cite.htm | 13 +- program/js/tiny_mce/plugins/xhtmlxtras/del.htm | 14 +- .../tiny_mce/plugins/xhtmlxtras/editor_plugin.js | 2 +- .../plugins/xhtmlxtras/editor_plugin_src.js | 14 +- program/js/tiny_mce/plugins/xhtmlxtras/ins.htm | 14 +- program/js/tiny_mce/plugins/xhtmlxtras/js/abbr.js | 13 +- .../js/tiny_mce/plugins/xhtmlxtras/js/acronym.js | 11 +- .../tiny_mce/plugins/xhtmlxtras/js/attributes.js | 11 +- program/js/tiny_mce/plugins/xhtmlxtras/js/cite.js | 11 +- program/js/tiny_mce/plugins/xhtmlxtras/js/del.js | 11 +- .../plugins/xhtmlxtras/js/element_common.js | 16 +- program/js/tiny_mce/plugins/xhtmlxtras/js/ins.js | 11 +- program/js/tiny_mce/themes/advanced/about.htm | 4 +- program/js/tiny_mce/themes/advanced/anchor.htm | 9 +- .../js/tiny_mce/themes/advanced/color_picker.htm | 4 +- .../js/tiny_mce/themes/advanced/editor_template.js | 2 +- .../themes/advanced/editor_template_src.js | 335 +- program/js/tiny_mce/themes/advanced/image.htm | 9 +- program/js/tiny_mce/themes/advanced/img/icons.gif | Bin 11505 -> 11794 bytes program/js/tiny_mce/themes/advanced/js/anchor.js | 14 +- program/js/tiny_mce/themes/advanced/js/charmap.js | 10 + program/js/tiny_mce/themes/advanced/js/image.js | 4 +- program/js/tiny_mce/themes/advanced/link.htm | 9 +- .../themes/advanced/skins/default/content.css | 9 +- .../themes/advanced/skins/default/dialog.css | 7 +- .../tiny_mce/themes/advanced/skins/default/ui.css | 9 +- .../themes/advanced/skins/o2k7/content.css | 9 +- .../tiny_mce/themes/advanced/skins/o2k7/dialog.css | 5 +- .../js/tiny_mce/themes/advanced/skins/o2k7/ui.css | 6 +- .../js/tiny_mce/themes/advanced/source_editor.htm | 9 +- .../tiny_mce/themes/simple/editor_template_src.js | 10 +- program/js/tiny_mce/tiny_mce.js | 2 +- program/js/tiny_mce/tiny_mce_popup.js | 2 +- program/js/tiny_mce/tiny_mce_src.js | 8791 +++++++++++--------- program/js/tiny_mce/utils/editable_selects.js | 9 +- program/js/tiny_mce/utils/form_utils.js | 9 +- program/js/tiny_mce/utils/mctabs.js | 9 +- program/js/tiny_mce/utils/validate.js | 9 +- 70 files changed, 6657 insertions(+), 5711 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4fb319802..379f896ef 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG RoundCube Webmail =========================== +- TinyMCE 3.3.1 - Implemented messages copying using drag&drop + SHIFT (#1484086) - Improved performance of folders operations (#1486525) - Fix blocked.gif attachment is not attached to the message (#1486516) diff --git a/program/js/tiny_mce/langs/en.js b/program/js/tiny_mce/langs/en.js index 8519b4de7..075bef70d 100644 --- a/program/js/tiny_mce/langs/en.js +++ b/program/js/tiny_mce/langs/en.js @@ -120,7 +120,9 @@ col:"Column", cell:"Cell" }, autosave:{ -unload_msg:"The changes you made will be lost if you navigate away from this page." +unload_msg:"The changes you made will be lost if you navigate away from this page.", +restore_content: "Restore auto-saved content", +warning_message: "If you restore the saved content, you will lose all the content that is currently in the editor.\n\nAre you sure you want to restore the saved content?" }, fullscreen:{ desc:"Toggle fullscreen mode" @@ -151,4 +153,17 @@ no_mpell:"No misspellings found." }, pagebreak:{ desc:"Insert page break." -}}}); \ No newline at end of file +}, +advlist : { + types : 'Types', + def : 'Default', + lower_alpha : "Lower alpha", + lower_greek : "Lower greek", + lower_roman : "Lower roman", + upper_alpha : "Upper alpha", + upper_roman : "Upper roman", + circle : "Circle", + disc : "Disc", + square : "Square" +} +}}); \ No newline at end of file diff --git a/program/js/tiny_mce/plugins/contextmenu/editor_plugin_src.js b/program/js/tiny_mce/plugins/contextmenu/editor_plugin_src.js index a2c1866ba..26e9ce2f8 100644 --- a/program/js/tiny_mce/plugins/contextmenu/editor_plugin_src.js +++ b/program/js/tiny_mce/plugins/contextmenu/editor_plugin_src.js @@ -1,18 +1,43 @@ /** - * $Id: editor_plugin_src.js 848 2008-05-15 11:54:40Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ (function() { var Event = tinymce.dom.Event, each = tinymce.each, DOM = tinymce.DOM; + /** + * This plugin a context menu to TinyMCE editor instances. + * + * @class tinymce.plugins.ContextMenu + */ tinymce.create('tinymce.plugins.ContextMenu', { + /** + * Initializes the plugin, this will be executed after the plugin has been created. + * This call is done before the editor instance has finished it's initialization so use the onInit event + * of the editor instance to intercept that event. + * + * @method init + * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in. + * @param {string} url Absolute URL to where the plugin is located. + */ init : function(ed) { var t = this; t.editor = ed; + + /** + * This event gets fired when the context menu is shown. + * + * @event onContextMenu + * @param {tinymce.plugins.ContextMenu} sender Plugin instance sending the event. + * @param {tinymce.ui.DropMenu} menu Drop down menu to fill with more items if needed. + */ t.onContextMenu = new tinymce.util.Dispatcher(this); ed.onContextMenu.add(function(ed, e) { @@ -35,6 +60,13 @@ ed.onKeyDown.add(hide); }, + /** + * Returns information about the plugin as a name/value array. + * The current keys are longname, author, authorurl, infourl and version. + * + * @method getInfo + * @return {Object} Name/value array containing information about the plugin. + */ getInfo : function() { return { longname : 'Contextmenu', diff --git a/program/js/tiny_mce/plugins/directionality/editor_plugin_src.js b/program/js/tiny_mce/plugins/directionality/editor_plugin_src.js index 81818e37c..4444959bf 100644 --- a/program/js/tiny_mce/plugins/directionality/editor_plugin_src.js +++ b/program/js/tiny_mce/plugins/directionality/editor_plugin_src.js @@ -1,8 +1,11 @@ /** - * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ (function() { diff --git a/program/js/tiny_mce/plugins/emotions/editor_plugin.js b/program/js/tiny_mce/plugins/emotions/editor_plugin.js index 4783bc371..dbdd8ffb5 100644 --- a/program/js/tiny_mce/plugins/emotions/editor_plugin.js +++ b/program/js/tiny_mce/plugins/emotions/editor_plugin.js @@ -1 +1 @@ -(function(){tinymce.create("tinymce.plugins.EmotionsPlugin",{init:function(a,b){a.addCommand("mceEmotion",function(){a.windowManager.open({file:b+"/emotions.htm",width:250+parseInt(a.getLang("emotions.delta_width",0)),height:160+parseInt(a.getLang("emotions.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("emotions",{title:"emotions.emotions_desc",cmd:"mceEmotion"})},getInfo:function(){return{longname:"Emotions",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("emotions",tinymce.plugins.EmotionsPlugin)})(); \ No newline at end of file +(function(a){a.create("tinymce.plugins.EmotionsPlugin",{init:function(b,c){b.addCommand("mceEmotion",function(){b.windowManager.open({file:c+"/emotions.htm",width:250+parseInt(b.getLang("emotions.delta_width",0)),height:160+parseInt(b.getLang("emotions.delta_height",0)),inline:1},{plugin_url:c})});b.addButton("emotions",{title:"emotions.emotions_desc",cmd:"mceEmotion"})},getInfo:function(){return{longname:"Emotions",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions",version:a.majorVersion+"."+a.minorVersion}}});a.PluginManager.add("emotions",a.plugins.EmotionsPlugin)})(tinymce); \ No newline at end of file diff --git a/program/js/tiny_mce/plugins/emotions/editor_plugin_src.js b/program/js/tiny_mce/plugins/emotions/editor_plugin_src.js index df0d370ae..71d541697 100644 --- a/program/js/tiny_mce/plugins/emotions/editor_plugin_src.js +++ b/program/js/tiny_mce/plugins/emotions/editor_plugin_src.js @@ -1,11 +1,14 @@ /** - * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ -(function() { +(function(tinymce) { tinymce.create('tinymce.plugins.EmotionsPlugin', { init : function(ed, url) { // Register commands @@ -37,4 +40,4 @@ // Register plugin tinymce.PluginManager.add('emotions', tinymce.plugins.EmotionsPlugin); -})(); \ No newline at end of file +})(tinymce); \ No newline at end of file diff --git a/program/js/tiny_mce/plugins/media/editor_plugin.js b/program/js/tiny_mce/plugins/media/editor_plugin.js index 2889be5ab..4bbe367e3 100644 --- a/program/js/tiny_mce/plugins/media/editor_plugin.js +++ b/program/js/tiny_mce/plugins/media/editor_plugin.js @@ -1 +1 @@ -(function(){var a=tinymce.each;tinymce.create("tinymce.plugins.MediaPlugin",{init:function(b,c){var e=this;e.editor=b;e.url=c;function f(g){return/^(mceItemFlash|mceItemShockWave|mceItemWindowsMedia|mceItemQuickTime|mceItemRealMedia)$/.test(g.className)}b.onPreInit.add(function(){b.serializer.addRules("param[name|value|_mce_value]")});b.addCommand("mceMedia",function(){b.windowManager.open({file:c+"/media.htm",width:430+parseInt(b.getLang("media.delta_width",0)),height:470+parseInt(b.getLang("media.delta_height",0)),inline:1},{plugin_url:c})});b.addButton("media",{title:"media.desc",cmd:"mceMedia"});b.onNodeChange.add(function(h,g,i){g.setActive("media",i.nodeName=="IMG"&&f(i))});b.onInit.add(function(){var g={mceItemFlash:"flash",mceItemShockWave:"shockwave",mceItemWindowsMedia:"windowsmedia",mceItemQuickTime:"quicktime",mceItemRealMedia:"realmedia"};b.selection.onSetContent.add(function(){e._spansToImgs(b.getBody())});b.selection.onBeforeSetContent.add(e._objectsToSpans,e);if(b.settings.content_css!==false){b.dom.loadCSS(c+"/css/content.css")}if(b.theme&&b.theme.onResolveName){b.theme.onResolveName.add(function(h,i){if(i.name=="img"){a(g,function(l,j){if(b.dom.hasClass(i.node,j)){i.name=l;i.title=b.dom.getAttrib(i.node,"title");return false}})}})}if(b&&b.plugins.contextmenu){b.plugins.contextmenu.onContextMenu.add(function(i,h,j){if(j.nodeName=="IMG"&&/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(j.className)){h.add({title:"media.edit",icon:"media",cmd:"mceMedia"})}})}});b.onBeforeSetContent.add(e._objectsToSpans,e);b.onSetContent.add(function(){e._spansToImgs(b.getBody())});b.onPreProcess.add(function(g,i){var h=g.dom;if(i.set){e._spansToImgs(i.node);a(h.select("IMG",i.node),function(k){var j;if(f(k)){j=e._parse(k.title);h.setAttrib(k,"width",h.getAttrib(k,"width",j.width||100));h.setAttrib(k,"height",h.getAttrib(k,"height",j.height||100))}})}if(i.get){a(h.select("IMG",i.node),function(m){var l,j,k;if(g.getParam("media_use_script")){if(f(m)){m.className=m.className.replace(/mceItem/g,"mceTemp")}return}switch(m.className){case"mceItemFlash":l="d27cdb6e-ae6d-11cf-96b8-444553540000";j="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0";k="application/x-shockwave-flash";break;case"mceItemShockWave":l="166b1bca-3f9c-11cf-8075-444553540000";j="http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0";k="application/x-director";break;case"mceItemWindowsMedia":l=g.getParam("media_wmp6_compatible")?"05589fa1-c356-11ce-bf01-00aa0055595a":"6bf52a52-394a-11d3-b153-00c04f79faa6";j="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701";k="application/x-mplayer2";break;case"mceItemQuickTime":l="02bf25d5-8c17-4b23-bc80-d3488abddc6b";j="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0";k="video/quicktime";break;case"mceItemRealMedia":l="cfcdaa03-8be4-11cf-b84b-0020afbbccfa";j="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0";k="audio/x-pn-realaudio-plugin";break}if(l){h.replace(e._buildObj({classid:l,codebase:j,type:k},m),m)}})}});b.onPostProcess.add(function(g,h){h.content=h.content.replace(/_mce_value=/g,"value=")});function d(g,h){h=new RegExp(h+'="([^"]+)"',"g").exec(g);return h?b.dom.decode(h[1]):""}b.onPostProcess.add(function(g,h){if(g.getParam("media_use_script")){h.content=h.content.replace(/]+>/g,function(j){var i=d(j,"class");if(/^(mceTempFlash|mceTempShockWave|mceTempWindowsMedia|mceTempQuickTime|mceTempRealMedia)$/.test(i)){at=e._parse(d(j,"title"));at.width=d(j,"width");at.height=d(j,"height");j=' @@ -20,13 +19,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/plugins/paste/pasteword.htm b/program/js/tiny_mce/plugins/paste/pasteword.htm index f4a9b3db3..0f6bb4121 100644 --- a/program/js/tiny_mce/plugins/paste/pasteword.htm +++ b/program/js/tiny_mce/plugins/paste/pasteword.htm @@ -1,6 +1,5 @@ - {#paste.paste_word_desc} @@ -14,13 +13,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/plugins/searchreplace/editor_plugin.js b/program/js/tiny_mce/plugins/searchreplace/editor_plugin.js index c3f8358c6..cd9c985b7 100644 --- a/program/js/tiny_mce/plugins/searchreplace/editor_plugin.js +++ b/program/js/tiny_mce/plugins/searchreplace/editor_plugin.js @@ -1 +1 @@ -(function(){tinymce.create("tinymce.plugins.SearchReplacePlugin",{init:function(a,c){function b(d){a.windowManager.open({file:c+"/searchreplace.htm",width:420+parseInt(a.getLang("searchreplace.delta_width",0)),height:160+parseInt(a.getLang("searchreplace.delta_height",0)),inline:1,auto_focus:0},{mode:d,search_string:a.selection.getContent({format:"text"}),plugin_url:c})}a.addCommand("mceSearch",function(){b("search")});a.addCommand("mceReplace",function(){b("replace")});a.addButton("search",{title:"searchreplace.search_desc",cmd:"mceSearch"});a.addButton("replace",{title:"searchreplace.replace_desc",cmd:"mceReplace"});a.addShortcut("ctrl+f","searchreplace.search_desc","mceSearch")},getInfo:function(){return{longname:"Search/Replace",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/searchreplace",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("searchreplace",tinymce.plugins.SearchReplacePlugin)})(); \ No newline at end of file +(function(){tinymce.create("tinymce.plugins.SearchReplacePlugin",{init:function(a,c){function b(d){a.windowManager.open({file:c+"/searchreplace.htm",width:420+parseInt(a.getLang("searchreplace.delta_width",0)),height:170+parseInt(a.getLang("searchreplace.delta_height",0)),inline:1,auto_focus:0},{mode:d,search_string:a.selection.getContent({format:"text"}),plugin_url:c})}a.addCommand("mceSearch",function(){b("search")});a.addCommand("mceReplace",function(){b("replace")});a.addButton("search",{title:"searchreplace.search_desc",cmd:"mceSearch"});a.addButton("replace",{title:"searchreplace.replace_desc",cmd:"mceReplace"});a.addShortcut("ctrl+f","searchreplace.search_desc","mceSearch")},getInfo:function(){return{longname:"Search/Replace",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/searchreplace",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("searchreplace",tinymce.plugins.SearchReplacePlugin)})(); \ No newline at end of file diff --git a/program/js/tiny_mce/plugins/searchreplace/editor_plugin_src.js b/program/js/tiny_mce/plugins/searchreplace/editor_plugin_src.js index 59edc3b25..1433a06a4 100644 --- a/program/js/tiny_mce/plugins/searchreplace/editor_plugin_src.js +++ b/program/js/tiny_mce/plugins/searchreplace/editor_plugin_src.js @@ -1,8 +1,11 @@ /** - * $Id: editor_plugin_src.js 686 2008-03-09 18:13:49Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ (function() { @@ -12,7 +15,7 @@ ed.windowManager.open({ file : url + '/searchreplace.htm', width : 420 + parseInt(ed.getLang('searchreplace.delta_width', 0)), - height : 160 + parseInt(ed.getLang('searchreplace.delta_height', 0)), + height : 170 + parseInt(ed.getLang('searchreplace.delta_height', 0)), inline : 1, auto_focus : 0 }, { diff --git a/program/js/tiny_mce/plugins/searchreplace/js/searchreplace.js b/program/js/tiny_mce/plugins/searchreplace/js/searchreplace.js index a8585cccc..c0a624329 100644 --- a/program/js/tiny_mce/plugins/searchreplace/js/searchreplace.js +++ b/program/js/tiny_mce/plugins/searchreplace/js/searchreplace.js @@ -75,6 +75,10 @@ var SearchReplaceDialog = { r.select(); replace(); fo = 1; + + if (b) { + r.moveEnd("character", -(rs.length)); // Otherwise will loop forever + } } tinyMCEPopup.storeSelection(); diff --git a/program/js/tiny_mce/plugins/searchreplace/searchreplace.htm b/program/js/tiny_mce/plugins/searchreplace/searchreplace.htm index 0b42486b6..d0424cfc9 100644 --- a/program/js/tiny_mce/plugins/searchreplace/searchreplace.htm +++ b/program/js/tiny_mce/plugins/searchreplace/searchreplace.htm @@ -89,15 +89,10 @@
-
- - - -
- -
- -
+ + + +
diff --git a/program/js/tiny_mce/plugins/table/cell.htm b/program/js/tiny_mce/plugins/table/cell.htm index 1fabc8dc2..d243e1d83 100644 --- a/program/js/tiny_mce/plugins/table/cell.htm +++ b/program/js/tiny_mce/plugins/table/cell.htm @@ -170,13 +170,8 @@ -
-
-
- -
- -
+ + diff --git a/program/js/tiny_mce/plugins/table/editor_plugin.js b/program/js/tiny_mce/plugins/table/editor_plugin.js index 806ef288f..39f2c694b 100644 --- a/program/js/tiny_mce/plugins/table/editor_plugin.js +++ b/program/js/tiny_mce/plugins/table/editor_plugin.js @@ -1 +1 @@ -(function(){var b=tinymce.each;function a(d,e){var f=e.ownerDocument,c=f.createRange(),g;c.setStartBefore(e);c.setEnd(d.endContainer,d.endOffset);g=f.createElement("body");g.appendChild(c.cloneContents());return g.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length==0}tinymce.create("tinymce.plugins.TablePlugin",{init:function(c,d){var e=this;e.editor=c;e.url=d;b([["table","table.desc","mceInsertTable",true],["delete_table","table.del","mceTableDelete"],["delete_col","table.delete_col_desc","mceTableDeleteCol"],["delete_row","table.delete_row_desc","mceTableDeleteRow"],["col_after","table.col_after_desc","mceTableInsertColAfter"],["col_before","table.col_before_desc","mceTableInsertColBefore"],["row_after","table.row_after_desc","mceTableInsertRowAfter"],["row_before","table.row_before_desc","mceTableInsertRowBefore"],["row_props","table.row_desc","mceTableRowProps",true],["cell_props","table.cell_desc","mceTableCellProps",true],["split_cells","table.split_cells_desc","mceTableSplitCells",true],["merge_cells","table.merge_cells_desc","mceTableMergeCells",true]],function(f){c.addButton(f[0],{title:f[1],cmd:f[2],ui:f[3]})});if(c.getParam("inline_styles")){c.onPreProcess.add(function(f,h){var g=f.dom;b(g.select("table",h.node),function(j){var i;if(i=g.getAttrib(j,"width")){g.setStyle(j,"width",i);g.setAttrib(j,"width")}if(i=g.getAttrib(j,"height")){g.setStyle(j,"height",i);g.setAttrib(j,"height")}})})}c.onInit.add(function(){if(!tinymce.isIE&&c.getParam("forced_root_block")){function f(){var g=c.getBody().lastChild;if(g&&g.nodeName=="TABLE"){c.dom.add(c.getBody(),"p",null,'
')}}if(tinymce.isGecko){c.onKeyDown.add(function(h,j){var g,i,k=h.dom;if(j.keyCode==37||j.keyCode==38){g=h.selection.getRng();i=k.getParent(g.startContainer,"table");if(i&&h.getBody().firstChild==i){if(a(g,i)){g=k.createRng();g.setStartBefore(i);g.setEndBefore(i);h.selection.setRng(g);j.preventDefault()}}}})}c.onKeyUp.add(f);c.onSetContent.add(f);c.onVisualAid.add(f);c.onPreProcess.add(function(g,i){var h=i.node.lastChild;if(h&&h.childNodes.length==1&&h.firstChild.nodeName=="BR"){g.dom.remove(h)}});f()}if(c&&c.plugins.contextmenu){c.plugins.contextmenu.onContextMenu.add(function(i,g,k){var l,j=c.selection,h=j.getNode()||c.getBody();if(c.dom.getParent(k,"td")||c.dom.getParent(k,"th")){g.removeAll();if(h.nodeName=="A"&&!c.dom.getAttrib(h,"name")){g.add({title:"advanced.link_desc",icon:"link",cmd:c.plugins.advlink?"mceAdvLink":"mceLink",ui:true});g.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"});g.addSeparator()}if(h.nodeName=="IMG"&&h.className.indexOf("mceItem")==-1){g.add({title:"advanced.image_desc",icon:"image",cmd:c.plugins.advimage?"mceAdvImage":"mceImage",ui:true});g.addSeparator()}g.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",ui:true,value:{action:"insert"}});g.add({title:"table.props_desc",icon:"table_props",cmd:"mceInsertTable",ui:true});g.add({title:"table.del",icon:"delete_table",cmd:"mceTableDelete",ui:true});g.addSeparator();l=g.addMenu({title:"table.cell"});l.add({title:"table.cell_desc",icon:"cell_props",cmd:"mceTableCellProps",ui:true});l.add({title:"table.split_cells_desc",icon:"split_cells",cmd:"mceTableSplitCells",ui:true});l.add({title:"table.merge_cells_desc",icon:"merge_cells",cmd:"mceTableMergeCells",ui:true});l=g.addMenu({title:"table.row"});l.add({title:"table.row_desc",icon:"row_props",cmd:"mceTableRowProps",ui:true});l.add({title:"table.row_before_desc",icon:"row_before",cmd:"mceTableInsertRowBefore"});l.add({title:"table.row_after_desc",icon:"row_after",cmd:"mceTableInsertRowAfter"});l.add({title:"table.delete_row_desc",icon:"delete_row",cmd:"mceTableDeleteRow"});l.addSeparator();l.add({title:"table.cut_row_desc",icon:"cut",cmd:"mceTableCutRow"});l.add({title:"table.copy_row_desc",icon:"copy",cmd:"mceTableCopyRow"});l.add({title:"table.paste_row_before_desc",icon:"paste",cmd:"mceTablePasteRowBefore"});l.add({title:"table.paste_row_after_desc",icon:"paste",cmd:"mceTablePasteRowAfter"});l=g.addMenu({title:"table.col"});l.add({title:"table.col_before_desc",icon:"col_before",cmd:"mceTableInsertColBefore"});l.add({title:"table.col_after_desc",icon:"col_after",cmd:"mceTableInsertColAfter"});l.add({title:"table.delete_col_desc",icon:"delete_col",cmd:"mceTableDeleteCol"})}else{g.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",ui:true})}})}});c.onKeyDown.add(function(f,g){if(g.keyCode==9&&f.dom.getParent(f.selection.getNode(),"TABLE")){if(!tinymce.isGecko&&!tinymce.isOpera){tinyMCE.execInstanceCommand(f.editorId,"mceTableMoveToNextRow",true);return tinymce.dom.Event.cancel(g)}f.undoManager.add()}});if(!tinymce.isIE){if(c.getParam("table_selection",true)){c.onClick.add(function(f,g){g=g.target;if(g.nodeName==="TABLE"){f.selection.select(g)}})}}c.onNodeChange.add(function(g,f,i){var h=g.dom.getParent(i,"td,th,caption");f.setActive("table",i.nodeName==="TABLE"||!!h);if(h&&h.nodeName==="CAPTION"){h=null}f.setDisabled("delete_table",!h);f.setDisabled("delete_col",!h);f.setDisabled("delete_table",!h);f.setDisabled("delete_row",!h);f.setDisabled("col_after",!h);f.setDisabled("col_before",!h);f.setDisabled("row_after",!h);f.setDisabled("row_before",!h);f.setDisabled("row_props",!h);f.setDisabled("cell_props",!h);f.setDisabled("split_cells",!h||(parseInt(g.dom.getAttrib(h,"colspan","1"))<2&&parseInt(g.dom.getAttrib(h,"rowspan","1"))<2));f.setDisabled("merge_cells",!h)});if(!tinymce.isIE){c.onBeforeSetContent.add(function(f,g){if(g.initial){g.content=g.content.replace(/<(td|th)([^>]+|)>\s*<\/(td|th)>/g,tinymce.isOpera?"<$1$2> ":'<$1$2>
')}})}},execCommand:function(f,e,g){var d=this.editor,c;switch(f){case"mceTableMoveToNextRow":case"mceInsertTable":case"mceTableRowProps":case"mceTableCellProps":case"mceTableSplitCells":case"mceTableMergeCells":case"mceTableInsertRowBefore":case"mceTableInsertRowAfter":case"mceTableDeleteRow":case"mceTableInsertColBefore":case"mceTableInsertColAfter":case"mceTableDeleteCol":case"mceTableCutRow":case"mceTableCopyRow":case"mceTablePasteRowBefore":case"mceTablePasteRowAfter":case"mceTableDelete":d.execCommand("mceBeginUndoLevel");this._doExecCommand(f,e,g);d.execCommand("mceEndUndoLevel");return true}return false},getInfo:function(){return{longname:"Tables",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/table",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_doExecCommand:function(s,aa,af){var W=this.editor,av=W,h=this.url;var o=W.selection.getNode();var X=W.dom.getParent(o,"tr");var ar=W.dom.getParent(o,"td,th");var G=W.dom.getParent(o,"table");var l=W.contentWindow.document;var aw=G?G.getAttribute("border"):"";if(X&&ar==null){ar=X.cells[0]}function aq(y,x){for(var ay=0;ay0&&aq(y[ay],x)){return true}if(y[ay]==x){return true}}return false}function ak(x,i){var y;ae=f(G);x=x||0;i=i||0;x=Math.max(p.cellindex+x,0);i=Math.max(p.rowindex+i,0);W.execCommand("mceRepaint");y=e(ae,i,x);if(y){W.selection.select(y.firstChild||y);W.selection.collapse(1)}}function ai(){var i=l.createElement("td");if(!tinymce.isIE){i.innerHTML='
'}}function k(y){var x=W.dom.getAttrib(y,"colspan");var i=W.dom.getAttrib(y,"rowspan");x=x==""?1:parseInt(x);i=i==""?1:parseInt(i);return{colspan:x,rowspan:i}}function am(ay,aA){var i,az;for(az=0;az1){for(var aA=aF;aA1){az.rowSpan=aC.rowspan+1}aD=az}C(G)}}function P(x,i){while((x=x.previousSibling)!=null){if(x.nodeName==i){return x}}return null}function ag(ay,az){var x=az.split(",");while((ay=ay.nextSibling)!=null){for(var y=0;y1){do{var i=ag(az,"TD,TH");if(az._delete){az.parentNode.removeChild(az)}}while((az=i)!=null)}}while((y=x)!=null)}function q(ay,aB,aA){ay.rowSpan=1;var x=ag(aB,"TR");for(var az=1;az'}if(tinymce.isIE){x.insertBefore(y,x.cells(ay.cellIndex))}else{x.insertBefore(y,x.cells[ay.cellIndex])}x=ag(x,"TR")}}function T(aG,aI,aC){var y=f(aI);var ay=aC.cloneNode(false);var aH=am(y,aC.cells[0]);var aD=null;var aB=W.dom.getAttrib(aI,"border");var aA=null;for(var aF=0;aA=e(y,aH.rowindex,aF);aF++){var aE=null;if(aD!=aA){for(var az=0;az'}}aE.colSpan=1;aE.rowSpan=1;ay.appendChild(aE);aD=aA}return ay}switch(s){case"mceTableMoveToNextRow":var M=B(G,ar);if(!M){W.execCommand("mceTableInsertRowAfter",ar);M=B(G,ar)}W.selection.select(M);W.selection.collapse(true);return true;case"mceTableRowProps":if(X==null){return true}if(aa){W.windowManager.open({url:h+"/row.htm",width:400+parseInt(W.getLang("table.rowprops_delta_width",0)),height:295+parseInt(W.getLang("table.rowprops_delta_height",0)),inline:1},{plugin_url:h})}return true;case"mceTableCellProps":if(ar==null){return true}if(aa){W.windowManager.open({url:h+"/cell.htm",width:400+parseInt(W.getLang("table.cellprops_delta_width",0)),height:295+parseInt(W.getLang("table.cellprops_delta_height",0)),inline:1},{plugin_url:h})}return true;case"mceInsertTable":if(aa){W.windowManager.open({url:h+"/table.htm",width:400+parseInt(W.getLang("table.table_delta_width",0)),height:320+parseInt(W.getLang("table.table_delta_height",0)),inline:1},{plugin_url:h,action:af?af.action:0})}return true;case"mceTableDelete":var H=W.dom.getParent(W.selection.getNode(),"table");if(H){H.parentNode.removeChild(H);W.execCommand("mceRepaint")}return true;case"mceTableSplitCells":case"mceTableMergeCells":case"mceTableInsertRowBefore":case"mceTableInsertRowAfter":case"mceTableDeleteRow":case"mceTableInsertColBefore":case"mceTableInsertColAfter":case"mceTableDeleteCol":case"mceTableCutRow":case"mceTableCopyRow":case"mceTablePasteRowBefore":case"mceTablePasteRowAfter":if(!G){return true}if(X&&G!=X.parentNode){G=X.parentNode}if(G&&X){switch(s){case"mceTableCutRow":if(!X||!ar){return true}W.tableRowClipboard=T(l,G,X);W.execCommand("mceTableDeleteRow");break;case"mceTableCopyRow":if(!X||!ar){return true}W.tableRowClipboard=T(l,G,X);break;case"mceTablePasteRowBefore":if(!X||!ar){return true}var w=W.tableRowClipboard.cloneNode(true);var j=P(X,"TR");if(j!=null){n(G,j,j.cells[0],w)}X.parentNode.insertBefore(w,X);break;case"mceTablePasteRowAfter":if(!X||!ar){return true}var Y=ag(X,"TR");var w=W.tableRowClipboard.cloneNode(true);n(G,X,ar,w);if(Y==null){X.parentNode.appendChild(w)}else{Y.parentNode.insertBefore(w,Y)}break;case"mceTableInsertRowBefore":if(!X||!ar){return true}var ae=f(G);var p=am(ae,ar);var w=l.createElement("tr");var v=null;p.rowindex--;if(p.rowindex<0){p.rowindex=0}for(var ad=0;ar=e(ae,p.rowindex,ad);ad++){if(ar!=v){var F=k(ar);if(F.rowspan==1){var K=l.createElement("td");if(!tinymce.isIE){K.innerHTML='
'}K.colSpan=ar.colSpan;w.appendChild(K)}else{ar.rowSpan=F.rowspan+1}v=ar}}X.parentNode.insertBefore(w,X);ak(0,1);break;case"mceTableInsertRowAfter":if(!X||!ar){return true}var ae=f(G);var p=am(ae,ar);var w=l.createElement("tr");var v=null;for(var ad=0;ar=e(ae,p.rowindex,ad);ad++){if(ar!=v){var F=k(ar);if(F.rowspan==1){var K=l.createElement("td");if(!tinymce.isIE){K.innerHTML='
'}K.colSpan=ar.colSpan;w.appendChild(K)}else{ar.rowSpan=F.rowspan+1}v=ar}}if(w.hasChildNodes()){var Y=ag(X,"TR");if(Y){Y.parentNode.insertBefore(w,Y)}else{G.appendChild(w)}}ak(0,1);break;case"mceTableDeleteRow":if(!X||!ar){return true}var ae=f(G);var p=am(ae,ar);if(ae.length==1&&G.nodeName=="TBODY"){W.dom.remove(W.dom.getParent(G,"table"));return true}var E=X.cells;var Y=ag(X,"TR");for(var ad=0;ad1){var K=E[ad].cloneNode(true);var F=k(E[ad]);K.rowSpan=F.rowspan-1;var al=Y.cells[ad];if(al==null){Y.appendChild(K)}else{Y.insertBefore(K,al)}}}var v=null;for(var ad=0;ar=e(ae,p.rowindex,ad);ad++){if(ar!=v){var F=k(ar);if(F.rowspan>1){ar.rowSpan=F.rowspan-1}else{X=ar.parentNode;if(X.parentNode){X._delete=true}}v=ar}}C(G);ak(0,-1);break;case"mceTableInsertColBefore":if(!X||!ar){return true}var ae=f(W.dom.getParent(G,"table"));var p=am(ae,ar);var v=null;for(var ab=0;ar=e(ae,ab,p.cellindex);ab++){if(ar!=v){var F=k(ar);if(F.colspan==1){var K=l.createElement(ar.nodeName);if(!tinymce.isIE){K.innerHTML='
'}K.rowSpan=ar.rowSpan;ar.parentNode.insertBefore(K,ar)}else{ar.colSpan++}v=ar}}ak();break;case"mceTableInsertColAfter":if(!X||!ar){return true}var ae=f(W.dom.getParent(G,"table"));var p=am(ae,ar);var v=null;for(var ab=0;ar=e(ae,ab,p.cellindex);ab++){if(ar!=v){var F=k(ar);if(F.colspan==1){var K=l.createElement(ar.nodeName);if(!tinymce.isIE){K.innerHTML='
'}K.rowSpan=ar.rowSpan;var al=ag(ar,"TD,TH");if(al==null){ar.parentNode.appendChild(K)}else{al.parentNode.insertBefore(K,al)}}else{ar.colSpan++}v=ar}}ak(1);break;case"mceTableDeleteCol":if(!X||!ar){return true}var ae=f(G);var p=am(ae,ar);var v=null;if((ae.length>1&&ae[0].length<=1)&&G.nodeName=="TBODY"){W.dom.remove(W.dom.getParent(G,"table"));return true}for(var ab=0;ar=e(ae,ab,p.cellindex);ab++){if(ar!=v){var F=k(ar);if(F.colspan>1){ar.colSpan=F.colspan-1}else{if(ar.parentNode){ar.parentNode.removeChild(ar)}}v=ar}}ak(-1);break;case"mceTableSplitCells":if(!X||!ar){return true}var m=k(ar);var D=m.colspan;var I=m.rowspan;if(D>1||I>1){ar.colSpan=1;for(var an=1;an'}X.insertBefore(K,ag(ar,"TD,TH"));if(I>1){q(K,X,I)}}q(ar,X,I)}G=W.dom.getParent(W.selection.getNode(),"table");break;case"mceTableMergeCells":var ap=[];var S=W.selection.getSel();var ae=f(G);if(tinymce.isIE||S.rangeCount==1){if(aa){var u=k(ar);W.windowManager.open({url:h+"/merge_cells.htm",width:240+parseInt(W.getLang("table.merge_cells_delta_width",0)),height:110+parseInt(W.getLang("table.merge_cells_delta_height",0)),inline:1},{action:"update",numcols:u.colspan,numrows:u.rowspan,plugin_url:h});return true}else{var V=parseInt(af.numrows);var d=parseInt(af.numcols);var p=am(ae,ar);if((""+V)=="NaN"){V=1}if((""+d)=="NaN"){d=1}var c=G.rows;for(var ab=p.rowindex;ab0){ap[ap.length]=ah}var g=e(ae,p.rowindex,p.cellindex);b(av.dom.select("br",g),function(y,x){if(x>0&&av.dom.getAttrib("mce_bogus")){av.dom.remove(y)}})}}}else{var E=[];var S=W.selection.getSel();var Z=null;var ao=null;var A=-1,ax=-1,z,au;if(S.rangeCount<2){return true}for(var an=0;an0){ap[ap.length]=ah}}var ao=[];var Z=null;for(var ab=0;abr){r=J}U=-1}var R=-1;for(var ad=0;adt){t=N}R=-1}ar=ap[0][0];ar.rowSpan=t;ar.colSpan=r;for(var ab=0;ab0)){ar.innerHTML+=Q}if(ap[ab][ad]!=ar&&!ap[ab][ad]._deleted){var p=am(ae,ap[ab][ad]);var at=ap[ab][ad].parentNode;at.removeChild(ap[ab][ad]);ap[ab][ad]._deleted=true;if(!at.hasChildNodes()){at.parentNode.removeChild(at);var ac=null;for(var ad=0;cellElm=e(ae,p.rowindex,ad);ad++){if(cellElm!=ac&&cellElm.rowSpan>1){cellElm.rowSpan--}ac=cellElm}if(ar.rowSpan>1){ar.rowSpan--}}}}}b(av.dom.select("br",ar),function(y,x){if(x>0&&av.dom.getAttrib(y,"mce_bogus")){av.dom.remove(y)}});break}G=W.dom.getParent(W.selection.getNode(),"table");W.addVisual(G);W.nodeChanged()}return true}return false}});tinymce.PluginManager.add("table",tinymce.plugins.TablePlugin)})(); \ No newline at end of file +(function(b){var c=b.each;function a(E,D,H){var e,I,A,n;r();n=D.getParent(H.getStart(),"th,td");if(n){I=C(n);A=F();n=v(I.x,I.y)}function r(){var J=0;e=[];c(["thead","tbody","tfoot"],function(K){var L=D.select(K+" tr",E);c(L,function(M,N){N+=J;c(D.select("td,th",M),function(T,O){var P,Q,R,S;if(e[N]){while(e[N][O]){O++}}R=g(T,"rowspan");S=g(T,"colspan");for(Q=N;Q'}return false}},"childNodes");J=J.cloneNode(false);J.rowSpan=J.colSpan=1;if(K){J.appendChild(K)}else{if(!b.isIE){J.innerHTML='
'}}return J}function p(){var J=D.createRng();c(D.select("tr",E),function(K){if(K.cells.length==0){D.remove(K)}});if(D.select("tr",E).length==0){J.setStartAfter(E);J.setEndAfter(E);H.setRng(J);D.remove(E);return}c(D.select("thead,tbody,tfoot",E),function(K){if(K.rows.length==0){D.remove(K)}});r();row=e[Math.min(e.length-1,I.y)];if(row){H.select(row[Math.min(row.length-1,I.x)].elm,true);H.collapse(true)}}function s(P,N,R,O){var M,K,J,L,Q;M=e[N][P].elm.parentNode;for(J=1;J<=R;J++){M=D.getNext(M,"tr");if(M){for(K=P;K>=0;K--){Q=e[N+J][K].elm;if(Q.parentNode==M){for(L=1;L<=O;L++){D.insertAfter(d(Q),Q)}break}}if(K==-1){for(L=1;L<=O;L++){M.insertBefore(d(M.cells[0]),M.cells[0])}}}}}function z(){c(e,function(J,K){c(J,function(M,L){var P,O,Q,N;if(h(M)){M=M.elm;P=g(M,"colspan");O=g(M,"rowspan");if(P>1||O>1){M.colSpan=M.rowSpan=1;for(N=0;N1){O.rowSpan=rowSpan+1;continue}}else{if(J>0&&e[J-1][N]){R=e[J-1][N].elm;rowSpan=g(R,"rowspan");if(rowSpan>1){R.rowSpan=rowSpan+1;continue}}}K=d(O);K.colSpan=O.colSpan;Q.appendChild(K);L=O}}if(Q.hasChildNodes()){if(!M){D.insertAfter(Q,P)}else{P.parentNode.insertBefore(Q,P)}}}function f(K){var L,J;c(e,function(M,N){c(M,function(P,O){if(h(P)){L=O;if(K){return false}}});if(K){return !L}});c(e,function(P,Q){var M=P[L].elm,N,O;if(M!=J){O=g(M,"colspan");N=g(M,"rowspan");if(O==1){if(!K){D.insertAfter(d(M),M);s(L,Q,N-1,O)}else{M.parentNode.insertBefore(d(M),M);s(L,Q,N-1,O)}}else{M.colSpan++}J=M}})}function m(){var J=[];c(e,function(K,L){c(K,function(N,M){if(h(N)&&b.inArray(J,M)===-1){c(e,function(Q){var O=Q[M].elm,P;P=g(O,"colspan");if(P>1){O.colSpan=P-1}else{D.remove(O)}});J.push(M)}})});p()}function l(){var K;function J(N){var M,O,L;M=D.getNext(N,"tr");c(N.cells,function(P){var Q=g(P,"rowspan");if(Q>1){P.rowSpan=Q-1;O=C(P);s(O.x,O.y,1,1)}});O=C(N.cells[0]);c(e[O.y],function(P){var Q;P=P.elm;if(P!=L){Q=g(P,"rowspan");if(Q<=1){D.remove(P)}else{P.rowSpan=Q-1}L=P}})}K=j();c(K.reverse(),function(L){J(L)});p()}function B(){var J=j();D.remove(J);p();return J}function G(){var J=j();c(J,function(L,K){J[K]=L.cloneNode(true)});return J}function w(L,K){var M=j(),J=M[K?0:M.length-1],N=J.cells.length;c(e,function(P){var O;N=0;c(P,function(R,Q){if(R.real){N+=R.colspan}if(R.elm.parentNode==J){O=1}});if(O){return false}});if(!K){L.reverse()}c(L,function(Q){var P=Q.cells.length,O;for(i=0;iK){K=O}if(N>J){J=N}if(P.real){R=P.colspan-1;Q=P.rowspan-1;if(R){if(O+R>K){K=O+R}}if(Q){if(N+Q>J){J=N+Q}}}}})});return{x:K,y:J}}function t(P){var M,L,R,Q,K,J,N,O;A=C(P);if(I&&A){M=Math.min(I.x,A.x);L=Math.min(I.y,A.y);R=Math.max(I.x,A.x);Q=Math.max(I.y,A.y);K=R;J=Q;for(y=L;y<=J;y++){P=e[y][M];if(!P.real){if(M-(P.colspan-1)K){K=x+N}}if(O){if(y+O>J){J=y+O}}}}}D.removeClass(D.select("td.mceSelected,th.mceSelected"),"mceSelected");for(y=L;y<=J;y++){for(x=M;x<=K;x++){D.addClass(e[y][x].elm,"mceSelected")}}}}b.extend(this,{deleteTable:q,split:z,merge:o,insertRow:k,insertCol:f,deleteCols:m,deleteRows:l,cutRows:B,copyRows:G,pasteRows:w,getPos:C,setStartCell:u,setEndCell:t})}b.create("tinymce.plugins.TablePlugin",{init:function(e,f){var d,j;function h(m){var l=e.selection,k=e.dom.getParent(m||l.getNode(),"table");if(k){return new a(k,e.dom,l)}}function g(){e.getBody().style.webkitUserSelect="";e.dom.removeClass(e.dom.select("td.mceSelected,th.mceSelected"),"mceSelected")}c([["table","table.desc","mceInsertTable",true],["delete_table","table.del","mceTableDelete"],["delete_col","table.delete_col_desc","mceTableDeleteCol"],["delete_row","table.delete_row_desc","mceTableDeleteRow"],["col_after","table.col_after_desc","mceTableInsertColAfter"],["col_before","table.col_before_desc","mceTableInsertColBefore"],["row_after","table.row_after_desc","mceTableInsertRowAfter"],["row_before","table.row_before_desc","mceTableInsertRowBefore"],["row_props","table.row_desc","mceTableRowProps",true],["cell_props","table.cell_desc","mceTableCellProps",true],["split_cells","table.split_cells_desc","mceTableSplitCells",true],["merge_cells","table.merge_cells_desc","mceTableMergeCells",true]],function(k){e.addButton(k[0],{title:k[1],cmd:k[2],ui:k[3]})});if(!b.isIE){e.onClick.add(function(k,l){l=l.target;if(l.nodeName==="TABLE"){k.selection.select(l)}})}e.onNodeChange.add(function(l,k,o){var m;o=l.selection.getStart();m=l.dom.getParent(o,"td,th,caption");k.setActive("table",o.nodeName==="TABLE"||!!m);if(m&&m.nodeName==="CAPTION"){m=0}k.setDisabled("delete_table",!m);k.setDisabled("delete_col",!m);k.setDisabled("delete_table",!m);k.setDisabled("delete_row",!m);k.setDisabled("col_after",!m);k.setDisabled("col_before",!m);k.setDisabled("row_after",!m);k.setDisabled("row_before",!m);k.setDisabled("row_props",!m);k.setDisabled("cell_props",!m);k.setDisabled("split_cells",!m);k.setDisabled("merge_cells",!m)});e.onInit.add(function(l){var k,o,p=l.dom,m;d=l.windowManager;l.onMouseDown.add(function(q,r){if(r.button!=2){g();o=p.getParent(r.target,"td,th");k=p.getParent(o,"table")}});p.bind(l.getDoc(),"mouseover",function(t){var r,q,s=t.target;if(o&&(m||s!=o)&&(s.nodeName=="TD"||s.nodeName=="TH")){q=p.getParent(s,"table");if(q==k){if(!m){m=h(q);m.setStartCell(o);l.getBody().style.webkitUserSelect="none"}m.setEndCell(s)}r=l.selection.getSel();if(r.removeAllRanges){r.removeAllRanges()}else{r.empty()}t.preventDefault()}});l.onMouseUp.add(function(z,A){var r,t=z.selection,B,C=t.getSel(),q,u,s,w;if(o){if(m){z.getBody().style.webkitUserSelect=""}function v(D,F){var E=new b.dom.TreeWalker(D,D);do{if(D.nodeType==3&&b.trim(D.nodeValue).length!=0){if(F){r.setStart(D,0)}else{r.setEnd(D,D.nodeValue.length)}return}if(D.nodeName=="BR"){if(F){r.setStartBefore(D)}else{r.setEndBefore(D)}return}}while(D=(F?E.next():E.prev()))}B=p.select("td.mceSelected,th.mceSelected");if(B.length>0){r=p.createRng();u=B[0];w=B[B.length-1];v(u,1);q=new b.dom.TreeWalker(u,p.getParent(B[0],"table"));do{if(u.nodeName=="TD"||u.nodeName=="TH"){if(!p.hasClass(u,"mceSelected")){break}s=u}}while(u=q.next());v(s);t.setRng(r)}z.nodeChanged();o=m=k=null}});l.onKeyUp.add(function(q,r){g()});if(l&&l.plugins.contextmenu){l.plugins.contextmenu.onContextMenu.add(function(s,q,u){var v,t=l.selection,r=t.getNode()||l.getBody();if(l.dom.getParent(u,"td")||l.dom.getParent(u,"th")){q.removeAll();if(r.nodeName=="A"&&!l.dom.getAttrib(r,"name")){q.add({title:"advanced.link_desc",icon:"link",cmd:l.plugins.advlink?"mceAdvLink":"mceLink",ui:true});q.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"});q.addSeparator()}if(r.nodeName=="IMG"&&r.className.indexOf("mceItem")==-1){q.add({title:"advanced.image_desc",icon:"image",cmd:l.plugins.advimage?"mceAdvImage":"mceImage",ui:true});q.addSeparator()}q.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",value:{action:"insert"}});q.add({title:"table.props_desc",icon:"table_props",cmd:"mceInsertTable"});q.add({title:"table.del",icon:"delete_table",cmd:"mceTableDelete"});q.addSeparator();v=q.addMenu({title:"table.cell"});v.add({title:"table.cell_desc",icon:"cell_props",cmd:"mceTableCellProps"});v.add({title:"table.split_cells_desc",icon:"split_cells",cmd:"mceTableSplitCells"});v.add({title:"table.merge_cells_desc",icon:"merge_cells",cmd:"mceTableMergeCells"});v=q.addMenu({title:"table.row"});v.add({title:"table.row_desc",icon:"row_props",cmd:"mceTableRowProps"});v.add({title:"table.row_before_desc",icon:"row_before",cmd:"mceTableInsertRowBefore"});v.add({title:"table.row_after_desc",icon:"row_after",cmd:"mceTableInsertRowAfter"});v.add({title:"table.delete_row_desc",icon:"delete_row",cmd:"mceTableDeleteRow"});v.addSeparator();v.add({title:"table.cut_row_desc",icon:"cut",cmd:"mceTableCutRow"});v.add({title:"table.copy_row_desc",icon:"copy",cmd:"mceTableCopyRow"});v.add({title:"table.paste_row_before_desc",icon:"paste",cmd:"mceTablePasteRowBefore"}).setDisabled(!j);v.add({title:"table.paste_row_after_desc",icon:"paste",cmd:"mceTablePasteRowAfter"}).setDisabled(!j);v=q.addMenu({title:"table.col"});v.add({title:"table.col_before_desc",icon:"col_before",cmd:"mceTableInsertColBefore"});v.add({title:"table.col_after_desc",icon:"col_after",cmd:"mceTableInsertColAfter"});v.add({title:"table.delete_col_desc",icon:"delete_col",cmd:"mceTableDeleteCol"})}else{q.add({title:"table.desc",icon:"table",cmd:"mceInsertTable"})}})}if(!b.isIE){function n(){var q;for(q=l.getBody().lastChild;q&&q.nodeType==3&&!q.nodeValue.length;q=q.previousSibling){}if(q&&q.nodeName=="TABLE"){l.dom.add(l.getBody(),"p",null,'
')}}if(b.isGecko){l.onKeyDown.add(function(r,t){var q,s,u=r.dom;if(t.keyCode==37||t.keyCode==38){q=r.selection.getRng();s=u.getParent(q.startContainer,"table");if(s&&r.getBody().firstChild==s){if(isAtStart(q,s)){q=u.createRng();q.setStartBefore(s);q.setEndBefore(s);r.selection.setRng(q);t.preventDefault()}}}})}l.onKeyUp.add(n);l.onSetContent.add(n);l.onVisualAid.add(n);l.onPreProcess.add(function(q,s){var r=s.node.lastChild;if(r&&r.childNodes.length==1&&r.firstChild.nodeName=="BR"){q.dom.remove(r)}});n()}});c({mceTableSplitCells:function(k){k.split()},mceTableMergeCells:function(l){var m,n,k;k=e.dom.getParent(e.selection.getNode(),"th,td");if(k){m=k.rowSpan;n=k.colSpan}if(!e.dom.select("td.mceSelected,th.mceSelected").length){d.open({url:f+"/merge_cells.htm",width:240+parseInt(e.getLang("table.merge_cells_delta_width",0)),height:110+parseInt(e.getLang("table.merge_cells_delta_height",0)),inline:1},{rows:m,cols:n,onaction:function(o){l.merge(k,o.cols,o.rows)},plugin_url:f})}else{l.merge()}},mceTableInsertRowBefore:function(k){k.insertRow(true)},mceTableInsertRowAfter:function(k){k.insertRow()},mceTableInsertColBefore:function(k){k.insertCol(true)},mceTableInsertColAfter:function(k){k.insertCol()},mceTableDeleteCol:function(k){k.deleteCols()},mceTableDeleteRow:function(k){k.deleteRows()},mceTableCutRow:function(k){j=k.cutRows()},mceTableCopyRow:function(k){j=k.copyRows()},mceTablePasteRowBefore:function(k){k.pasteRows(j,true)},mceTablePasteRowAfter:function(k){k.pasteRows(j)},mceTableDelete:function(k){k.deleteTable()}},function(l,k){e.addCommand(k,function(){var m=h();if(m){l(m);e.execCommand("mceRepaint");g()}})});c({mceInsertTable:function(k){d.open({url:f+"/table.htm",width:400+parseInt(e.getLang("table.table_delta_width",0)),height:320+parseInt(e.getLang("table.table_delta_height",0)),inline:1},{plugin_url:f,action:k?k.action:0})},mceTableRowProps:function(){d.open({url:f+"/row.htm",width:400+parseInt(e.getLang("table.rowprops_delta_width",0)),height:295+parseInt(e.getLang("table.rowprops_delta_height",0)),inline:1},{plugin_url:f})},mceTableCellProps:function(){d.open({url:f+"/cell.htm",width:400+parseInt(e.getLang("table.cellprops_delta_width",0)),height:295+parseInt(e.getLang("table.cellprops_delta_height",0)),inline:1},{plugin_url:f})}},function(l,k){e.addCommand(k,function(m,n){l(n)})})}});b.PluginManager.add("table",b.plugins.TablePlugin)})(tinymce); \ No newline at end of file diff --git a/program/js/tiny_mce/plugins/table/editor_plugin_src.js b/program/js/tiny_mce/plugins/table/editor_plugin_src.js index 87b10556f..2260f34a3 100644 --- a/program/js/tiny_mce/plugins/table/editor_plugin_src.js +++ b/program/js/tiny_mce/plugins/table/editor_plugin_src.js @@ -1,1202 +1,1118 @@ /** - * $Id: editor_plugin_src.js 1209 2009-08-20 12:35:10Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ -(function() { +(function(tinymce) { var each = tinymce.each; - // Checks if the selection/caret is at the start of the specified block element - function isAtStart(rng, par) { - var doc = par.ownerDocument, rng2 = doc.createRange(), elm; + /** + * Table Grid class. + */ + function TableGrid(table, dom, selection) { + var grid, startPos, endPos, selectedCell; + + buildGrid(); + selectedCell = dom.getParent(selection.getStart(), 'th,td'); + if (selectedCell) { + startPos = getPos(selectedCell); + endPos = findEndPos(); + selectedCell = getCell(startPos.x, startPos.y); + } - rng2.setStartBefore(par); - rng2.setEnd(rng.endContainer, rng.endOffset); + function buildGrid() { + var startY = 0; - elm = doc.createElement('body'); - elm.appendChild(rng2.cloneContents()); + grid = []; - // Check for text characters of other elements that should be treated as content - return elm.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi, '-').replace(/<[^>]+>/g, '').length == 0; - }; + each(['thead', 'tbody', 'tfoot'], function(part) { + var rows = dom.select(part + ' tr', table); - tinymce.create('tinymce.plugins.TablePlugin', { - init : function(ed, url) { - var t = this; + each(rows, function(tr, y) { + y += startY; - t.editor = ed; - t.url = url; + each(dom.select('td,th', tr), function(td, x) { + var x2, y2, rowspan, colspan; - // Register buttons - each([ - ['table', 'table.desc', 'mceInsertTable', true], - ['delete_table', 'table.del', 'mceTableDelete'], - ['delete_col', 'table.delete_col_desc', 'mceTableDeleteCol'], - ['delete_row', 'table.delete_row_desc', 'mceTableDeleteRow'], - ['col_after', 'table.col_after_desc', 'mceTableInsertColAfter'], - ['col_before', 'table.col_before_desc', 'mceTableInsertColBefore'], - ['row_after', 'table.row_after_desc', 'mceTableInsertRowAfter'], - ['row_before', 'table.row_before_desc', 'mceTableInsertRowBefore'], - ['row_props', 'table.row_desc', 'mceTableRowProps', true], - ['cell_props', 'table.cell_desc', 'mceTableCellProps', true], - ['split_cells', 'table.split_cells_desc', 'mceTableSplitCells', true], - ['merge_cells', 'table.merge_cells_desc', 'mceTableMergeCells', true] - ], function(c) { - ed.addButton(c[0], {title : c[1], cmd : c[2], ui : c[3]}); - }); - - if (ed.getParam('inline_styles')) { - // Force move of attribs to styles in strict mode - ed.onPreProcess.add(function(ed, o) { - var dom = ed.dom; + // Skip over existing cells produced by rowspan + if (grid[y]) { + while (grid[y][x]) + x++; + } - each(dom.select('table', o.node), function(n) { - var v; + // Get col/rowspan from cell + rowspan = getSpanVal(td, 'rowspan'); + colspan = getSpanVal(td, 'colspan'); - if (v = dom.getAttrib(n, 'width')) { - dom.setStyle(n, 'width', v); - dom.setAttrib(n, 'width'); - } + // Fill out rowspan/colspan right and down + for (y2 = y; y2 < y + rowspan; y2++) { + if (!grid[y2]) + grid[y2] = []; - if (v = dom.getAttrib(n, 'height')) { - dom.setStyle(n, 'height', v); - dom.setAttrib(n, 'height'); + for (x2 = x; x2 < x + colspan; x2++) { + grid[y2][x2] = { + part : part, + real : y2 == y && x2 == x, + elm : td, + rowspan : rowspan, + colspan : colspan + }; + } } }); }); - } - ed.onInit.add(function() { - // Fixes an issue on Gecko where it's impossible to place the caret behind a table - // This fix will force a paragraph element after the table but only when the forced_root_block setting is enabled - if (!tinymce.isIE && ed.getParam('forced_root_block')) { - function fixTableCaretPos() { - var last = ed.getBody().lastChild; + startY += rows.length; + }); + }; - if (last && last.nodeName == 'TABLE') - ed.dom.add(ed.getBody(), 'p', null, '
'); - }; + function getCell(x, y) { + var row; - // Fixes an bug where it's impossible to place the caret before a table in Gecko - // this fix solves it by detecting when the caret is at the beginning of such a table - // and then manually moves the caret infront of the table - if (tinymce.isGecko) { - ed.onKeyDown.add(function(ed, e) { - var rng, table, dom = ed.dom; + row = grid[y]; + if (row) + return row[x]; + }; - // On gecko it's not possible to place the caret before a table - if (e.keyCode == 37 || e.keyCode == 38) { - rng = ed.selection.getRng(); - table = dom.getParent(rng.startContainer, 'table'); + function getSpanVal(td, name) { + return parseInt(td.getAttribute(name) || 1); + }; - if (table && ed.getBody().firstChild == table) { - if (isAtStart(rng, table)) { - rng = dom.createRng(); - - rng.setStartBefore(table); - rng.setEndBefore(table); + function isCellSelected(cell) { + return dom.hasClass(cell.elm, 'mceSelected') || cell == selectedCell; + }; - ed.selection.setRng(rng); + function getSelectedRows() { + var rows = []; - e.preventDefault(); - } - } - } - }); + each(table.rows, function(row) { + each(row.cells, function(cell) { + if (dom.hasClass(cell, 'mceSelected') || cell == selectedCell.elm) { + rows.push(row); + return false; } + }); + }); - ed.onKeyUp.add(fixTableCaretPos); - ed.onSetContent.add(fixTableCaretPos); - ed.onVisualAid.add(fixTableCaretPos); + return rows; + }; - ed.onPreProcess.add(function(ed, o) { - var last = o.node.lastChild; + function deleteTable() { + var rng = dom.createRng(); - if (last && last.childNodes.length == 1 && last.firstChild.nodeName == 'BR') - ed.dom.remove(last); - }); + rng.setStartAfter(table); + rng.setEndAfter(table); - fixTableCaretPos(); - } + selection.setRng(rng); - if (ed && ed.plugins.contextmenu) { - ed.plugins.contextmenu.onContextMenu.add(function(th, m, e) { - var sm, se = ed.selection, el = se.getNode() || ed.getBody(); + dom.remove(table); + }; - if (ed.dom.getParent(e, 'td') || ed.dom.getParent(e, 'th')) { - m.removeAll(); + function cloneCell(cell) { + var formatNode; - if (el.nodeName == 'A' && !ed.dom.getAttrib(el, 'name')) { - m.add({title : 'advanced.link_desc', icon : 'link', cmd : ed.plugins.advlink ? 'mceAdvLink' : 'mceLink', ui : true}); - m.add({title : 'advanced.unlink_desc', icon : 'unlink', cmd : 'UnLink'}); - m.addSeparator(); - } + // Clone formats + tinymce.walk(cell, function(node) { + var curNode; - if (el.nodeName == 'IMG' && el.className.indexOf('mceItem') == -1) { - m.add({title : 'advanced.image_desc', icon : 'image', cmd : ed.plugins.advimage ? 'mceAdvImage' : 'mceImage', ui : true}); - m.addSeparator(); - } + if (node.nodeType == 3) { + each(dom.getParents(node.parentNode, null, cell).reverse(), function(node) { + node = node.cloneNode(false); - m.add({title : 'table.desc', icon : 'table', cmd : 'mceInsertTable', ui : true, value : {action : 'insert'}}); - m.add({title : 'table.props_desc', icon : 'table_props', cmd : 'mceInsertTable', ui : true}); - m.add({title : 'table.del', icon : 'delete_table', cmd : 'mceTableDelete', ui : true}); - m.addSeparator(); - - // Cell menu - sm = m.addMenu({title : 'table.cell'}); - sm.add({title : 'table.cell_desc', icon : 'cell_props', cmd : 'mceTableCellProps', ui : true}); - sm.add({title : 'table.split_cells_desc', icon : 'split_cells', cmd : 'mceTableSplitCells', ui : true}); - sm.add({title : 'table.merge_cells_desc', icon : 'merge_cells', cmd : 'mceTableMergeCells', ui : true}); - - // Row menu - sm = m.addMenu({title : 'table.row'}); - sm.add({title : 'table.row_desc', icon : 'row_props', cmd : 'mceTableRowProps', ui : true}); - sm.add({title : 'table.row_before_desc', icon : 'row_before', cmd : 'mceTableInsertRowBefore'}); - sm.add({title : 'table.row_after_desc', icon : 'row_after', cmd : 'mceTableInsertRowAfter'}); - sm.add({title : 'table.delete_row_desc', icon : 'delete_row', cmd : 'mceTableDeleteRow'}); - sm.addSeparator(); - sm.add({title : 'table.cut_row_desc', icon : 'cut', cmd : 'mceTableCutRow'}); - sm.add({title : 'table.copy_row_desc', icon : 'copy', cmd : 'mceTableCopyRow'}); - sm.add({title : 'table.paste_row_before_desc', icon : 'paste', cmd : 'mceTablePasteRowBefore'}); - sm.add({title : 'table.paste_row_after_desc', icon : 'paste', cmd : 'mceTablePasteRowAfter'}); + if (!formatNode) + formatNode = curNode = node; + else if (curNode) + curNode.appendChild(node); - // Column menu - sm = m.addMenu({title : 'table.col'}); - sm.add({title : 'table.col_before_desc', icon : 'col_before', cmd : 'mceTableInsertColBefore'}); - sm.add({title : 'table.col_after_desc', icon : 'col_after', cmd : 'mceTableInsertColAfter'}); - sm.add({title : 'table.delete_col_desc', icon : 'delete_col', cmd : 'mceTableDeleteCol'}); - } else - m.add({title : 'table.desc', icon : 'table', cmd : 'mceInsertTable', ui : true}); + curNode = node; }); - } - }); - // Add undo level when new rows are created using the tab key - ed.onKeyDown.add(function(ed, e) { - if (e.keyCode == 9 && ed.dom.getParent(ed.selection.getNode(), 'TABLE')) { - if (!tinymce.isGecko && !tinymce.isOpera) { - tinyMCE.execInstanceCommand(ed.editorId, "mceTableMoveToNextRow", true); - return tinymce.dom.Event.cancel(e); - } + // Add something to the inner node + if (curNode) + curNode.innerHTML = tinymce.isIE ? ' ' : '
'; - ed.undoManager.add(); + return false; } - }); + }, 'childNodes'); - // Select whole table is a table border is clicked - if (!tinymce.isIE) { - if (ed.getParam('table_selection', true)) { - ed.onClick.add(function(ed, e) { - e = e.target; + cell = cell.cloneNode(false); + cell.rowSpan = cell.colSpan = 1; - if (e.nodeName === 'TABLE') - ed.selection.select(e); - }); - } + if (formatNode) { + cell.appendChild(formatNode); + } else { + if (!tinymce.isIE) + cell.innerHTML = '
'; } - ed.onNodeChange.add(function(ed, cm, n) { - var p = ed.dom.getParent(n, 'td,th,caption'); + return cell; + }; - cm.setActive('table', n.nodeName === 'TABLE' || !!p); - if (p && p.nodeName === 'CAPTION') - p = null; + function cleanup() { + var rng = dom.createRng(); - cm.setDisabled('delete_table', !p); - cm.setDisabled('delete_col', !p); - cm.setDisabled('delete_table', !p); - cm.setDisabled('delete_row', !p); - cm.setDisabled('col_after', !p); - cm.setDisabled('col_before', !p); - cm.setDisabled('row_after', !p); - cm.setDisabled('row_before', !p); - cm.setDisabled('row_props', !p); - cm.setDisabled('cell_props', !p); - cm.setDisabled('split_cells', !p || (parseInt(ed.dom.getAttrib(p, 'colspan', '1')) < 2 && parseInt(ed.dom.getAttrib(p, 'rowspan', '1')) < 2)); - cm.setDisabled('merge_cells', !p); + // Empty rows + each(dom.select('tr', table), function(tr) { + if (tr.cells.length == 0) + dom.remove(tr); }); - // Padd empty table cells - if (!tinymce.isIE) { - ed.onBeforeSetContent.add(function(ed, o) { - if (o.initial) - o.content = o.content.replace(/<(td|th)([^>]+|)>\s*<\/(td|th)>/g, tinymce.isOpera ? '<$1$2> ' : '<$1$2>
'); - }); - } - }, - - execCommand : function(cmd, ui, val) { - var ed = this.editor, b; - - // Is table command - switch (cmd) { - case "mceTableMoveToNextRow": - case "mceInsertTable": - case "mceTableRowProps": - case "mceTableCellProps": - case "mceTableSplitCells": - case "mceTableMergeCells": - case "mceTableInsertRowBefore": - case "mceTableInsertRowAfter": - case "mceTableDeleteRow": - case "mceTableInsertColBefore": - case "mceTableInsertColAfter": - case "mceTableDeleteCol": - case "mceTableCutRow": - case "mceTableCopyRow": - case "mceTablePasteRowBefore": - case "mceTablePasteRowAfter": - case "mceTableDelete": - ed.execCommand('mceBeginUndoLevel'); - this._doExecCommand(cmd, ui, val); - ed.execCommand('mceEndUndoLevel'); - - return true; + // Empty table + if (dom.select('tr', table).length == 0) { + rng.setStartAfter(table); + rng.setEndAfter(table); + selection.setRng(rng); + dom.remove(table); + return; } - // Pass to next handler in chain - return false; - }, - - getInfo : function() { - return { - longname : 'Tables', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/table', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - }, - - // Private plugin internal methods - - /** - * Executes the table commands. - */ - _doExecCommand : function(command, user_interface, value) { - var inst = this.editor, ed = inst, url = this.url; - var focusElm = inst.selection.getNode(); - var trElm = inst.dom.getParent(focusElm, "tr"); - var tdElm = inst.dom.getParent(focusElm, "td,th"); - var tableElm = inst.dom.getParent(focusElm, "table"); - var doc = inst.contentWindow.document; - var tableBorder = tableElm ? tableElm.getAttribute("border") : ""; - - // Get first TD if no TD found - if (trElm && tdElm == null) - tdElm = trElm.cells[0]; - - function inArray(ar, v) { - for (var i=0; i 0 && inArray(ar[i], v)) - return true; - - // Found value - if (ar[i] == v) - return true; - } + // Empty header/body/footer + each(dom.select('thead,tbody,tfoot', table), function(part) { + if (part.rows.length == 0) + dom.remove(part); + }); + + // Restore selection to start position if it still exists + buildGrid(); - return false; + // Restore the selection to the closest table position + row = grid[Math.min(grid.length - 1, startPos.y)]; + if (row) { + selection.select(row[Math.min(row.length - 1, startPos.x)].elm, true); + selection.collapse(true); } + }; - function select(dx, dy) { - var td; + function fillLeftDown(x, y, rows, cols) { + var tr, x2, r, c, cell; - grid = getTableGrid(tableElm); - dx = dx || 0; - dy = dy || 0; - dx = Math.max(cpos.cellindex + dx, 0); - dy = Math.max(cpos.rowindex + dy, 0); + tr = grid[y][x].elm.parentNode; + for (r = 1; r <= rows; r++) { + tr = dom.getNext(tr, 'tr'); - // Recalculate grid and select - inst.execCommand('mceRepaint'); - td = getCell(grid, dy, dx); + if (tr) { + // Loop left to find real cell + for (x2 = x; x2 >= 0; x2--) { + cell = grid[y + r][x2].elm; - if (td) { - inst.selection.select(td.firstChild || td); - inst.selection.collapse(1); - } - }; + if (cell.parentNode == tr) { + // Append clones after + for (c = 1; c <= cols; c++) + dom.insertAfter(cloneCell(cell), cell); - function makeTD() { - var newTD = doc.createElement("td"); + break; + } + } - if (!tinymce.isIE) - newTD.innerHTML = '
'; + if (x2 == -1) { + // Insert nodes before first cell + for (c = 1; c <= cols; c++) + tr.insertBefore(cloneCell(tr.cells[0]), tr.cells[0]); + } + } } + }; - function getColRowSpan(td) { - var colspan = inst.dom.getAttrib(td, "colspan"); - var rowspan = inst.dom.getAttrib(td, "rowspan"); + function split() { + each(grid, function(row, y) { + each(row, function(cell, x) { + var colSpan, rowSpan, newCell, i; - colspan = colspan == "" ? 1 : parseInt(colspan); - rowspan = rowspan == "" ? 1 : parseInt(rowspan); + if (isCellSelected(cell)) { + cell = cell.elm; + colSpan = getSpanVal(cell, 'colspan'); + rowSpan = getSpanVal(cell, 'rowspan'); - return {colspan : colspan, rowspan : rowspan}; + if (colSpan > 1 || rowSpan > 1) { + cell.colSpan = cell.rowSpan = 1; + + // Insert cells right + for (i = 0; i < colSpan - 1; i++) + dom.insertAfter(cloneCell(cell), cell); + + fillLeftDown(x, y, rowSpan - 1, colSpan); + } + } + }); + }); + }; + + function merge(cell, cols, rows) { + var startX, startY, endX, endY, x, y, startCell, endCell, cell, children; + + // Use specified cell and cols/rows + if (cell) { + pos = getPos(cell); + startX = pos.x; + startY = pos.y; + endX = startX + (cols - 1); + endY = startY + (rows - 1); + } else { + // Use selection + startX = startPos.x; + startY = startPos.y; + endX = endPos.x; + endY = endPos.y; } - function getCellPos(grid, td) { - var x, y; + // Find start/end cells + startCell = getCell(startX, startY); + endCell = getCell(endX, endY); + + // Check if the cells exists and if they are of the same part for example tbody = tbody + if (startCell && endCell && startCell.part == endCell.part) { + // Split and rebuild grid + split(); + buildGrid(); + + // Set row/col span to start cell + startCell = getCell(startX, startY).elm; + startCell.colSpan = (endX - startX) + 1; + startCell.rowSpan = (endY - startY) + 1; + + // Remove other cells and add it's contents to the start cell + for (y = startY; y <= endY; y++) { + for (x = startX; x <= endX; x++) { + cell = grid[y][x].elm; + + if (cell != startCell) { + // Move children to startCell + children = tinymce.grep(cell.childNodes); + each(children, function(node, i) { + // Jump over last BR element + if (node.nodeName != 'BR' || i != children.length - 1) + startCell.appendChild(node); + }); - for (y=0; y 1) { + cell.rowSpan = rowSpan + 1; + continue; + } + } else { + // Check if cell above can be expanded + if (posY > 0 && grid[posY - 1][x]) { + otherCell = grid[posY - 1][x].elm; + rowSpan = getSpanVal(otherCell, 'rowspan'); + if (rowSpan > 1) { + otherCell.rowSpan = rowSpan + 1; + continue; + } + } + } - for (i = 0; i < table.rows.length; i++) - for (j = 0; j < table.rows[i].cells.length; j++, x++) - cells[x] = table.rows[i].cells[j]; + // Insert new cell into new row + newCell = cloneCell(cell) + newCell.colSpan = cell.colSpan; + newRow.appendChild(newCell); - for (i = 0; i < cells.length; i++) - if (cells[i] == cell) - if (nextCell = cells[i+1]) - return nextCell; + lastCell = cell; + } } - function getTableGrid(table) { - var grid = [], rows = table.rows, x, y, td, sd, xstart, x2, y2; - - for (y=0; y 1) { // Remove due to colspan - for (var i=x; i 1) - td.rowSpan = sd.rowspan + 1; + if (cell != lastCell) { + colSpan = getSpanVal(cell, 'colspan'); + rowSpan = getSpanVal(cell, 'rowspan'); - lastElm = td; - } + if (colSpan == 1) { + if (!before) { + dom.insertAfter(cloneCell(cell), cell); + fillLeftDown(posX, y, rowSpan - 1, colSpan); + } else { + cell.parentNode.insertBefore(cloneCell(cell), cell); + fillLeftDown(posX, y, rowSpan - 1, colSpan); + } + } else + cell.colSpan++; - deleteMarked(tableElm); + lastCell = cell; } - } + }); + }; - function prevElm(node, name) { - while ((node = node.previousSibling) != null) { - if (node.nodeName == name) - return node; - } + function deleteCols() { + var cols = []; - return null; - } + // Get selected column indexes + each(grid, function(row, y) { + each(row, function(cell, x) { + if (isCellSelected(cell) && tinymce.inArray(cols, x) === -1) { + each(grid, function(row) { + var cell = row[x].elm, colSpan; - function nextElm(node, names) { - var namesAr = names.split(','); + colSpan = getSpanVal(cell, 'colspan'); - while ((node = node.nextSibling) != null) { - for (var i=0; i 1) + cell.colSpan = colSpan - 1; + else + dom.remove(cell); + }); + + cols.push(x); } - } + }); + }); - return null; - } + cleanup(); + }; - function deleteMarked(tbl) { - if (tbl.rows == 0) - return; + function deleteRows() { + var rows; - var tr = tbl.rows[0]; - do { - var next = nextElm(tr, "TR"); + function deleteRow(tr) { + var nextTr, pos, lastCell; - // Delete row - if (tr._delete) { - tr.parentNode.removeChild(tr); - continue; - } + nextTr = dom.getNext(tr, 'tr'); - // Delete cells - var td = tr.cells[0]; - if (td.cells > 1) { - do { - var nexttd = nextElm(td, "TD,TH"); + // Move down row spanned cells + each(tr.cells, function(cell) { + var rowSpan = getSpanVal(cell, 'rowspan'); - if (td._delete) - td.parentNode.removeChild(td); - } while ((td = nexttd) != null); + if (rowSpan > 1) { + cell.rowSpan = rowSpan - 1; + pos = getPos(cell); + fillLeftDown(pos.x, pos.y, 1, 1); } - } while ((tr = next) != null); - } + }); - function addRows(td_elm, tr_elm, rowspan) { - // Add rows - td_elm.rowSpan = 1; - var trNext = nextElm(tr_elm, "TR"); - for (var i=1; i maxX) + maxX = x; - select(0, 1); - break; + if (y > maxY) + maxY = y; - case "mceTableDeleteRow": - if (!trElm || !tdElm) - return true; + if (cell.real) { + colSpan = cell.colspan - 1; + rowSpan = cell.rowspan - 1; - var grid = getTableGrid(tableElm); - var cpos = getCellPos(grid, tdElm); + if (colSpan) { + if (x + colSpan > maxX) + maxX = x + colSpan; + } - // Only one row, remove whole table - if (grid.length == 1 && tableElm.nodeName == 'TBODY') { - inst.dom.remove(inst.dom.getParent(tableElm, "table")); - return true; - } + if (rowSpan) { + if (y + rowSpan > maxY) + maxY = y + rowSpan; + } + } + } + }); + }); - // Move down row spanned cells - var cells = trElm.cells; - var nextTR = nextElm(trElm, "TR"); - for (var x=0; x 1) { - var newTD = cells[x].cloneNode(true); - var sd = getColRowSpan(cells[x]); + return {x : maxX, y : maxY}; + }; - newTD.rowSpan = sd.rowspan - 1; + function setEndCell(cell) { + var startX, startY, endX, endY, maxX, maxY, colSpan, rowSpan; - var nextTD = nextTR.cells[x]; + endPos = getPos(cell); - if (nextTD == null) - nextTR.appendChild(newTD); - else - nextTR.insertBefore(newTD, nextTD); - } - } + if (startPos && endPos) { + // Get start/end positions + startX = Math.min(startPos.x, endPos.x); + startY = Math.min(startPos.y, endPos.y); + endX = Math.max(startPos.x, endPos.x); + endY = Math.max(startPos.y, endPos.y); - // Delete cells - var lastTDElm = null; - for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { - if (tdElm != lastTDElm) { - var sd = getColRowSpan(tdElm); + // Expand end positon to include spans + maxX = endX; + maxY = endY; - if (sd.rowspan > 1) { - tdElm.rowSpan = sd.rowspan - 1; - } else { - trElm = tdElm.parentNode; + // Expand startX + for (y = startY; y <= maxY; y++) { + cell = grid[y][startX]; - if (trElm.parentNode) - trElm._delete = true; - } + if (!cell.real) { + if (startX - (cell.colspan - 1) < startX) + startX -= cell.colspan - 1; + } + } - lastTDElm = tdElm; - } - } + // Expand startY + for (x = startX; x <= maxX; x++) { + cell = grid[startY][x]; - deleteMarked(tableElm); + if (!cell.real) { + if (startY - (cell.rowspan - 1) < startY) + startY -= cell.rowspan - 1; + } + } - select(0, -1); - break; + // Find max X, Y + for (y = startY; y <= endY; y++) { + for (x = startX; x <= endX; x++) { + cell = grid[y][x]; - case "mceTableInsertColBefore": - if (!trElm || !tdElm) - return true; + if (cell.real) { + colSpan = cell.colspan - 1; + rowSpan = cell.rowspan - 1; - var grid = getTableGrid(inst.dom.getParent(tableElm, "table")); - var cpos = getCellPos(grid, tdElm); - var lastTDElm = null; + if (colSpan) { + if (x + colSpan > maxX) + maxX = x + colSpan; + } - for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { - if (tdElm != lastTDElm) { - var sd = getColRowSpan(tdElm); + if (rowSpan) { + if (y + rowSpan > maxY) + maxY = y + rowSpan; + } + } + } + } - if (sd['colspan'] == 1) { - var newTD = doc.createElement(tdElm.nodeName); + // Remove current selection + dom.removeClass(dom.select('td.mceSelected,th.mceSelected'), 'mceSelected'); - if (!tinymce.isIE) - newTD.innerHTML = '
'; + // Add new selection + for (y = startY; y <= maxY; y++) { + for (x = startX; x <= maxX; x++) + dom.addClass(grid[y][x].elm, 'mceSelected'); + } + } + }; + + // Expose to public + tinymce.extend(this, { + deleteTable : deleteTable, + split : split, + merge : merge, + insertRow : insertRow, + insertCol : insertCol, + deleteCols : deleteCols, + deleteRows : deleteRows, + cutRows : cutRows, + copyRows : copyRows, + pasteRows : pasteRows, + getPos : getPos, + setStartCell : setStartCell, + setEndCell : setEndCell + }); + }; - newTD.rowSpan = tdElm.rowSpan; + tinymce.create('tinymce.plugins.TablePlugin', { + init : function(ed, url) { + var winMan, clipboardRows; - tdElm.parentNode.insertBefore(newTD, tdElm); - } else - tdElm.colSpan++; + function createTableGrid(node) { + var selection = ed.selection, tblElm = ed.dom.getParent(node || selection.getNode(), 'table'); - lastTDElm = tdElm; - } - } + if (tblElm) + return new TableGrid(tblElm, ed.dom, selection); + }; - select(); - break; + function cleanup() { + // Restore selection possibilities + ed.getBody().style.webkitUserSelect = ''; + ed.dom.removeClass(ed.dom.select('td.mceSelected,th.mceSelected'), 'mceSelected'); + }; - case "mceTableInsertColAfter": - if (!trElm || !tdElm) - return true; + // Register buttons + each([ + ['table', 'table.desc', 'mceInsertTable', true], + ['delete_table', 'table.del', 'mceTableDelete'], + ['delete_col', 'table.delete_col_desc', 'mceTableDeleteCol'], + ['delete_row', 'table.delete_row_desc', 'mceTableDeleteRow'], + ['col_after', 'table.col_after_desc', 'mceTableInsertColAfter'], + ['col_before', 'table.col_before_desc', 'mceTableInsertColBefore'], + ['row_after', 'table.row_after_desc', 'mceTableInsertRowAfter'], + ['row_before', 'table.row_before_desc', 'mceTableInsertRowBefore'], + ['row_props', 'table.row_desc', 'mceTableRowProps', true], + ['cell_props', 'table.cell_desc', 'mceTableCellProps', true], + ['split_cells', 'table.split_cells_desc', 'mceTableSplitCells', true], + ['merge_cells', 'table.merge_cells_desc', 'mceTableMergeCells', true] + ], function(c) { + ed.addButton(c[0], {title : c[1], cmd : c[2], ui : c[3]}); + }); - var grid = getTableGrid(inst.dom.getParent(tableElm, "table")); - var cpos = getCellPos(grid, tdElm); - var lastTDElm = null; + // Select whole table is a table border is clicked + if (!tinymce.isIE) { + ed.onClick.add(function(ed, e) { + e = e.target; - for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { - if (tdElm != lastTDElm) { - var sd = getColRowSpan(tdElm); + if (e.nodeName === 'TABLE') + ed.selection.select(e); + }); + } - if (sd['colspan'] == 1) { - var newTD = doc.createElement(tdElm.nodeName); + // Handle node change updates + ed.onNodeChange.add(function(ed, cm, n) { + var p; - if (!tinymce.isIE) - newTD.innerHTML = '
'; + n = ed.selection.getStart(); + p = ed.dom.getParent(n, 'td,th,caption'); + cm.setActive('table', n.nodeName === 'TABLE' || !!p); - newTD.rowSpan = tdElm.rowSpan; + // Disable table tools if we are in caption + if (p && p.nodeName === 'CAPTION') + p = 0; - var nextTD = nextElm(tdElm, "TD,TH"); - if (nextTD == null) - tdElm.parentNode.appendChild(newTD); - else - nextTD.parentNode.insertBefore(newTD, nextTD); - } else - tdElm.colSpan++; + cm.setDisabled('delete_table', !p); + cm.setDisabled('delete_col', !p); + cm.setDisabled('delete_table', !p); + cm.setDisabled('delete_row', !p); + cm.setDisabled('col_after', !p); + cm.setDisabled('col_before', !p); + cm.setDisabled('row_after', !p); + cm.setDisabled('row_before', !p); + cm.setDisabled('row_props', !p); + cm.setDisabled('cell_props', !p); + cm.setDisabled('split_cells', !p); + cm.setDisabled('merge_cells', !p); + }); - lastTDElm = tdElm; - } - } + ed.onInit.add(function(ed) { + var startTable, startCell, dom = ed.dom, tableGrid; - select(1); - break; + winMan = ed.windowManager; - case "mceTableDeleteCol": - if (!trElm || !tdElm) - return true; + // Add cell selection logic + ed.onMouseDown.add(function(ed, e) { + if (e.button != 2) { + cleanup(); - var grid = getTableGrid(tableElm); - var cpos = getCellPos(grid, tdElm); - var lastTDElm = null; + startCell = dom.getParent(e.target, 'td,th'); + startTable = dom.getParent(startCell, 'table'); + } + }); - // Only one col, remove whole table - if ((grid.length > 1 && grid[0].length <= 1) && tableElm.nodeName == 'TBODY') { - inst.dom.remove(inst.dom.getParent(tableElm, "table")); - return true; - } + dom.bind(ed.getDoc(), 'mouseover', function(e) { + var sel, table, target = e.target; - // Delete cells - for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { - if (tdElm != lastTDElm) { - var sd = getColRowSpan(tdElm); + if (startCell && (tableGrid || target != startCell) && (target.nodeName == 'TD' || target.nodeName == 'TH')) { + table = dom.getParent(target, 'table'); + if (table == startTable) { + if (!tableGrid) { + tableGrid = createTableGrid(table); + tableGrid.setStartCell(startCell); - if (sd['colspan'] > 1) - tdElm.colSpan = sd['colspan'] - 1; - else { - if (tdElm.parentNode) - tdElm.parentNode.removeChild(tdElm); - } + ed.getBody().style.webkitUserSelect = 'none'; + } - lastTDElm = tdElm; - } - } + tableGrid.setEndCell(target); + } - select(-1); - break; + // Remove current selection + sel = ed.selection.getSel(); - case "mceTableSplitCells": - if (!trElm || !tdElm) - return true; + if (sel.removeAllRanges) + sel.removeAllRanges(); + else + sel.empty(); - var spandata = getColRowSpan(tdElm); + e.preventDefault(); + } + }); - var colspan = spandata["colspan"]; - var rowspan = spandata["rowspan"]; + ed.onMouseUp.add(function(ed, e) { + var rng, sel = ed.selection, selectedCells, nativeSel = sel.getSel(), walker, node, lastNode, endNode; - // Needs splitting - if (colspan > 1 || rowspan > 1) { - // Generate cols - tdElm.colSpan = 1; - for (var i=1; i 1) - addRows(newTD, trElm, rowspan); + return; } - addRows(tdElm, trElm, rowspan); - } - - // Apply visual aids - tableElm = inst.dom.getParent(inst.selection.getNode(), "table"); - break; - - case "mceTableMergeCells": - var rows = []; - var sel = inst.selection.getSel(); - var grid = getTableGrid(tableElm); - - if (tinymce.isIE || sel.rangeCount == 1) { - if (user_interface) { - // Setup template - var sp = getColRowSpan(tdElm); - - inst.windowManager.open({ - url : url + '/merge_cells.htm', - width : 240 + parseInt(inst.getLang('table.merge_cells_delta_width', 0)), - height : 110 + parseInt(inst.getLang('table.merge_cells_delta_height', 0)), - inline : 1 - }, { - action : "update", - numcols : sp.colspan, - numrows : sp.rowspan, - plugin_url : url - }); - - return true; - } else { - var numRows = parseInt(value['numrows']); - var numCols = parseInt(value['numcols']); - var cpos = getCellPos(grid, tdElm); - - if (("" + numRows) == "NaN") - numRows = 1; - - if (("" + numCols) == "NaN") - numCols = 1; - - // Get rows and cells - var tRows = tableElm.rows; - for (var y=cpos.rowindex; y 0) - rows[rows.length] = rowCells; - - var td = getCell(grid, cpos.rowindex, cpos.cellindex); - each(ed.dom.select('br', td), function(e, i) { - if (i > 0 && ed.dom.getAttrib('mce_bogus')) - ed.dom.remove(e); - }); - } + // BR element + if (node.nodeName == 'BR') { + if (start) + rng.setStartBefore(node); + else + rng.setEndBefore(node); - //return true; + return; } - } else { - var cells = []; - var sel = inst.selection.getSel(); - var lastTR = null; - var curRow = null; - var x1 = -1, y1 = -1, x2, y2; - - // Only one cell selected, whats the point? - if (sel.rangeCount < 2) - return true; - - // Get all selected cells - for (var i=0; i 0) { + rng = dom.createRng(); + node = selectedCells[0]; + endNode = selectedCells[selectedCells.length - 1]; + + setPoint(node, 1); + walker = new tinymce.dom.TreeWalker(node, dom.getParent(selectedCells[0], 'table')); + + do { + if (node.nodeName == 'TD' || node.nodeName == 'TH') { + if (!dom.hasClass(node, 'mceSelected')) break; - if (tdElm.nodeName == "TD" || tdElm.nodeName == "TH") - cells[cells.length] = tdElm; + lastNode = node; } + } while (node = walker.next()); - // Get rows and cells - var tRows = tableElm.rows; - for (var y=0; y 0) - rows[rows.length] = rowCells; - } + ed.onKeyUp.add(function(ed, e) { + cleanup(); + }); - // Find selected cells in grid and box - var curRow = []; - var lastTR = null; - for (var y=0; y colSpan) - colSpan = rowColSpan; + // Skip empty text nodes form the end + for (last = ed.getBody().lastChild; last && last.nodeType == 3 && !last.nodeValue.length; last = last.previousSibling) ; - lastRowSpan = -1; - } + if (last && last.nodeName == 'TABLE') + ed.dom.add(ed.getBody(), 'p', null, '
'); + }; + + // Fixes an bug where it's impossible to place the caret before a table in Gecko + // this fix solves it by detecting when the caret is at the beginning of such a table + // and then manually moves the caret infront of the table + if (tinymce.isGecko) { + ed.onKeyDown.add(function(ed, e) { + var rng, table, dom = ed.dom; + + // On gecko it's not possible to place the caret before a table + if (e.keyCode == 37 || e.keyCode == 38) { + rng = ed.selection.getRng(); + table = dom.getParent(rng.startContainer, 'table'); - // Validate vertical and get total rowspan - var lastColSpan = -1; - for (var x=0; x rowSpan) - rowSpan = colRowSpan; + ed.onKeyUp.add(fixTableCaretPos); + ed.onSetContent.add(fixTableCaretPos); + ed.onVisualAid.add(fixTableCaretPos); - lastColSpan = -1; - } + ed.onPreProcess.add(function(ed, o) { + var last = o.node.lastChild; - // Setup td - tdElm = rows[0][0]; - tdElm.rowSpan = rowSpan; - tdElm.colSpan = colSpan; + if (last && last.childNodes.length == 1 && last.firstChild.nodeName == 'BR') + ed.dom.remove(last); + }); - // Merge cells - for (var y=0; y 0)) - tdElm.innerHTML += html; + // Register action commands + each({ + mceTableSplitCells : function(grid) { + grid.split(); + }, - // Not current cell - if (rows[y][x] != tdElm && !rows[y][x]._deleted) { - var cpos = getCellPos(grid, rows[y][x]); - var tr = rows[y][x].parentNode; + mceTableMergeCells : function(grid) { + var rowSpan, colSpan, cell; - tr.removeChild(rows[y][x]); - rows[y][x]._deleted = true; + cell = ed.dom.getParent(ed.selection.getNode(), 'th,td'); + if (cell) { + rowSpan = cell.rowSpan; + colSpan = cell.colSpan; + } - // Empty TR, remove it - if (!tr.hasChildNodes()) { - tr.parentNode.removeChild(tr); + if (!ed.dom.select('td.mceSelected,th.mceSelected').length) { + winMan.open({ + url : url + '/merge_cells.htm', + width : 240 + parseInt(ed.getLang('table.merge_cells_delta_width', 0)), + height : 110 + parseInt(ed.getLang('table.merge_cells_delta_height', 0)), + inline : 1 + }, { + rows : rowSpan, + cols : colSpan, + onaction : function(data) { + grid.merge(cell, data.cols, data.rows); + }, + plugin_url : url + }); + } else + grid.merge(); + }, - var lastCell = null; - for (var x=0; cellElm = getCell(grid, cpos.rowindex, x); x++) { - if (cellElm != lastCell && cellElm.rowSpan > 1) - cellElm.rowSpan--; + mceTableInsertRowBefore : function(grid) { + grid.insertRow(true); + }, - lastCell = cellElm; - } + mceTableInsertRowAfter : function(grid) { + grid.insertRow(); + }, - if (tdElm.rowSpan > 1) - tdElm.rowSpan--; - } - } - } - } + mceTableInsertColBefore : function(grid) { + grid.insertCol(true); + }, - // Remove all but one bogus br - each(ed.dom.select('br', tdElm), function(e, i) { - if (i > 0 && ed.dom.getAttrib(e, 'mce_bogus')) - ed.dom.remove(e); - }); + mceTableInsertColAfter : function(grid) { + grid.insertCol(); + }, - break; - } + mceTableDeleteCol : function(grid) { + grid.deleteCols(); + }, - tableElm = inst.dom.getParent(inst.selection.getNode(), "table"); - inst.addVisual(tableElm); - inst.nodeChanged(); - } + mceTableDeleteRow : function(grid) { + grid.deleteRows(); + }, - return true; - } + mceTableCutRow : function(grid) { + clipboardRows = grid.cutRows(); + }, + + mceTableCopyRow : function(grid) { + clipboardRows = grid.copyRows(); + }, - // Pass to next handler in chain - return false; + mceTablePasteRowBefore : function(grid) { + grid.pasteRows(clipboardRows, true); + }, + + mceTablePasteRowAfter : function(grid) { + grid.pasteRows(clipboardRows); + }, + + mceTableDelete : function(grid) { + grid.deleteTable(); + } + }, function(func, name) { + ed.addCommand(name, function() { + var grid = createTableGrid(); + + if (grid) { + func(grid); + ed.execCommand('mceRepaint'); + cleanup(); + } + }); + }); + + // Register dialog commands + each({ + mceInsertTable : function(val) { + winMan.open({ + url : url + '/table.htm', + width : 400 + parseInt(ed.getLang('table.table_delta_width', 0)), + height : 320 + parseInt(ed.getLang('table.table_delta_height', 0)), + inline : 1 + }, { + plugin_url : url, + action : val ? val.action : 0 + }); + }, + + mceTableRowProps : function() { + winMan.open({ + url : url + '/row.htm', + width : 400 + parseInt(ed.getLang('table.rowprops_delta_width', 0)), + height : 295 + parseInt(ed.getLang('table.rowprops_delta_height', 0)), + inline : 1 + }, { + plugin_url : url + }); + }, + + mceTableCellProps : function() { + winMan.open({ + url : url + '/cell.htm', + width : 400 + parseInt(ed.getLang('table.cellprops_delta_width', 0)), + height : 295 + parseInt(ed.getLang('table.cellprops_delta_height', 0)), + inline : 1 + }, { + plugin_url : url + }); + } + }, function(func, name) { + ed.addCommand(name, function(ui, val) { + func(val); + }); + }); } }); // Register plugin tinymce.PluginManager.add('table', tinymce.plugins.TablePlugin); -})(); \ No newline at end of file +})(tinymce); \ No newline at end of file diff --git a/program/js/tiny_mce/plugins/table/js/cell.js b/program/js/tiny_mce/plugins/table/js/cell.js index f23b06751..f24619172 100644 --- a/program/js/tiny_mce/plugins/table/js/cell.js +++ b/program/js/tiny_mce/plugins/table/js/cell.js @@ -11,7 +11,7 @@ function init() { document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor') var inst = ed; - var tdElm = ed.dom.getParent(ed.selection.getNode(), "td,th"); + var tdElm = ed.dom.getParent(ed.selection.getStart(), "td,th"); var formObj = document.forms[0]; var st = ed.dom.parseStyle(ed.dom.getAttrib(tdElm, "style")); @@ -34,38 +34,55 @@ function init() { addClassesToList('class', 'table_cell_styles'); TinyMCE_EditableSelects.init(); - formObj.bordercolor.value = bordercolor; - formObj.bgcolor.value = bgcolor; - formObj.backgroundimage.value = backgroundimage; - formObj.width.value = width; - formObj.height.value = height; - formObj.id.value = id; - formObj.lang.value = lang; - formObj.style.value = ed.dom.serializeStyle(st); - selectByValue(formObj, 'align', align); - selectByValue(formObj, 'valign', valign); - selectByValue(formObj, 'class', className, true, true); - selectByValue(formObj, 'celltype', celltype); - selectByValue(formObj, 'dir', dir); - selectByValue(formObj, 'scope', scope); - - // Resize some elements - if (isVisible('backgroundimagebrowser')) - document.getElementById('backgroundimage').style.width = '180px'; - - updateColor('bordercolor_pick', 'bordercolor'); - updateColor('bgcolor_pick', 'bgcolor'); + if (!ed.dom.hasClass(tdElm, 'mceSelected')) { + formObj.bordercolor.value = bordercolor; + formObj.bgcolor.value = bgcolor; + formObj.backgroundimage.value = backgroundimage; + formObj.width.value = width; + formObj.height.value = height; + formObj.id.value = id; + formObj.lang.value = lang; + formObj.style.value = ed.dom.serializeStyle(st); + selectByValue(formObj, 'align', align); + selectByValue(formObj, 'valign', valign); + selectByValue(formObj, 'class', className, true, true); + selectByValue(formObj, 'celltype', celltype); + selectByValue(formObj, 'dir', dir); + selectByValue(formObj, 'scope', scope); + + // Resize some elements + if (isVisible('backgroundimagebrowser')) + document.getElementById('backgroundimage').style.width = '180px'; + + updateColor('bordercolor_pick', 'bordercolor'); + updateColor('bgcolor_pick', 'bgcolor'); + } else + tinyMCEPopup.dom.hide('action'); } function updateAction() { var el, inst = ed, tdElm, trElm, tableElm, formObj = document.forms[0]; tinyMCEPopup.restoreSelection(); - el = ed.selection.getNode(); + el = ed.selection.getStart(); tdElm = ed.dom.getParent(el, "td,th"); trElm = ed.dom.getParent(el, "tr"); tableElm = ed.dom.getParent(el, "table"); + // Cell is selected + if (ed.dom.hasClass(tdElm, 'mceSelected')) { + // Update all selected sells + tinymce.each(ed.dom.select('td.mceSelected,th.mceSelected'), function(td) { + updateCell(td); + }); + + ed.addVisual(); + ed.nodeChanged(); + inst.execCommand('mceEndUndoLevel'); + tinyMCEPopup.close(); + return; + } + ed.execCommand('mceBeginUndoLevel'); switch (getSelectValue(formObj, 'action')) { diff --git a/program/js/tiny_mce/plugins/table/js/merge_cells.js b/program/js/tiny_mce/plugins/table/js/merge_cells.js index 31d6df0ab..7ee4bf040 100644 --- a/program/js/tiny_mce/plugins/table/js/merge_cells.js +++ b/program/js/tiny_mce/plugins/table/js/merge_cells.js @@ -1,29 +1,27 @@ tinyMCEPopup.requireLangPack(); -function init() { - var f = document.forms[0], v; +var MergeCellsDialog = { + init : function() { + var f = document.forms[0]; - tinyMCEPopup.resizeToInnerSize(); + f.numcols.value = tinyMCEPopup.getWindowArg('cols', 1); + f.numrows.value = tinyMCEPopup.getWindowArg('rows', 1); + }, - f.numcols.value = tinyMCEPopup.getWindowArg('numcols', 1); - f.numrows.value = tinyMCEPopup.getWindowArg('numrows', 1); -} + merge : function() { + var func, f = document.forms[0]; -function mergeCells() { - var args = [], f = document.forms[0]; + tinyMCEPopup.restoreSelection(); - tinyMCEPopup.restoreSelection(); + func = tinyMCEPopup.getWindowArg('onaction'); - if (!AutoValidator.validate(f)) { - tinyMCEPopup.alert(tinyMCEPopup.getLang('invalid_data')); - return false; - } - - args["numcols"] = f.numcols.value; - args["numrows"] = f.numrows.value; + func({ + cols : f.numcols.value, + rows : f.numrows.value + }); - tinyMCEPopup.execCommand("mceTableMergeCells", false, args); - tinyMCEPopup.close(); -} + tinyMCEPopup.close(); + } +}; -tinyMCEPopup.onInit.add(init); +tinyMCEPopup.onInit.add(MergeCellsDialog.init, MergeCellsDialog); diff --git a/program/js/tiny_mce/plugins/table/js/row.js b/program/js/tiny_mce/plugins/table/js/row.js index d25f635f6..7e188c3f0 100644 --- a/program/js/tiny_mce/plugins/table/js/row.js +++ b/program/js/tiny_mce/plugins/table/js/row.js @@ -8,7 +8,7 @@ function init() { var inst = tinyMCEPopup.editor; var dom = inst.dom; - var trElm = dom.getParent(inst.selection.getNode(), "tr"); + var trElm = dom.getParent(inst.selection.getStart(), "tr"); var formObj = document.forms[0]; var st = dom.parseStyle(dom.getAttrib(trElm, "style")); @@ -24,27 +24,32 @@ function init() { var lang = dom.getAttrib(trElm, 'lang'); var dir = dom.getAttrib(trElm, 'dir'); - // Setup form - addClassesToList('class', 'table_row_styles'); - TinyMCE_EditableSelects.init(); - - formObj.bgcolor.value = bgcolor; - formObj.backgroundimage.value = backgroundimage; - formObj.height.value = height; - formObj.id.value = id; - formObj.lang.value = lang; - formObj.style.value = dom.serializeStyle(st); - selectByValue(formObj, 'align', align); - selectByValue(formObj, 'valign', valign); - selectByValue(formObj, 'class', className, true, true); selectByValue(formObj, 'rowtype', rowtype); - selectByValue(formObj, 'dir', dir); - - // Resize some elements - if (isVisible('backgroundimagebrowser')) - document.getElementById('backgroundimage').style.width = '180px'; - updateColor('bgcolor_pick', 'bgcolor'); + // Any cells selected + if (dom.select('td.mceSelected,th.mceSelected', trElm).length == 0) { + // Setup form + addClassesToList('class', 'table_row_styles'); + TinyMCE_EditableSelects.init(); + + formObj.bgcolor.value = bgcolor; + formObj.backgroundimage.value = backgroundimage; + formObj.height.value = height; + formObj.id.value = id; + formObj.lang.value = lang; + formObj.style.value = dom.serializeStyle(st); + selectByValue(formObj, 'align', align); + selectByValue(formObj, 'valign', valign); + selectByValue(formObj, 'class', className, true, true); + selectByValue(formObj, 'dir', dir); + + // Resize some elements + if (isVisible('backgroundimagebrowser')) + document.getElementById('backgroundimage').style.width = '180px'; + + updateColor('bgcolor_pick', 'bgcolor'); + } else + tinyMCEPopup.dom.hide('action'); } function updateAction() { @@ -52,8 +57,28 @@ function updateAction() { var action = getSelectValue(formObj, 'action'); tinyMCEPopup.restoreSelection(); - trElm = dom.getParent(inst.selection.getNode(), "tr"); - tableElm = dom.getParent(inst.selection.getNode(), "table"); + trElm = dom.getParent(inst.selection.getStart(), "tr"); + tableElm = dom.getParent(inst.selection.getStart(), "table"); + + // Update all selected rows + if (dom.select('td.mceSelected,th.mceSelected', trElm).length > 0) { + tinymce.each(tableElm.rows, function(tr) { + var i; + + for (i = 0; i < tr.cells.length; i++) { + if (dom.hasClass(tr.cells[i], 'mceSelected')) { + updateRow(tr, true); + return; + } + } + }); + + inst.addVisual(); + inst.nodeChanged(); + inst.execCommand('mceEndUndoLevel'); + tinyMCEPopup.close(); + return; + } inst.execCommand('mceBeginUndoLevel'); diff --git a/program/js/tiny_mce/plugins/table/js/table.js b/program/js/tiny_mce/plugins/table/js/table.js index 182589d69..f4b0862ef 100644 --- a/program/js/tiny_mce/plugins/table/js/table.js +++ b/program/js/tiny_mce/plugins/table/js/table.js @@ -82,7 +82,7 @@ function insertTable() { capEl = elm.ownerDocument.createElement('caption'); if (!tinymce.isIE) - capEl.innerHTML = '
'; + capEl.innerHTML = '
'; elm.insertBefore(capEl, elm.firstChild); } @@ -151,6 +151,7 @@ function insertTable() { html += makeAttrib('border', border); html += makeAttrib('cellpadding', cellpadding); html += makeAttrib('cellspacing', cellspacing); + html += makeAttrib('_mce_new', '1'); if (width && inst.settings.inline_styles) { if (style) @@ -186,7 +187,7 @@ function insertTable() { if (caption) { if (!tinymce.isIE) - html += '
'; + html += '
'; else html += ''; } @@ -196,7 +197,7 @@ function insertTable() { for (var x=0; x'); + inst.focus(); + inst.selection.setContent('
'); tinymce.each('h1,h2,h3,h4,h5,h6,p'.split(','), function(n) { if (patt) @@ -225,12 +227,19 @@ function insertTable() { inst.dom.split(inst.dom.getParent(n, 'h1,h2,h3,h4,h5,h6,p'), n); }); - dom.setOuterHTML(dom.select('._mce_marker')[0], html); - - inst.selection.moveToBookmark(bm); + dom.setOuterHTML(dom.select('br._mce_marker')[0], html); } else inst.execCommand('mceInsertContent', false, html); + tinymce.each(dom.select('table[_mce_new]'), function(node) { + var td = dom.select('td', node); + + inst.selection.select(td[0], true); + inst.selection.collapse(); + + dom.setAttrib(node, '_mce_new', ''); + }); + inst.addVisual(); inst.execCommand('mceEndUndoLevel'); diff --git a/program/js/tiny_mce/plugins/table/merge_cells.htm b/program/js/tiny_mce/plugins/table/merge_cells.htm index 25d42eb65..9736ed8c0 100644 --- a/program/js/tiny_mce/plugins/table/merge_cells.htm +++ b/program/js/tiny_mce/plugins/table/merge_cells.htm @@ -8,7 +8,7 @@ -
+
{#table_dlg.merge_cells_title} @@ -24,13 +24,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/plugins/table/row.htm b/program/js/tiny_mce/plugins/table/row.htm index 07ca13c98..092e6c827 100644 --- a/program/js/tiny_mce/plugins/table/row.htm +++ b/program/js/tiny_mce/plugins/table/row.htm @@ -147,13 +147,8 @@ -
-
-
- -
- -
+ + diff --git a/program/js/tiny_mce/plugins/table/table.htm b/program/js/tiny_mce/plugins/table/table.htm index 37e615970..f26903922 100644 --- a/program/js/tiny_mce/plugins/table/table.htm +++ b/program/js/tiny_mce/plugins/table/table.htm @@ -179,13 +179,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/plugins/visualchars/editor_plugin_src.js b/program/js/tiny_mce/plugins/visualchars/editor_plugin_src.js index 02ec4e698..0a5275fe2 100644 --- a/program/js/tiny_mce/plugins/visualchars/editor_plugin_src.js +++ b/program/js/tiny_mce/plugins/visualchars/editor_plugin_src.js @@ -1,8 +1,11 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ (function() { diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/abbr.htm b/program/js/tiny_mce/plugins/xhtmlxtras/abbr.htm index 3928a17e1..3aeac0deb 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/abbr.htm +++ b/program/js/tiny_mce/plugins/xhtmlxtras/abbr.htm @@ -132,17 +132,10 @@
-
- -
-
- -
-
- -
+ + +
- diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/acronym.htm b/program/js/tiny_mce/plugins/xhtmlxtras/acronym.htm index 4d4ebaac0..31ee7b70f 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/acronym.htm +++ b/program/js/tiny_mce/plugins/xhtmlxtras/acronym.htm @@ -132,17 +132,10 @@
-
- -
-
- -
-
- -
+ + +
- diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/attributes.htm b/program/js/tiny_mce/plugins/xhtmlxtras/attributes.htm index 322b468e3..17054da3e 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/attributes.htm +++ b/program/js/tiny_mce/plugins/xhtmlxtras/attributes.htm @@ -140,14 +140,9 @@
-
- -
-
- -
+ +
- diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/cite.htm b/program/js/tiny_mce/plugins/xhtmlxtras/cite.htm index cdfaf4e85..d0a3e3a8e 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/cite.htm +++ b/program/js/tiny_mce/plugins/xhtmlxtras/cite.htm @@ -132,17 +132,10 @@
-
- -
-
- -
-
- -
+ + +
- diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/del.htm b/program/js/tiny_mce/plugins/xhtmlxtras/del.htm index f45676e3d..8b07fa842 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/del.htm +++ b/program/js/tiny_mce/plugins/xhtmlxtras/del.htm @@ -152,18 +152,10 @@
-
- -
-
- -
-
- -
+ + +
- - diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin.js b/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin.js index 8c7f48e69..e5195265e 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin.js @@ -1 +1 @@ -(function(){tinymce.create("tinymce.plugins.XHTMLXtrasPlugin",{init:function(b,c){b.addCommand("mceCite",function(){b.windowManager.open({file:c+"/cite.htm",width:350+parseInt(b.getLang("xhtmlxtras.cite_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.cite_delta_height",0)),inline:1},{plugin_url:c})});b.addCommand("mceAcronym",function(){b.windowManager.open({file:c+"/acronym.htm",width:350+parseInt(b.getLang("xhtmlxtras.acronym_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.acronym_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceAbbr",function(){b.windowManager.open({file:c+"/abbr.htm",width:350+parseInt(b.getLang("xhtmlxtras.abbr_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.abbr_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceDel",function(){b.windowManager.open({file:c+"/del.htm",width:340+parseInt(b.getLang("xhtmlxtras.del_delta_width",0)),height:310+parseInt(b.getLang("xhtmlxtras.del_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceIns",function(){b.windowManager.open({file:c+"/ins.htm",width:340+parseInt(b.getLang("xhtmlxtras.ins_delta_width",0)),height:310+parseInt(b.getLang("xhtmlxtras.ins_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceAttributes",function(){b.windowManager.open({file:c+"/attributes.htm",width:380,height:370,inline:1},{plugin_url:c})});b.addButton("cite",{title:"xhtmlxtras.cite_desc",cmd:"mceCite"});b.addButton("acronym",{title:"xhtmlxtras.acronym_desc",cmd:"mceAcronym"});b.addButton("abbr",{title:"xhtmlxtras.abbr_desc",cmd:"mceAbbr"});b.addButton("del",{title:"xhtmlxtras.del_desc",cmd:"mceDel"});b.addButton("ins",{title:"xhtmlxtras.ins_desc",cmd:"mceIns"});b.addButton("attribs",{title:"xhtmlxtras.attribs_desc",cmd:"mceAttributes"});if(tinymce.isIE){function a(d,e){if(e.set){e.content=e.content.replace(/]+)>/gi,"");e.content=e.content.replace(/<\/abbr>/gi,"")}}b.onBeforeSetContent.add(a);b.onPostProcess.add(a)}b.onNodeChange.add(function(e,d,g,f){g=e.dom.getParent(g,"CITE,ACRONYM,ABBR,DEL,INS");d.setDisabled("cite",f);d.setDisabled("acronym",f);d.setDisabled("abbr",f);d.setDisabled("del",f);d.setDisabled("ins",f);d.setDisabled("attribs",g&&g.nodeName=="BODY");d.setActive("cite",0);d.setActive("acronym",0);d.setActive("abbr",0);d.setActive("del",0);d.setActive("ins",0);if(g){do{d.setDisabled(g.nodeName.toLowerCase(),0);d.setActive(g.nodeName.toLowerCase(),1)}while(g=g.parentNode)}})},getInfo:function(){return{longname:"XHTML Xtras Plugin",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/xhtmlxtras",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("xhtmlxtras",tinymce.plugins.XHTMLXtrasPlugin)})(); \ No newline at end of file +(function(){tinymce.create("tinymce.plugins.XHTMLXtrasPlugin",{init:function(b,c){b.addCommand("mceCite",function(){b.windowManager.open({file:c+"/cite.htm",width:350+parseInt(b.getLang("xhtmlxtras.cite_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.cite_delta_height",0)),inline:1},{plugin_url:c})});b.addCommand("mceAcronym",function(){b.windowManager.open({file:c+"/acronym.htm",width:350+parseInt(b.getLang("xhtmlxtras.acronym_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.acronym_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceAbbr",function(){b.windowManager.open({file:c+"/abbr.htm",width:350+parseInt(b.getLang("xhtmlxtras.abbr_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.abbr_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceDel",function(){b.windowManager.open({file:c+"/del.htm",width:340+parseInt(b.getLang("xhtmlxtras.del_delta_width",0)),height:310+parseInt(b.getLang("xhtmlxtras.del_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceIns",function(){b.windowManager.open({file:c+"/ins.htm",width:340+parseInt(b.getLang("xhtmlxtras.ins_delta_width",0)),height:310+parseInt(b.getLang("xhtmlxtras.ins_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceAttributes",function(){b.windowManager.open({file:c+"/attributes.htm",width:380,height:370,inline:1},{plugin_url:c})});b.addButton("cite",{title:"xhtmlxtras.cite_desc",cmd:"mceCite"});b.addButton("acronym",{title:"xhtmlxtras.acronym_desc",cmd:"mceAcronym"});b.addButton("abbr",{title:"xhtmlxtras.abbr_desc",cmd:"mceAbbr"});b.addButton("del",{title:"xhtmlxtras.del_desc",cmd:"mceDel"});b.addButton("ins",{title:"xhtmlxtras.ins_desc",cmd:"mceIns"});b.addButton("attribs",{title:"xhtmlxtras.attribs_desc",cmd:"mceAttributes"});if(tinymce.isIE){function a(d,e){if(e.set){e.content=e.content.replace(/]+)>/gi,"");e.content=e.content.replace(/<\/abbr>/gi,"")}}b.onBeforeSetContent.add(a);b.onPostProcess.add(a)}b.onNodeChange.add(function(e,d,g,f){g=e.dom.getParent(g,"CITE,ACRONYM,ABBR,DEL,INS");d.setDisabled("cite",f);d.setDisabled("acronym",f);d.setDisabled("abbr",f);d.setDisabled("del",f);d.setDisabled("ins",f);d.setDisabled("attribs",g&&g.nodeName=="BODY");d.setActive("cite",0);d.setActive("acronym",0);d.setActive("abbr",0);d.setActive("del",0);d.setActive("ins",0);if(g){do{d.setDisabled(g.nodeName.toLowerCase(),0);d.setActive(g.nodeName.toLowerCase(),1)}while(g=g.parentNode)}});b.onPreInit.add(function(){b.dom.create("abbr")})},getInfo:function(){return{longname:"XHTML Xtras Plugin",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/xhtmlxtras",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("xhtmlxtras",tinymce.plugins.XHTMLXtrasPlugin)})(); \ No newline at end of file diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js b/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js index bef06f2d2..9b51b8368 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js @@ -1,8 +1,11 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * editor_plugin_src.js * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ (function() { @@ -118,6 +121,11 @@ } while (n = n.parentNode); } }); + + ed.onPreInit.add(function() { + // Fixed IE issue where it can't handle these elements correctly + ed.dom.create('abbr'); + }); }, getInfo : function() { diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/ins.htm b/program/js/tiny_mce/plugins/xhtmlxtras/ins.htm index 9fa21c433..6c5470cfc 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/ins.htm +++ b/program/js/tiny_mce/plugins/xhtmlxtras/ins.htm @@ -152,18 +152,10 @@
-
- -
-
- -
-
- -
+ + +
- - diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/js/abbr.js b/program/js/tiny_mce/plugins/xhtmlxtras/js/abbr.js index e84b6a837..4b51a2572 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/js/abbr.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/js/abbr.js @@ -1,8 +1,11 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ +/** + * abbr.js * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ function init() { @@ -13,7 +16,7 @@ function init() { } function insertAbbr() { - SXE.insertElement(tinymce.isIE ? 'html:abbr' : 'abbr'); + SXE.insertElement('abbr'); tinyMCEPopup.close(); } diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/js/acronym.js b/program/js/tiny_mce/plugins/xhtmlxtras/js/acronym.js index 933d122cb..6ec2f8871 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/js/acronym.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/js/acronym.js @@ -1,8 +1,11 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ +/** + * acronym.js * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ function init() { diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/js/attributes.js b/program/js/tiny_mce/plugins/xhtmlxtras/js/attributes.js index 23c7fa4c2..d62a219e6 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/js/attributes.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/js/attributes.js @@ -1,8 +1,11 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ +/** + * attributes.js * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ function init() { diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/js/cite.js b/program/js/tiny_mce/plugins/xhtmlxtras/js/cite.js index c36f7fd87..009b71546 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/js/cite.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/js/cite.js @@ -1,8 +1,11 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ +/** + * cite.js * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ function init() { diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/js/del.js b/program/js/tiny_mce/plugins/xhtmlxtras/js/del.js index 7049f2beb..9e5d8c571 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/js/del.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/js/del.js @@ -1,8 +1,11 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ +/** + * del.js * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ function init() { diff --git a/program/js/tiny_mce/plugins/xhtmlxtras/js/element_common.js b/program/js/tiny_mce/plugins/xhtmlxtras/js/element_common.js index 70f168a6b..5b494a566 100644 --- a/program/js/tiny_mce/plugins/xhtmlxtras/js/element_common.js +++ b/program/js/tiny_mce/plugins/xhtmlxtras/js/element_common.js @@ -1,8 +1,11 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ +/** + * element_common.js * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ tinyMCEPopup.requireLangPack(); @@ -157,9 +160,6 @@ SXE.insertElement = function(element_name) { if(s.length > 0) { tagName = element_name; - if (tinymce.isIE && element_name.indexOf('html:') == 0) - element_name = element_name.substring(5).toLowerCase(); - insertInlineElement(element_name); var elementArray = tinymce.grep(SXE.inst.dom.select(element_name)); for (var i=0; i
-
- -
+
diff --git a/program/js/tiny_mce/themes/advanced/anchor.htm b/program/js/tiny_mce/themes/advanced/anchor.htm index 42095a1c0..2bc63fcfd 100644 --- a/program/js/tiny_mce/themes/advanced/anchor.htm +++ b/program/js/tiny_mce/themes/advanced/anchor.htm @@ -18,13 +18,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/themes/advanced/color_picker.htm b/program/js/tiny_mce/themes/advanced/color_picker.htm index cbd6b88dc..096e7550c 100644 --- a/program/js/tiny_mce/themes/advanced/color_picker.htm +++ b/program/js/tiny_mce/themes/advanced/color_picker.htm @@ -60,9 +60,7 @@
-
- -
+
diff --git a/program/js/tiny_mce/themes/advanced/editor_template.js b/program/js/tiny_mce/themes/advanced/editor_template.js index 628c793cc..804289082 100644 --- a/program/js/tiny_mce/themes/advanced/editor_template.js +++ b/program/js/tiny_mce/themes/advanced/editor_template.js @@ -1 +1 @@ -(function(e){var d=e.DOM,b=e.dom.Event,h=e.extend,f=e.each,a=e.util.Cookie,g,c=e.explode;e.ThemeManager.requireLangPack("advanced");e.create("tinymce.themes.AdvancedTheme",{sizes:[8,10,12,14,18,24,36],controls:{bold:["bold_desc","Bold"],italic:["italic_desc","Italic"],underline:["underline_desc","Underline"],strikethrough:["striketrough_desc","Strikethrough"],justifyleft:["justifyleft_desc","JustifyLeft"],justifycenter:["justifycenter_desc","JustifyCenter"],justifyright:["justifyright_desc","JustifyRight"],justifyfull:["justifyfull_desc","JustifyFull"],bullist:["bullist_desc","InsertUnorderedList"],numlist:["numlist_desc","InsertOrderedList"],outdent:["outdent_desc","Outdent"],indent:["indent_desc","Indent"],cut:["cut_desc","Cut"],copy:["copy_desc","Copy"],paste:["paste_desc","Paste"],undo:["undo_desc","Undo"],redo:["redo_desc","Redo"],link:["link_desc","mceLink"],unlink:["unlink_desc","unlink"],image:["image_desc","mceImage"],cleanup:["cleanup_desc","mceCleanup"],help:["help_desc","mceHelp"],code:["code_desc","mceCodeEditor"],hr:["hr_desc","InsertHorizontalRule"],removeformat:["removeformat_desc","RemoveFormat"],sub:["sub_desc","subscript"],sup:["sup_desc","superscript"],forecolor:["forecolor_desc","ForeColor"],forecolorpicker:["forecolor_desc","mceForeColor"],backcolor:["backcolor_desc","HiliteColor"],backcolorpicker:["backcolor_desc","mceBackColor"],charmap:["charmap_desc","mceCharMap"],visualaid:["visualaid_desc","mceToggleVisualAid"],anchor:["anchor_desc","mceInsertAnchor"],newdocument:["newdocument_desc","mceNewDocument"],blockquote:["blockquote_desc","mceBlockQuote"]},stateControls:["bold","italic","underline","strikethrough","bullist","numlist","justifyleft","justifycenter","justifyright","justifyfull","sub","sup","blockquote"],init:function(j,k){var l=this,m,i,n;l.editor=j;l.url=k;l.onResolveName=new e.util.Dispatcher(this);l.settings=m=h({theme_advanced_path:true,theme_advanced_toolbar_location:"bottom",theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,|,sub,sup,|,charmap",theme_advanced_blockformats:"p,address,pre,h1,h2,h3,h4,h5,h6",theme_advanced_toolbar_align:"center",theme_advanced_fonts:"Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",theme_advanced_more_colors:1,theme_advanced_row_height:23,theme_advanced_resize_horizontal:1,theme_advanced_resizing_use_cookie:1,theme_advanced_font_sizes:"1,2,3,4,5,6,7",readonly:j.settings.readonly},j.settings);if(!m.font_size_style_values){m.font_size_style_values="8pt,10pt,12pt,14pt,18pt,24pt,36pt"}if(e.is(m.theme_advanced_font_sizes,"string")){m.font_size_style_values=e.explode(m.font_size_style_values);m.font_size_classes=e.explode(m.font_size_classes||"");n={};j.settings.theme_advanced_font_sizes=m.theme_advanced_font_sizes;f(j.getParam("theme_advanced_font_sizes","","hash"),function(q,p){var o;if(p==q&&q>=1&&q<=7){p=q+" ("+l.sizes[q-1]+"pt)";if(j.settings.convert_fonts_to_spans){o=m.font_size_classes[q-1];q=m.font_size_style_values[q-1]||(l.sizes[q-1]+"pt")}}if(/^\s*\./.test(q)){o=q.replace(/\./g,"")}n[p]=o?{"class":o}:{fontSize:q}});m.theme_advanced_font_sizes=n}if((i=m.theme_advanced_path_location)&&i!="none"){m.theme_advanced_statusbar_location=m.theme_advanced_path_location}if(m.theme_advanced_statusbar_location=="none"){m.theme_advanced_statusbar_location=0}j.onInit.add(function(){j.onNodeChange.add(l._nodeChanged,l);if(j.settings.content_css!==false){j.dom.loadCSS(j.baseURI.toAbsolute("themes/advanced/skins/"+j.settings.skin+"/content.css"))}});j.onSetProgressState.add(function(q,o,r){var s,t=q.id,p;if(o){l.progressTimer=setTimeout(function(){s=q.getContainer();s=s.insertBefore(d.create("DIV",{style:"position:relative"}),s.firstChild);p=d.get(q.id+"_tbl");d.add(s,"div",{id:t+"_blocker","class":"mceBlocker",style:{width:p.clientWidth+2,height:p.clientHeight+2}});d.add(s,"div",{id:t+"_progress","class":"mceProgress",style:{left:p.clientWidth/2,top:p.clientHeight/2}})},r||0)}else{d.remove(t+"_blocker");d.remove(t+"_progress");clearTimeout(l.progressTimer)}});d.loadCSS(m.editor_css?j.documentBaseURI.toAbsolute(m.editor_css):k+"/skins/"+j.settings.skin+"/ui.css");if(m.skin_variant){d.loadCSS(k+"/skins/"+j.settings.skin+"/ui_"+m.skin_variant+".css")}},createControl:function(l,i){var j,k;if(k=i.createControl(l)){return k}switch(l){case"styleselect":return this._createStyleSelect();case"formatselect":return this._createBlockFormats();case"fontselect":return this._createFontSelect();case"fontsizeselect":return this._createFontSizeSelect();case"forecolor":return this._createForeColorMenu();case"backcolor":return this._createBackColorMenu()}if((j=this.controls[l])){return i.createButton(l,{title:"advanced."+j[0],cmd:j[1],ui:j[2],value:j[3]})}},execCommand:function(k,j,l){var i=this["_"+k];if(i){i.call(this,j,l);return true}return false},_importClasses:function(j){var i=this.editor,k=i.controlManager.get("styleselect");if(k.getLength()==0){f(i.dom.getClasses(),function(l){k.add(l["class"],l["class"])})}},_createStyleSelect:function(m){var j=this,i=j.editor,k=i.controlManager,l=k.createListBox("styleselect",{title:"advanced.style_select",onselect:function(n){if(l.selectedValue===n){i.execCommand("mceSetStyleInfo",0,{command:"removeformat"});l.select();return false}else{i.execCommand("mceSetCSSClass",0,n)}}});if(l){f(i.getParam("theme_advanced_styles","","hash"),function(o,n){if(o){l.add(j.editor.translate(n),o)}});l.onPostRender.add(function(o,p){if(!l.NativeListBox){b.add(p.id+"_text","focus",j._importClasses,j);b.add(p.id+"_text","mousedown",j._importClasses,j);b.add(p.id+"_open","focus",j._importClasses,j);b.add(p.id+"_open","mousedown",j._importClasses,j)}else{b.add(p.id,"focus",j._importClasses,j)}})}return l},_createFontSelect:function(){var k,j=this,i=j.editor;k=i.controlManager.createListBox("fontselect",{title:"advanced.fontdefault",cmd:"FontName"});if(k){f(i.getParam("theme_advanced_fonts",j.settings.theme_advanced_fonts,"hash"),function(m,l){k.add(i.translate(l),m,{style:m.indexOf("dings")==-1?"font-family:"+m:""})})}return k},_createFontSizeSelect:function(){var m=this,k=m.editor,n,l=0,j=[];n=k.controlManager.createListBox("fontsizeselect",{title:"advanced.font_size",onselect:function(i){if(i.fontSize){k.execCommand("FontSize",false,i.fontSize)}else{f(m.settings.theme_advanced_font_sizes,function(p,o){if(p["class"]){j.push(p["class"])}});k.editorCommands._applyInlineStyle("span",{"class":i["class"]},{check_classes:j})}}});if(n){f(m.settings.theme_advanced_font_sizes,function(o,i){var p=o.fontSize;if(p>=1&&p<=7){p=m.sizes[parseInt(p)-1]+"pt"}n.add(i,o,{style:"font-size:"+p,"class":"mceFontSize"+(l++)+(" "+(o["class"]||""))})})}return n},_createBlockFormats:function(){var k,i={p:"advanced.paragraph",address:"advanced.address",pre:"advanced.pre",h1:"advanced.h1",h2:"advanced.h2",h3:"advanced.h3",h4:"advanced.h4",h5:"advanced.h5",h6:"advanced.h6",div:"advanced.div",blockquote:"advanced.blockquote",code:"advanced.code",dt:"advanced.dt",dd:"advanced.dd",samp:"advanced.samp"},j=this;k=j.editor.controlManager.createListBox("formatselect",{title:"advanced.block",cmd:"FormatBlock"});if(k){f(j.editor.getParam("theme_advanced_blockformats",j.settings.theme_advanced_blockformats,"hash"),function(m,l){k.add(j.editor.translate(l!=m?l:i[m]),m,{"class":"mce_formatPreview mce_"+m})})}return k},_createForeColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_text_colors){l.colors=i}if(k.theme_advanced_default_foreground_color){l.default_color=k.theme_advanced_default_foreground_color}l.title="advanced.forecolor_desc";l.cmd="ForeColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("forecolor",l);return m},_createBackColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_background_colors){l.colors=i}if(k.theme_advanced_default_background_color){l.default_color=k.theme_advanced_default_background_color}l.title="advanced.backcolor_desc";l.cmd="HiliteColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("backcolor",l);return m},renderUI:function(k){var m,l,q,v=this,r=v.editor,w=v.settings,u,j,i;m=j=d.create("span",{id:r.id+"_parent","class":"mceEditor "+r.settings.skin+"Skin"+(w.skin_variant?" "+r.settings.skin+"Skin"+v._ufirst(w.skin_variant):"")});if(!d.boxModel){m=d.add(m,"div",{"class":"mceOldBoxModel"})}m=u=d.add(m,"table",{id:r.id+"_tbl","class":"mceLayout",cellSpacing:0,cellPadding:0});m=q=d.add(m,"tbody");switch((w.theme_advanced_layout_manager||"").toLowerCase()){case"rowlayout":l=v._rowLayout(w,q,k);break;case"customlayout":l=r.execCallback("theme_advanced_custom_layout",w,q,k,j);break;default:l=v._simpleLayout(w,q,k,j)}m=k.targetNode;i=d.stdMode?u.getElementsByTagName("tr"):u.rows;d.addClass(i[0],"mceFirst");d.addClass(i[i.length-1],"mceLast");f(d.select("tr",q),function(o){d.addClass(o.firstChild,"mceFirst");d.addClass(o.childNodes[o.childNodes.length-1],"mceLast")});if(d.get(w.theme_advanced_toolbar_container)){d.get(w.theme_advanced_toolbar_container).appendChild(j)}else{d.insertAfter(j,m)}b.add(r.id+"_path_row","click",function(n){n=n.target;if(n.nodeName=="A"){v._sel(n.className.replace(/^.*mcePath_([0-9]+).*$/,"$1"));return b.cancel(n)}});if(!r.getParam("accessibility_focus")){b.add(d.add(j,"a",{href:"#"},""),"focus",function(){tinyMCE.get(r.id).focus()})}if(w.theme_advanced_toolbar_location=="external"){k.deltaHeight=0}v.deltaHeight=k.deltaHeight;k.targetNode=null;return{iframeContainer:l,editorContainer:r.id+"_parent",sizeContainer:u,deltaHeight:k.deltaHeight}},getInfo:function(){return{longname:"Advanced theme",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",version:e.majorVersion+"."+e.minorVersion}},resizeBy:function(i,j){var k=d.get(this.editor.id+"_tbl");this.resizeTo(k.clientWidth+i,k.clientHeight+j)},resizeTo:function(i,l){var j=this.editor,k=j.settings,n=d.get(j.id+"_tbl"),o=d.get(j.id+"_ifr"),m;i=Math.max(k.theme_advanced_resizing_min_width||100,i);l=Math.max(k.theme_advanced_resizing_min_height||100,l);i=Math.min(k.theme_advanced_resizing_max_width||65535,i);l=Math.min(k.theme_advanced_resizing_max_height||65535,l);m=n.clientHeight-o.clientHeight;d.setStyle(o,"height",l-m);d.setStyles(n,{width:i,height:l})},destroy:function(){var i=this.editor.id;b.clear(i+"_resize");b.clear(i+"_path_row");b.clear(i+"_external_close")},_simpleLayout:function(y,r,k,i){var x=this,u=x.editor,v=y.theme_advanced_toolbar_location,m=y.theme_advanced_statusbar_location,l,j,q,w;if(y.readonly){l=d.add(r,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"});return j}if(v=="top"){x._addToolbars(r,k)}if(v=="external"){l=w=d.create("div",{style:"position:relative"});l=d.add(l,"div",{id:u.id+"_external","class":"mceExternalToolbar"});d.add(l,"a",{id:u.id+"_external_close",href:"javascript:;","class":"mceExternalClose"});l=d.add(l,"table",{id:u.id+"_tblext",cellSpacing:0,cellPadding:0});q=d.add(l,"tbody");if(i.firstChild.className=="mceOldBoxModel"){i.firstChild.appendChild(w)}else{i.insertBefore(w,i.firstChild)}x._addToolbars(q,k);u.onMouseUp.add(function(){var o=d.get(u.id+"_external");d.show(o);d.hide(g);var n=b.add(u.id+"_external_close","click",function(){d.hide(u.id+"_external");b.remove(u.id+"_external_close","click",n)});d.show(o);d.setStyle(o,"top",0-d.getRect(u.id+"_tblext").h-1);d.hide(o);d.show(o);o.style.filter="";g=u.id+"_external";o=null})}if(m=="top"){x._addStatusBar(r,k)}if(!y.theme_advanced_toolbar_container){l=d.add(r,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"})}if(v=="bottom"){x._addToolbars(r,k)}if(m=="bottom"){x._addStatusBar(r,k)}return j},_rowLayout:function(w,m,k){var v=this,p=v.editor,u,x,i=p.controlManager,l,j,r,q;u=w.theme_advanced_containers_default_class||"";x=w.theme_advanced_containers_default_align||"center";f(c(w.theme_advanced_containers||""),function(s,o){var n=w["theme_advanced_container_"+s]||"";switch(n.toLowerCase()){case"mceeditor":l=d.add(m,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"});break;case"mceelementpath":v._addStatusBar(m,k);break;default:q=(w["theme_advanced_container_"+s+"_align"]||x).toLowerCase();q="mce"+v._ufirst(q);l=d.add(d.add(m,"tr"),"td",{"class":"mceToolbar "+(w["theme_advanced_container_"+s+"_class"]||u)+" "+q||x});r=i.createToolbar("toolbar"+o);v._addControls(n,r);d.setHTML(l,r.renderHTML());k.deltaHeight-=w.theme_advanced_row_height}});return j},_addControls:function(j,i){var k=this,l=k.settings,m,n=k.editor.controlManager;if(l.theme_advanced_disable&&!k._disabled){m={};f(c(l.theme_advanced_disable),function(o){m[o]=1});k._disabled=m}else{m=k._disabled}f(c(j),function(p){var o;if(m&&m[p]){return}if(p=="tablecontrols"){f(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"],function(q){q=k.createControl(q,n);if(q){i.add(q)}});return}o=k.createControl(p,n);if(o){i.add(o)}})},_addToolbars:function(w,k){var z=this,p,m,r=z.editor,A=z.settings,y,j=r.controlManager,u,l,q=[],x;x=A.theme_advanced_toolbar_align.toLowerCase();x="mce"+z._ufirst(x);l=d.add(d.add(w,"tr"),"td",{"class":"mceToolbar "+x});if(!r.getParam("accessibility_focus")){q.push(d.createHTML("a",{href:"#",onfocus:"tinyMCE.get('"+r.id+"').focus();"},""))}q.push(d.createHTML("a",{href:"#",accesskey:"q",title:r.getLang("advanced.toolbar_focus")},""));for(p=1;(y=A["theme_advanced_buttons"+p]);p++){m=j.createToolbar("toolbar"+p,{"class":"mceToolbarRow"+p});if(A["theme_advanced_buttons"+p+"_add"]){y+=","+A["theme_advanced_buttons"+p+"_add"]}if(A["theme_advanced_buttons"+p+"_add_before"]){y=A["theme_advanced_buttons"+p+"_add_before"]+","+y}z._addControls(y,m);q.push(m.renderHTML());k.deltaHeight-=A.theme_advanced_row_height}q.push(d.createHTML("a",{href:"#",accesskey:"z",title:r.getLang("advanced.toolbar_focus"),onfocus:"tinyMCE.getInstanceById('"+r.id+"').focus();"},""));d.setHTML(l,q.join(""))},_addStatusBar:function(m,j){var k,v=this,p=v.editor,w=v.settings,i,q,u,l;k=d.add(m,"tr");k=l=d.add(k,"td",{"class":"mceStatusbar"});k=d.add(k,"div",{id:p.id+"_path_row"},w.theme_advanced_path?p.translate("advanced.path")+": ":" ");d.add(k,"a",{href:"#",accesskey:"x"});if(w.theme_advanced_resizing){d.add(l,"a",{id:p.id+"_resize",href:"javascript:;",onclick:"return false;","class":"mceResize"});if(w.theme_advanced_resizing_use_cookie){p.onPostRender.add(function(){var n=a.getHash("TinyMCE_"+p.id+"_size"),r=d.get(p.id+"_tbl");if(!n){return}if(w.theme_advanced_resize_horizontal){r.style.width=Math.max(10,n.cw)+"px"}r.style.height=Math.max(10,n.ch)+"px";d.get(p.id+"_ifr").style.height=Math.max(10,parseInt(n.ch)+v.deltaHeight)+"px"})}p.onPostRender.add(function(){b.add(p.id+"_resize","mousedown",function(x){var z,t,o,s,y,r;z=d.get(p.id+"_tbl");o=z.clientWidth;s=z.clientHeight;miw=w.theme_advanced_resizing_min_width||100;mih=w.theme_advanced_resizing_min_height||100;maw=w.theme_advanced_resizing_max_width||65535;mah=w.theme_advanced_resizing_max_height||65535;t=d.add(d.get(p.id+"_parent"),"div",{"class":"mcePlaceHolder"});d.setStyles(t,{width:o,height:s});d.hide(z);d.show(t);i={x:x.screenX,y:x.screenY,w:o,h:s,dx:null,dy:null};q=b.add(d.doc,"mousemove",function(B){var n,A;i.dx=B.screenX-i.x;i.dy=B.screenY-i.y;n=Math.max(miw,i.w+i.dx);A=Math.max(mih,i.h+i.dy);n=Math.min(maw,n);A=Math.min(mah,A);if(w.theme_advanced_resize_horizontal){t.style.width=n+"px"}t.style.height=A+"px";return b.cancel(B)});u=b.add(d.doc,"mouseup",function(n){var A;b.remove(d.doc,"mousemove",q);b.remove(d.doc,"mouseup",u);z.style.display="";d.remove(t);if(i.dx===null){return}A=d.get(p.id+"_ifr");if(w.theme_advanced_resize_horizontal){z.style.width=Math.max(10,i.w+i.dx)+"px"}z.style.height=Math.max(10,i.h+i.dy)+"px";A.style.height=Math.max(10,A.clientHeight+i.dy)+"px";if(w.theme_advanced_resizing_use_cookie){a.setHash("TinyMCE_"+p.id+"_size",{cw:i.w+i.dx,ch:i.h+i.dy})}});return b.cancel(x)})})}j.deltaHeight-=21;k=m=null},_nodeChanged:function(l,u,k,q){var y=this,i,r=0,x,m,z=y.settings,w,j,o;if(z.readonly){return}e.each(y.stateControls,function(n){u.setActive(n,l.queryCommandState(y.controls[n][1]))});u.setActive("visualaid",l.hasVisual);u.setDisabled("undo",!l.undoManager.hasUndo()&&!l.typing);u.setDisabled("redo",!l.undoManager.hasRedo());u.setDisabled("outdent",!l.queryCommandState("Outdent"));i=d.getParent(k,"A");if(m=u.get("link")){if(!i||!i.name){m.setDisabled(!i&&q);m.setActive(!!i)}}if(m=u.get("unlink")){m.setDisabled(!i&&q);m.setActive(!!i&&!i.name)}if(m=u.get("anchor")){m.setActive(!!i&&i.name);if(e.isWebKit){i=d.getParent(k,"IMG");m.setActive(!!i&&d.getAttrib(i,"mce_name")=="a")}}i=d.getParent(k,"IMG");if(m=u.get("image")){m.setActive(!!i&&k.className.indexOf("mceItem")==-1)}if(m=u.get("styleselect")){if(k.className){y._importClasses();m.select(k.className)}else{m.select()}}if(m=u.get("formatselect")){i=d.getParent(k,d.isBlock);if(i){m.select(i.nodeName.toLowerCase())}}if(l.settings.convert_fonts_to_spans){l.dom.getParent(k,function(p){if(p.nodeName==="SPAN"){if(!w&&p.className){w=p.className}if(!j&&p.style.fontSize){j=p.style.fontSize}if(!o&&p.style.fontFamily){o=p.style.fontFamily.replace(/[\"\']+/g,"").replace(/^([^,]+).*/,"$1").toLowerCase()}}return false});if(m=u.get("fontselect")){m.select(function(n){return n.replace(/^([^,]+).*/,"$1").toLowerCase()==o})}if(m=u.get("fontsizeselect")){m.select(function(n){if(n.fontSize&&n.fontSize===j){return true}if(n["class"]&&n["class"]===w){return true}})}}else{if(m=u.get("fontselect")){m.select(l.queryCommandValue("FontName"))}if(m=u.get("fontsizeselect")){x=l.queryCommandValue("FontSize");m.select(function(n){return n.fontSize==x})}}if(z.theme_advanced_path&&z.theme_advanced_statusbar_location){i=d.get(l.id+"_path")||d.add(l.id+"_path_row","span",{id:l.id+"_path"});d.setHTML(i,"");l.dom.getParent(k,function(A){var p=A.nodeName.toLowerCase(),s,v,t="";if(A.nodeType!=1||A.nodeName==="BR"||(d.hasClass(A,"mceItemHidden")||d.hasClass(A,"mceItemRemoved"))){return}if(x=d.getAttrib(A,"mce_name")){p=x}if(e.isIE&&A.scopeName!=="HTML"){p=A.scopeName+":"+p}p=p.replace(/mce\:/g,"");switch(p){case"b":p="strong";break;case"i":p="em";break;case"img":if(x=d.getAttrib(A,"src")){t+="src: "+x+" "}break;case"a":if(x=d.getAttrib(A,"name")){t+="name: "+x+" ";p+="#"+x}if(x=d.getAttrib(A,"href")){t+="href: "+x+" "}break;case"font":if(z.convert_fonts_to_spans){p="span"}if(x=d.getAttrib(A,"face")){t+="font: "+x+" "}if(x=d.getAttrib(A,"size")){t+="size: "+x+" "}if(x=d.getAttrib(A,"color")){t+="color: "+x+" "}break;case"span":if(x=d.getAttrib(A,"style")){t+="style: "+x+" "}break}if(x=d.getAttrib(A,"id")){t+="id: "+x+" "}if(x=A.className){x=x.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g,"");if(x&&x.indexOf("mceItem")==-1){t+="class: "+x+" ";if(d.isBlock(A)||p=="img"||p=="span"){p+="."+x}}}p=p.replace(/(html:)/g,"");p={name:p,node:A,title:t};y.onResolveName.dispatch(y,p);t=p.title;p=p.name;v=d.create("a",{href:"javascript:;",onmousedown:"return false;",title:t,"class":"mcePath_"+(r++)},p);if(i.hasChildNodes()){i.insertBefore(d.doc.createTextNode(" \u00bb "),i.firstChild);i.insertBefore(v,i.firstChild)}else{i.appendChild(v)}},l.getBody())}},_sel:function(i){this.editor.execCommand("mceSelectNodeDepth",false,i)},_mceInsertAnchor:function(k,j){var i=this.editor;i.windowManager.open({url:e.baseURL+"/themes/advanced/anchor.htm",width:320+parseInt(i.getLang("advanced.anchor_delta_width",0)),height:90+parseInt(i.getLang("advanced.anchor_delta_height",0)),inline:true},{theme_url:this.url})},_mceCharMap:function(){var i=this.editor;i.windowManager.open({url:e.baseURL+"/themes/advanced/charmap.htm",width:550+parseInt(i.getLang("advanced.charmap_delta_width",0)),height:250+parseInt(i.getLang("advanced.charmap_delta_height",0)),inline:true},{theme_url:this.url})},_mceHelp:function(){var i=this.editor;i.windowManager.open({url:e.baseURL+"/themes/advanced/about.htm",width:480,height:380,inline:true},{theme_url:this.url})},_mceColorPicker:function(k,j){var i=this.editor;j=j||{};i.windowManager.open({url:e.baseURL+"/themes/advanced/color_picker.htm",width:375+parseInt(i.getLang("advanced.colorpicker_delta_width",0)),height:250+parseInt(i.getLang("advanced.colorpicker_delta_height",0)),close_previous:false,inline:true},{input_color:j.color,func:j.func,theme_url:this.url})},_mceCodeEditor:function(j,k){var i=this.editor;i.windowManager.open({url:e.baseURL+"/themes/advanced/source_editor.htm",width:parseInt(i.getParam("theme_advanced_source_editor_width",720)),height:parseInt(i.getParam("theme_advanced_source_editor_height",580)),inline:true,resizable:true,maximizable:true},{theme_url:this.url})},_mceImage:function(j,k){var i=this.editor;if(i.dom.getAttrib(i.selection.getNode(),"class").indexOf("mceItem")!=-1){return}i.windowManager.open({url:e.baseURL+"/themes/advanced/image.htm",width:355+parseInt(i.getLang("advanced.image_delta_width",0)),height:275+parseInt(i.getLang("advanced.image_delta_height",0)),inline:true},{theme_url:this.url})},_mceLink:function(j,k){var i=this.editor;i.windowManager.open({url:e.baseURL+"/themes/advanced/link.htm",width:310+parseInt(i.getLang("advanced.link_delta_width",0)),height:200+parseInt(i.getLang("advanced.link_delta_height",0)),inline:true},{theme_url:this.url})},_mceNewDocument:function(){var i=this.editor;i.windowManager.confirm("advanced.newdocument",function(j){if(j){i.execCommand("mceSetContent",false,"")}})},_mceForeColor:function(){var i=this;this._mceColorPicker(0,{color:i.fgColor,func:function(j){i.fgColor=j;i.editor.execCommand("ForeColor",false,j)}})},_mceBackColor:function(){var i=this;this._mceColorPicker(0,{color:i.bgColor,func:function(j){i.bgColor=j;i.editor.execCommand("HiliteColor",false,j)}})},_ufirst:function(i){return i.substring(0,1).toUpperCase()+i.substring(1)}});e.ThemeManager.add("advanced",e.themes.AdvancedTheme)}(tinymce)); \ No newline at end of file +(function(e){var d=e.DOM,b=e.dom.Event,h=e.extend,f=e.each,a=e.util.Cookie,g,c=e.explode;e.ThemeManager.requireLangPack("advanced");e.create("tinymce.themes.AdvancedTheme",{sizes:[8,10,12,14,18,24,36],controls:{bold:["bold_desc","Bold"],italic:["italic_desc","Italic"],underline:["underline_desc","Underline"],strikethrough:["striketrough_desc","Strikethrough"],justifyleft:["justifyleft_desc","JustifyLeft"],justifycenter:["justifycenter_desc","JustifyCenter"],justifyright:["justifyright_desc","JustifyRight"],justifyfull:["justifyfull_desc","JustifyFull"],bullist:["bullist_desc","InsertUnorderedList"],numlist:["numlist_desc","InsertOrderedList"],outdent:["outdent_desc","Outdent"],indent:["indent_desc","Indent"],cut:["cut_desc","Cut"],copy:["copy_desc","Copy"],paste:["paste_desc","Paste"],undo:["undo_desc","Undo"],redo:["redo_desc","Redo"],link:["link_desc","mceLink"],unlink:["unlink_desc","unlink"],image:["image_desc","mceImage"],cleanup:["cleanup_desc","mceCleanup"],help:["help_desc","mceHelp"],code:["code_desc","mceCodeEditor"],hr:["hr_desc","InsertHorizontalRule"],removeformat:["removeformat_desc","RemoveFormat"],sub:["sub_desc","subscript"],sup:["sup_desc","superscript"],forecolor:["forecolor_desc","ForeColor"],forecolorpicker:["forecolor_desc","mceForeColor"],backcolor:["backcolor_desc","HiliteColor"],backcolorpicker:["backcolor_desc","mceBackColor"],charmap:["charmap_desc","mceCharMap"],visualaid:["visualaid_desc","mceToggleVisualAid"],anchor:["anchor_desc","mceInsertAnchor"],newdocument:["newdocument_desc","mceNewDocument"],blockquote:["blockquote_desc","mceBlockQuote"]},stateControls:["bold","italic","underline","strikethrough","bullist","numlist","justifyleft","justifycenter","justifyright","justifyfull","sub","sup","blockquote"],init:function(j,k){var l=this,m,i,n;l.editor=j;l.url=k;l.onResolveName=new e.util.Dispatcher(this);l.settings=m=h({theme_advanced_path:true,theme_advanced_toolbar_location:"bottom",theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,|,sub,sup,|,charmap",theme_advanced_blockformats:"p,address,pre,h1,h2,h3,h4,h5,h6",theme_advanced_toolbar_align:"center",theme_advanced_fonts:"Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",theme_advanced_more_colors:1,theme_advanced_row_height:23,theme_advanced_resize_horizontal:1,theme_advanced_resizing_use_cookie:1,theme_advanced_font_sizes:"1,2,3,4,5,6,7",readonly:j.settings.readonly},j.settings);if(!m.font_size_style_values){m.font_size_style_values="8pt,10pt,12pt,14pt,18pt,24pt,36pt"}if(e.is(m.theme_advanced_font_sizes,"string")){m.font_size_style_values=e.explode(m.font_size_style_values);m.font_size_classes=e.explode(m.font_size_classes||"");n={};j.settings.theme_advanced_font_sizes=m.theme_advanced_font_sizes;f(j.getParam("theme_advanced_font_sizes","","hash"),function(q,p){var o;if(p==q&&q>=1&&q<=7){p=q+" ("+l.sizes[q-1]+"pt)";o=m.font_size_classes[q-1];q=m.font_size_style_values[q-1]||(l.sizes[q-1]+"pt")}if(/^\s*\./.test(q)){o=q.replace(/\./g,"")}n[p]=o?{"class":o}:{fontSize:q}});m.theme_advanced_font_sizes=n}if((i=m.theme_advanced_path_location)&&i!="none"){m.theme_advanced_statusbar_location=m.theme_advanced_path_location}if(m.theme_advanced_statusbar_location=="none"){m.theme_advanced_statusbar_location=0}j.onInit.add(function(){if(!j.settings.readonly){j.onNodeChange.add(l._nodeChanged,l)}if(j.settings.content_css!==false){j.dom.loadCSS(j.baseURI.toAbsolute("themes/advanced/skins/"+j.settings.skin+"/content.css"))}});j.onSetProgressState.add(function(q,o,r){var s,t=q.id,p;if(o){l.progressTimer=setTimeout(function(){s=q.getContainer();s=s.insertBefore(d.create("DIV",{style:"position:relative"}),s.firstChild);p=d.get(q.id+"_tbl");d.add(s,"div",{id:t+"_blocker","class":"mceBlocker",style:{width:p.clientWidth+2,height:p.clientHeight+2}});d.add(s,"div",{id:t+"_progress","class":"mceProgress",style:{left:p.clientWidth/2,top:p.clientHeight/2}})},r||0)}else{d.remove(t+"_blocker");d.remove(t+"_progress");clearTimeout(l.progressTimer)}});d.loadCSS(m.editor_css?j.documentBaseURI.toAbsolute(m.editor_css):k+"/skins/"+j.settings.skin+"/ui.css");if(m.skin_variant){d.loadCSS(k+"/skins/"+j.settings.skin+"/ui_"+m.skin_variant+".css")}},createControl:function(l,i){var j,k;if(k=i.createControl(l)){return k}switch(l){case"styleselect":return this._createStyleSelect();case"formatselect":return this._createBlockFormats();case"fontselect":return this._createFontSelect();case"fontsizeselect":return this._createFontSizeSelect();case"forecolor":return this._createForeColorMenu();case"backcolor":return this._createBackColorMenu()}if((j=this.controls[l])){return i.createButton(l,{title:"advanced."+j[0],cmd:j[1],ui:j[2],value:j[3]})}},execCommand:function(k,j,l){var i=this["_"+k];if(i){i.call(this,j,l);return true}return false},_importClasses:function(k){var i=this.editor,j=i.controlManager.get("styleselect");if(j.getLength()==0){f(i.dom.getClasses(),function(n,l){var m="style_"+l;i.formatter.register(m,{inline:"span",classes:n["class"],selector:"*"});j.add(n["class"],m)})}},_createStyleSelect:function(m){var k=this,i=k.editor,j=i.controlManager,l;l=j.createListBox("styleselect",{title:"advanced.style_select",onselect:function(n){i.execCommand("mceToggleFormat",false,n);return false}});i.onInit.add(function(){var o=0,n=i.getParam("style_formats");if(n){f(n,function(p){var q,r=0;f(p,function(){r++});if(r>1){q=p.name=p.name||"style_"+(o++);i.formatter.register(q,p);l.add(p.title,q)}else{l.add(p.title)}})}else{f(i.getParam("theme_advanced_styles","","hash"),function(r,q){var p;if(r){p="style_"+(o++);i.formatter.register(p,{inline:"span",classes:r});l.add(k.editor.translate(q),p)}})}});if(l.getLength()==0){l.onPostRender.add(function(o,p){if(!l.NativeListBox){b.add(p.id+"_text","focus",k._importClasses,k);b.add(p.id+"_text","mousedown",k._importClasses,k);b.add(p.id+"_open","focus",k._importClasses,k);b.add(p.id+"_open","mousedown",k._importClasses,k)}else{b.add(p.id,"focus",k._importClasses,k)}})}return l},_createFontSelect:function(){var k,j=this,i=j.editor;k=i.controlManager.createListBox("fontselect",{title:"advanced.fontdefault",onselect:function(l){i.execCommand("FontName",false,l);return false}});if(k){f(i.getParam("theme_advanced_fonts",j.settings.theme_advanced_fonts,"hash"),function(m,l){k.add(i.translate(l),m,{style:m.indexOf("dings")==-1?"font-family:"+m:""})})}return k},_createFontSizeSelect:function(){var m=this,k=m.editor,n,l=0,j=[];n=k.controlManager.createListBox("fontsizeselect",{title:"advanced.font_size",onselect:function(i){if(i.fontSize){k.execCommand("FontSize",false,i.fontSize)}else{f(m.settings.theme_advanced_font_sizes,function(p,o){if(p["class"]){j.push(p["class"])}});k.editorCommands._applyInlineStyle("span",{"class":i["class"]},{check_classes:j})}return false}});if(n){f(m.settings.theme_advanced_font_sizes,function(o,i){var p=o.fontSize;if(p>=1&&p<=7){p=m.sizes[parseInt(p)-1]+"pt"}n.add(i,o,{style:"font-size:"+p,"class":"mceFontSize"+(l++)+(" "+(o["class"]||""))})})}return n},_createBlockFormats:function(){var k,i={p:"advanced.paragraph",address:"advanced.address",pre:"advanced.pre",h1:"advanced.h1",h2:"advanced.h2",h3:"advanced.h3",h4:"advanced.h4",h5:"advanced.h5",h6:"advanced.h6",div:"advanced.div",blockquote:"advanced.blockquote",code:"advanced.code",dt:"advanced.dt",dd:"advanced.dd",samp:"advanced.samp"},j=this;k=j.editor.controlManager.createListBox("formatselect",{title:"advanced.block",cmd:"FormatBlock"});if(k){f(j.editor.getParam("theme_advanced_blockformats",j.settings.theme_advanced_blockformats,"hash"),function(m,l){k.add(j.editor.translate(l!=m?l:i[m]),m,{"class":"mce_formatPreview mce_"+m})})}return k},_createForeColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_text_colors){l.colors=i}if(k.theme_advanced_default_foreground_color){l.default_color=k.theme_advanced_default_foreground_color}l.title="advanced.forecolor_desc";l.cmd="ForeColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("forecolor",l);return m},_createBackColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_background_colors){l.colors=i}if(k.theme_advanced_default_background_color){l.default_color=k.theme_advanced_default_background_color}l.title="advanced.backcolor_desc";l.cmd="HiliteColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("backcolor",l);return m},renderUI:function(k){var m,l,q,v=this,r=v.editor,w=v.settings,u,j,i;m=j=d.create("span",{id:r.id+"_parent","class":"mceEditor "+r.settings.skin+"Skin"+(w.skin_variant?" "+r.settings.skin+"Skin"+v._ufirst(w.skin_variant):"")});if(!d.boxModel){m=d.add(m,"div",{"class":"mceOldBoxModel"})}m=u=d.add(m,"table",{id:r.id+"_tbl","class":"mceLayout",cellSpacing:0,cellPadding:0});m=q=d.add(m,"tbody");switch((w.theme_advanced_layout_manager||"").toLowerCase()){case"rowlayout":l=v._rowLayout(w,q,k);break;case"customlayout":l=r.execCallback("theme_advanced_custom_layout",w,q,k,j);break;default:l=v._simpleLayout(w,q,k,j)}m=k.targetNode;i=d.stdMode?u.getElementsByTagName("tr"):u.rows;d.addClass(i[0],"mceFirst");d.addClass(i[i.length-1],"mceLast");f(d.select("tr",q),function(o){d.addClass(o.firstChild,"mceFirst");d.addClass(o.childNodes[o.childNodes.length-1],"mceLast")});if(d.get(w.theme_advanced_toolbar_container)){d.get(w.theme_advanced_toolbar_container).appendChild(j)}else{d.insertAfter(j,m)}b.add(r.id+"_path_row","click",function(n){n=n.target;if(n.nodeName=="A"){v._sel(n.className.replace(/^.*mcePath_([0-9]+).*$/,"$1"));return b.cancel(n)}});if(!r.getParam("accessibility_focus")){b.add(d.add(j,"a",{href:"#"},""),"focus",function(){tinyMCE.get(r.id).focus()})}if(w.theme_advanced_toolbar_location=="external"){k.deltaHeight=0}v.deltaHeight=k.deltaHeight;k.targetNode=null;return{iframeContainer:l,editorContainer:r.id+"_parent",sizeContainer:u,deltaHeight:k.deltaHeight}},getInfo:function(){return{longname:"Advanced theme",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",version:e.majorVersion+"."+e.minorVersion}},resizeBy:function(i,j){var k=d.get(this.editor.id+"_tbl");this.resizeTo(k.clientWidth+i,k.clientHeight+j)},resizeTo:function(i,l){var j=this.editor,k=j.settings,m=d.get(j.id+"_tbl"),n=d.get(j.id+"_ifr");i=Math.max(k.theme_advanced_resizing_min_width||100,i);l=Math.max(k.theme_advanced_resizing_min_height||100,l);i=Math.min(k.theme_advanced_resizing_max_width||65535,i);l=Math.min(k.theme_advanced_resizing_max_height||65535,l);d.setStyles(m,{width:"",height:""});d.setStyles(n,{width:i,height:l})},destroy:function(){var i=this.editor.id;b.clear(i+"_resize");b.clear(i+"_path_row");b.clear(i+"_external_close")},_simpleLayout:function(y,r,k,i){var x=this,u=x.editor,v=y.theme_advanced_toolbar_location,m=y.theme_advanced_statusbar_location,l,j,q,w;if(y.readonly){l=d.add(r,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"});return j}if(v=="top"){x._addToolbars(r,k)}if(v=="external"){l=w=d.create("div",{style:"position:relative"});l=d.add(l,"div",{id:u.id+"_external","class":"mceExternalToolbar"});d.add(l,"a",{id:u.id+"_external_close",href:"javascript:;","class":"mceExternalClose"});l=d.add(l,"table",{id:u.id+"_tblext",cellSpacing:0,cellPadding:0});q=d.add(l,"tbody");if(i.firstChild.className=="mceOldBoxModel"){i.firstChild.appendChild(w)}else{i.insertBefore(w,i.firstChild)}x._addToolbars(q,k);u.onMouseUp.add(function(){var o=d.get(u.id+"_external");d.show(o);d.hide(g);var n=b.add(u.id+"_external_close","click",function(){d.hide(u.id+"_external");b.remove(u.id+"_external_close","click",n)});d.show(o);d.setStyle(o,"top",0-d.getRect(u.id+"_tblext").h-1);d.hide(o);d.show(o);o.style.filter="";g=u.id+"_external";o=null})}if(m=="top"){x._addStatusBar(r,k)}if(!y.theme_advanced_toolbar_container){l=d.add(r,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"})}if(v=="bottom"){x._addToolbars(r,k)}if(m=="bottom"){x._addStatusBar(r,k)}return j},_rowLayout:function(w,m,k){var v=this,p=v.editor,u,x,i=p.controlManager,l,j,r,q;u=w.theme_advanced_containers_default_class||"";x=w.theme_advanced_containers_default_align||"center";f(c(w.theme_advanced_containers||""),function(s,o){var n=w["theme_advanced_container_"+s]||"";switch(n.toLowerCase()){case"mceeditor":l=d.add(m,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"});break;case"mceelementpath":v._addStatusBar(m,k);break;default:q=(w["theme_advanced_container_"+s+"_align"]||x).toLowerCase();q="mce"+v._ufirst(q);l=d.add(d.add(m,"tr"),"td",{"class":"mceToolbar "+(w["theme_advanced_container_"+s+"_class"]||u)+" "+q||x});r=i.createToolbar("toolbar"+o);v._addControls(n,r);d.setHTML(l,r.renderHTML());k.deltaHeight-=w.theme_advanced_row_height}});return j},_addControls:function(j,i){var k=this,l=k.settings,m,n=k.editor.controlManager;if(l.theme_advanced_disable&&!k._disabled){m={};f(c(l.theme_advanced_disable),function(o){m[o]=1});k._disabled=m}else{m=k._disabled}f(c(j),function(p){var o;if(m&&m[p]){return}if(p=="tablecontrols"){f(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"],function(q){q=k.createControl(q,n);if(q){i.add(q)}});return}o=k.createControl(p,n);if(o){i.add(o)}})},_addToolbars:function(w,k){var z=this,p,m,r=z.editor,A=z.settings,y,j=r.controlManager,u,l,q=[],x;x=A.theme_advanced_toolbar_align.toLowerCase();x="mce"+z._ufirst(x);l=d.add(d.add(w,"tr"),"td",{"class":"mceToolbar "+x});if(!r.getParam("accessibility_focus")){q.push(d.createHTML("a",{href:"#",onfocus:"tinyMCE.get('"+r.id+"').focus();"},""))}q.push(d.createHTML("a",{href:"#",accesskey:"q",title:r.getLang("advanced.toolbar_focus")},""));for(p=1;(y=A["theme_advanced_buttons"+p]);p++){m=j.createToolbar("toolbar"+p,{"class":"mceToolbarRow"+p});if(A["theme_advanced_buttons"+p+"_add"]){y+=","+A["theme_advanced_buttons"+p+"_add"]}if(A["theme_advanced_buttons"+p+"_add_before"]){y=A["theme_advanced_buttons"+p+"_add_before"]+","+y}z._addControls(y,m);q.push(m.renderHTML());k.deltaHeight-=A.theme_advanced_row_height}q.push(d.createHTML("a",{href:"#",accesskey:"z",title:r.getLang("advanced.toolbar_focus"),onfocus:"tinyMCE.getInstanceById('"+r.id+"').focus();"},""));d.setHTML(l,q.join(""))},_addStatusBar:function(m,j){var k,v=this,p=v.editor,w=v.settings,i,q,u,l;k=d.add(m,"tr");k=l=d.add(k,"td",{"class":"mceStatusbar"});k=d.add(k,"div",{id:p.id+"_path_row"},w.theme_advanced_path?p.translate("advanced.path")+": ":" ");d.add(k,"a",{href:"#",accesskey:"x"});if(w.theme_advanced_resizing){d.add(l,"a",{id:p.id+"_resize",href:"javascript:;",onclick:"return false;","class":"mceResize"});if(w.theme_advanced_resizing_use_cookie){p.onPostRender.add(function(){var n=a.getHash("TinyMCE_"+p.id+"_size"),r=d.get(p.id+"_tbl");if(!n){return}v.resizeTo(n.cw,n.ch)})}p.onPostRender.add(function(){b.add(p.id+"_resize","mousedown",function(A){var r,o,D,z,x,y,C,n,B,s;function t(E){n=y+(E.screenX-z);B=C+(E.screenY-x);v.resizeTo(n,B)}A.preventDefault();z=A.screenX;x=A.screenY;s=d.get(v.editor.id+"_ifr");y=n=s.clientWidth;C=B=s.clientHeight;r=b.add(d.doc,"mousemove",t);o=b.add(p.getDoc(),"mousemove",t);D=b.add(d.doc,"mouseup",function(E){b.remove(d.doc,"mousemove",r);b.remove(p.getDoc(),"mousemove",o);b.remove(d.doc,"mouseup",D);if(w.theme_advanced_resizing_use_cookie){a.setHash("TinyMCE_"+p.id+"_size",{cw:n,ch:B})}})})})}j.deltaHeight-=21;k=m=null},_nodeChanged:function(o,x,l,u,j){var A=this,i,w=0,z,q,B=A.settings,y,k,r;e.each(A.stateControls,function(n){x.setActive(n,o.queryCommandState(A.controls[n][1]))});function m(p){var s,n=j.parents,t=p;if(typeof(p)=="string"){t=function(v){return v.nodeName==p}}for(s=0;s= 1 && v <= 7) { k = v + ' (' + t.sizes[v - 1] + 'pt)'; - - if (ed.settings.convert_fonts_to_spans) { - cl = s.font_size_classes[v - 1]; - v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt'); - } + cl = s.font_size_classes[v - 1]; + v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt'); } if (/^\s*\./.test(v)) @@ -121,7 +121,8 @@ // Init editor ed.onInit.add(function() { - ed.onNodeChange.add(t._nodeChanged, t); + if (!ed.settings.readonly) + ed.onNodeChange.add(t._nodeChanged, t); if (ed.settings.content_css !== false) ed.dom.loadCSS(ed.baseURI.toAbsolute("themes/advanced/skins/" + ed.settings.skin + "/content.css")); @@ -194,36 +195,75 @@ }, _importClasses : function(e) { - var ed = this.editor, c = ed.controlManager.get('styleselect'); + var ed = this.editor, ctrl = ed.controlManager.get('styleselect'); - if (c.getLength() == 0) { - each(ed.dom.getClasses(), function(o) { - c.add(o['class'], o['class']); + if (ctrl.getLength() == 0) { + each(ed.dom.getClasses(), function(o, idx) { + var name = 'style_' + idx; + + ed.formatter.register(name, { + inline : 'span', + classes : o['class'], + selector : '*' + }); + + ctrl.add(o['class'], name); }); } }, _createStyleSelect : function(n) { - var t = this, ed = t.editor, cf = ed.controlManager, c = cf.createListBox('styleselect', { + var t = this, ed = t.editor, ctrlMan = ed.controlManager, ctrl; + + // Setup style select box + ctrl = ctrlMan.createListBox('styleselect', { title : 'advanced.style_select', - onselect : function(v) { - if (c.selectedValue === v) { - ed.execCommand('mceSetStyleInfo', 0, {command : 'removeformat'}); - c.select(); - return false; - } else - ed.execCommand('mceSetCSSClass', 0, v); + onselect : function(name) { + ed.execCommand('mceToggleFormat', false, name); + + return false; // No auto select } }); - if (c) { - each(ed.getParam('theme_advanced_styles', '', 'hash'), function(v, k) { - if (v) - c.add(t.editor.translate(k), v); - }); + // Handle specified format + ed.onInit.add(function() { + var counter = 0, formats = ed.getParam('style_formats'); + + if (formats) { + each(formats, function(fmt) { + var name, keys = 0; + + each(fmt, function() {keys++;}); + + if (keys > 1) { + name = fmt.name = fmt.name || 'style_' + (counter++); + ed.formatter.register(name, fmt); + ctrl.add(fmt.title, name); + } else + ctrl.add(fmt.title); + }); + } else { + each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) { + var name; - c.onPostRender.add(function(ed, n) { - if (!c.NativeListBox) { + if (val) { + name = 'style_' + (counter++); + + ed.formatter.register(name, { + inline : 'span', + classes : val + }); + + ctrl.add(t.editor.translate(key), name); + } + }); + } + }); + + // Auto import classes if the ctrl box is empty + if (ctrl.getLength() == 0) { + ctrl.onPostRender.add(function(ed, n) { + if (!ctrl.NativeListBox) { Event.add(n.id + '_text', 'focus', t._importClasses, t); Event.add(n.id + '_text', 'mousedown', t._importClasses, t); Event.add(n.id + '_open', 'focus', t._importClasses, t); @@ -233,13 +273,20 @@ }); } - return c; + return ctrl; }, _createFontSelect : function() { var c, t = this, ed = t.editor; - c = ed.controlManager.createListBox('fontselect', {title : 'advanced.fontdefault', cmd : 'FontName'}); + c = ed.controlManager.createListBox('fontselect', { + title : 'advanced.fontdefault', + onselect : function(v) { + ed.execCommand('FontName', false, v); + return false; // No auto select + } + }); + if (c) { each(ed.getParam('theme_advanced_fonts', t.settings.theme_advanced_fonts, 'hash'), function(v, k) { c.add(ed.translate(k), v, {style : v.indexOf('dings') == -1 ? 'font-family:' + v : ''}); @@ -263,6 +310,8 @@ ed.editorCommands._applyInlineStyle('span', {'class' : v['class']}, {check_classes : cl}); } + + return false; // No auto select }}); if (c) { @@ -473,7 +522,7 @@ }, resizeTo : function(w, h) { - var ed = this.editor, s = ed.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr'), dh; + var ed = this.editor, s = ed.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr'); // Boundery fix box w = Math.max(s.theme_advanced_resizing_min_width || 100, w); @@ -481,12 +530,9 @@ w = Math.min(s.theme_advanced_resizing_max_width || 0xFFFF, w); h = Math.min(s.theme_advanced_resizing_max_height || 0xFFFF, h); - // Calc difference between iframe and container - dh = e.clientHeight - ifr.clientHeight; - // Resize iframe and container - DOM.setStyle(ifr, 'height', h - dh); - DOM.setStyles(e, {width : w, height : h}); + DOM.setStyles(e, {width : '', height : ''}); + DOM.setStyles(ifr, {width : w, height : h}); }, destroy : function() { @@ -700,99 +746,48 @@ if (!o) return; - if (s.theme_advanced_resize_horizontal) - c.style.width = Math.max(10, o.cw) + 'px'; - - c.style.height = Math.max(10, o.ch) + 'px'; - DOM.get(ed.id + '_ifr').style.height = Math.max(10, parseInt(o.ch) + t.deltaHeight) + 'px'; + t.resizeTo(o.cw, o.ch); }); } ed.onPostRender.add(function() { Event.add(ed.id + '_resize', 'mousedown', function(e) { - var c, p, w, h, n, pa; - - // Measure container - c = DOM.get(ed.id + '_tbl'); - w = c.clientWidth; - h = c.clientHeight; - - miw = s.theme_advanced_resizing_min_width || 100; - mih = s.theme_advanced_resizing_min_height || 100; - maw = s.theme_advanced_resizing_max_width || 0xFFFF; - mah = s.theme_advanced_resizing_max_height || 0xFFFF; - - // Setup placeholder - p = DOM.add(DOM.get(ed.id + '_parent'), 'div', {'class' : 'mcePlaceHolder'}); - DOM.setStyles(p, {width : w, height : h}); - - // Replace with placeholder - DOM.hide(c); - DOM.show(p); - - // Create internal resize obj - r = { - x : e.screenX, - y : e.screenY, - w : w, - h : h, - dx : null, - dy : null - }; - - // Start listening - mf = Event.add(DOM.doc, 'mousemove', function(e) { - var w, h; - - // Calc delta values - r.dx = e.screenX - r.x; - r.dy = e.screenY - r.y; + var mouseMoveHandler1, mouseMoveHandler2, mouseUpHandler, + startX, startY, startWidth, startHeight, width, height, ifrElm; - // Boundery fix box - w = Math.max(miw, r.w + r.dx); - h = Math.max(mih, r.h + r.dy); - w = Math.min(maw, w); - h = Math.min(mah, h); + function resizeOnMove(e) { + width = startWidth + (e.screenX - startX); + height = startHeight + (e.screenY - startY); - // Resize placeholder - if (s.theme_advanced_resize_horizontal) - p.style.width = w + 'px'; - - p.style.height = h + 'px'; + t.resizeTo(width, height); + }; - return Event.cancel(e); - }); + e.preventDefault(); - me = Event.add(DOM.doc, 'mouseup', function(e) { - var ifr; + // Get the current rect size + startX = e.screenX; + startY = e.screenY; + ifrElm = DOM.get(t.editor.id + '_ifr'); + startWidth = width = ifrElm.clientWidth; + startHeight = height = ifrElm.clientHeight; + // Register envent handlers + mouseMoveHandler1 = Event.add(DOM.doc, 'mousemove', resizeOnMove); + mouseMoveHandler2 = Event.add(ed.getDoc(), 'mousemove', resizeOnMove); + mouseUpHandler = Event.add(DOM.doc, 'mouseup', function(e) { // Stop listening - Event.remove(DOM.doc, 'mousemove', mf); - Event.remove(DOM.doc, 'mouseup', me); - - c.style.display = ''; - DOM.remove(p); - - if (r.dx === null) - return; - - ifr = DOM.get(ed.id + '_ifr'); - - if (s.theme_advanced_resize_horizontal) - c.style.width = Math.max(10, r.w + r.dx) + 'px'; - - c.style.height = Math.max(10, r.h + r.dy) + 'px'; - ifr.style.height = Math.max(10, ifr.clientHeight + r.dy) + 'px'; + Event.remove(DOM.doc, 'mousemove', mouseMoveHandler1); + Event.remove(ed.getDoc(), 'mousemove', mouseMoveHandler2); + Event.remove(DOM.doc, 'mouseup', mouseUpHandler); + // Store away the size if (s.theme_advanced_resizing_use_cookie) { Cookie.setHash("TinyMCE_" + ed.id + "_size", { - cw : r.w + r.dx, - ch : r.h + r.dy + cw : width, + ch : height }); } }); - - return Event.cancel(e); }); }); } @@ -801,22 +796,34 @@ n = tb = null; }, - _nodeChanged : function(ed, cm, n, co) { + _nodeChanged : function(ed, cm, n, co, ob) { var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn; - if (s.readonly) - return; - tinymce.each(t.stateControls, function(c) { cm.setActive(c, ed.queryCommandState(t.controls[c][1])); }); + function getParent(name) { + var i, parents = ob.parents, func = name; + + if (typeof(name) == 'string') { + func = function(node) { + return node.nodeName == name; + }; + } + + for (i = 0; i < parents.length; i++) { + if (func(parents[i])) + return parents[i]; + } + }; + cm.setActive('visualaid', ed.hasVisual); cm.setDisabled('undo', !ed.undoManager.hasUndo() && !ed.typing); cm.setDisabled('redo', !ed.undoManager.hasRedo()); cm.setDisabled('outdent', !ed.queryCommandState('Outdent')); - p = DOM.getParent(n, 'A'); + p = getParent('A'); if (c = cm.get('link')) { if (!p || !p.name) { c.setDisabled(!p && co); @@ -831,82 +838,75 @@ if (c = cm.get('anchor')) { c.setActive(!!p && p.name); - - if (tinymce.isWebKit) { - p = DOM.getParent(n, 'IMG'); - c.setActive(!!p && DOM.getAttrib(p, 'mce_name') == 'a'); - } } - p = DOM.getParent(n, 'IMG'); + p = getParent('IMG'); if (c = cm.get('image')) c.setActive(!!p && n.className.indexOf('mceItem') == -1); if (c = cm.get('styleselect')) { - if (n.className) { - t._importClasses(); - c.select(n.className); - } else - c.select(); + t._importClasses(); + + // Check each format and update + c.select(function(fmt) { + return !!ed.formatter.match(fmt); + }); } if (c = cm.get('formatselect')) { - p = DOM.getParent(n, DOM.isBlock); + p = getParent(DOM.isBlock); if (p) c.select(p.nodeName.toLowerCase()); } - if (ed.settings.convert_fonts_to_spans) { - ed.dom.getParent(n, function(n) { - if (n.nodeName === 'SPAN') { - if (!cl && n.className) - cl = n.className; + // Find out current fontSize, fontFamily and fontClass + getParent(function(n) { + if (n.nodeName === 'SPAN') { + if (!cl && n.className) + cl = n.className; - if (!fz && n.style.fontSize) - fz = n.style.fontSize; + if (!fz && n.style.fontSize) + fz = n.style.fontSize; - if (!fn && n.style.fontFamily) - fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase(); - } + if (!fn && n.style.fontFamily) + fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase(); + } - return false; + return false; + }); + + if (c = cm.get('fontselect')) { + c.select(function(v) { + return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn; }); + } - if (c = cm.get('fontselect')) { - c.select(function(v) { - return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn; - }); - } + // Select font size + if (c = cm.get('fontsizeselect')) { + // Use computed style + if (s.theme_advanced_runtime_fontsize && !fz && !cl) + fz = ed.dom.getStyle(n, 'fontSize', true); - if (c = cm.get('fontsizeselect')) { - c.select(function(v) { - if (v.fontSize && v.fontSize === fz) - return true; + c.select(function(v) { + if (v.fontSize && v.fontSize === fz) + return true; - if (v['class'] && v['class'] === cl) - return true; - }); - } - } else { - if (c = cm.get('fontselect')) - c.select(ed.queryCommandValue('FontName')); - - if (c = cm.get('fontsizeselect')) { - v = ed.queryCommandValue('FontSize'); - c.select(function(iv) { - return iv.fontSize == v; - }); - } + if (v['class'] && v['class'] === cl) + return true; + }); } if (s.theme_advanced_path && s.theme_advanced_statusbar_location) { p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'}); DOM.setHTML(p, ''); - ed.dom.getParent(n, function(n) { + getParent(function(n) { var na = n.nodeName.toLowerCase(), u, pi, ti = ''; + /*if (n.getAttribute('_mce_bogus')) + return; +*/ // Ignore non element and hidden elements if (n.nodeType != 1 || n.nodeName === 'BR' || (DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved'))) return; @@ -950,9 +950,6 @@ break; case 'font': - if (s.convert_fonts_to_spans) - na = 'span'; - if (v = DOM.getAttrib(n, 'face')) ti += 'font: ' + v + ' '; @@ -975,9 +972,9 @@ ti += 'id: ' + v + ' '; if (v = n.className) { - v = v.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g, ''); + v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, '') - if (v && v.indexOf('mceItem') == -1) { + if (v) { ti += 'class: ' + v + ' '; if (DOM.isBlock(n) || na == 'img' || na == 'span') diff --git a/program/js/tiny_mce/themes/advanced/image.htm b/program/js/tiny_mce/themes/advanced/image.htm index 7ec1052ba..f30d67064 100644 --- a/program/js/tiny_mce/themes/advanced/image.htm +++ b/program/js/tiny_mce/themes/advanced/image.htm @@ -72,13 +72,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/themes/advanced/img/icons.gif b/program/js/tiny_mce/themes/advanced/img/icons.gif index ccac36f54..e46de5333 100644 Binary files a/program/js/tiny_mce/themes/advanced/img/icons.gif and b/program/js/tiny_mce/themes/advanced/img/icons.gif differ diff --git a/program/js/tiny_mce/themes/advanced/js/anchor.js b/program/js/tiny_mce/themes/advanced/js/anchor.js index b5efd1ec9..7fe781055 100644 --- a/program/js/tiny_mce/themes/advanced/js/anchor.js +++ b/program/js/tiny_mce/themes/advanced/js/anchor.js @@ -5,7 +5,7 @@ var AnchorDialog = { var action, elm, f = document.forms[0]; this.editor = ed; - elm = ed.dom.getParent(ed.selection.getNode(), 'A,IMG'); + elm = ed.dom.getParent(ed.selection.getNode(), 'A'); v = ed.dom.getAttrib(elm, 'name'); if (v) { @@ -17,18 +17,18 @@ var AnchorDialog = { }, update : function() { - var ed = this.editor; - + var ed = this.editor, elm, name = document.forms[0].anchorName.value; + tinyMCEPopup.restoreSelection(); if (this.action != 'update') ed.selection.collapse(1); - // Webkit acts weird if empty inline element is inserted so we need to use a image instead - if (tinymce.isWebKit) - ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('img', {mce_name : 'a', name : document.forms[0].anchorName.value, 'class' : 'mceItemAnchor'})); + elm = ed.dom.getParent(ed.selection.getNode(), 'A'); + if (elm) + elm.name = name; else - ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', {name : document.forms[0].anchorName.value, 'class' : 'mceItemAnchor'}, '')); + ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', {name : name, 'class' : 'mceItemAnchor'}, '')); tinyMCEPopup.close(); } diff --git a/program/js/tiny_mce/themes/advanced/js/charmap.js b/program/js/tiny_mce/themes/advanced/js/charmap.js index 8467ef603..8c5aea172 100644 --- a/program/js/tiny_mce/themes/advanced/js/charmap.js +++ b/program/js/tiny_mce/themes/advanced/js/charmap.js @@ -1,3 +1,13 @@ +/** + * charmap.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + tinyMCEPopup.requireLangPack(); var charmap = [ diff --git a/program/js/tiny_mce/themes/advanced/js/image.js b/program/js/tiny_mce/themes/advanced/js/image.js index 4982ce0c8..6423d9080 100644 --- a/program/js/tiny_mce/themes/advanced/js/image.js +++ b/program/js/tiny_mce/themes/advanced/js/image.js @@ -151,8 +151,8 @@ var ImageDialog = { } // Merge - st = tinyMCEPopup.dom.parseStyle(dom.serializeStyle(st)); - this.styleVal = dom.serializeStyle(st); + st = tinyMCEPopup.dom.parseStyle(dom.serializeStyle(st), 'img'); + this.styleVal = dom.serializeStyle(st, 'img'); } }, diff --git a/program/js/tiny_mce/themes/advanced/link.htm b/program/js/tiny_mce/themes/advanced/link.htm index a78bd334d..7565b9ae8 100644 --- a/program/js/tiny_mce/themes/advanced/link.htm +++ b/program/js/tiny_mce/themes/advanced/link.htm @@ -50,13 +50,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/themes/advanced/skins/default/content.css b/program/js/tiny_mce/themes/advanced/skins/default/content.css index 19da1943b..36f38aba2 100644 --- a/program/js/tiny_mce/themes/advanced/skins/default/content.css +++ b/program/js/tiny_mce/themes/advanced/skins/default/content.css @@ -8,8 +8,8 @@ h4 {font-size: 1em} h5 {font-size: .83em} h6 {font-size: .75em} .mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} -a.mceItemAnchor {width:12px; line-height:6px; overflow:hidden; padding-left:12px; background:url(img/items.gif) no-repeat bottom left;} -img.mceItemAnchor {width:12px; height:12px; background:url(img/items.gif) no-repeat;} +a.mceItemAnchor {display:inline-block; width:11px !important; height:11px !important; background:url(img/items.gif) no-repeat 0 0;} +td.mceSelected, th.mceSelected {background-color:#3399ff !important} img {border:0;} table {cursor:default} table td, table th {cursor:text} @@ -17,7 +17,7 @@ ins {border-bottom:1px solid green; text-decoration: none; color:green} del {color:red; text-decoration:line-through} cite {border-bottom:1px dashed blue} acronym {border-bottom:1px dotted #CCC; cursor:help} -abbr, html\:abbr {border-bottom:1px dashed #CCC; cursor:help} +abbr {border-bottom:1px dashed #CCC; cursor:help} /* IE */ * html body { @@ -30,3 +30,6 @@ scrollbar-highlight-color:#F0F0EE; scrollbar-shadow-color:#F0F0EE; scrollbar-track-color:#F5F5F5; } + +img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} +font[face=mceinline] {font-family:inherit !important} diff --git a/program/js/tiny_mce/themes/advanced/skins/default/dialog.css b/program/js/tiny_mce/themes/advanced/skins/default/dialog.css index 873c67e3c..f01222650 100644 --- a/program/js/tiny_mce/themes/advanced/skins/default/dialog.css +++ b/program/js/tiny_mce/themes/advanced/skins/default/dialog.css @@ -42,10 +42,11 @@ width:94px; height:26px; background:url(img/buttons.png) 0 -26px; cursor:pointer; padding-bottom:2px; +float:left; } -#insert {background:url(img/buttons.png) 0 -52px;} -#cancel {background:url(img/buttons.png) 0 0;} +#insert {background:url(img/buttons.png) 0 -52px} +#cancel {background:url(img/buttons.png) 0 0; float:right} /* Browse */ a.pickcolor, a.browse {text-decoration:none} @@ -113,4 +114,4 @@ h3 {font-size:14px;} #colorpicker #namedcolors {width:150px;} #colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} #colorpicker #colornamecontainer {margin-top:5px;} -#colorpicker #picker_panel fieldset {margin:auto;width:325px;} \ No newline at end of file +#colorpicker #picker_panel fieldset {margin:auto;width:325px;} diff --git a/program/js/tiny_mce/themes/advanced/skins/default/ui.css b/program/js/tiny_mce/themes/advanced/skins/default/ui.css index 230a2ee28..01095aeea 100644 --- a/program/js/tiny_mce/themes/advanced/skins/default/ui.css +++ b/program/js/tiny_mce/themes/advanced/skins/default/ui.css @@ -4,7 +4,7 @@ .defaultSkin table td {vertical-align:middle} /* Containers */ -.defaultSkin table {background:#F0F0EE} +.defaultSkin table {direction:ltr; background:#F0F0EE} .defaultSkin iframe {display:block; background:#FFF} .defaultSkin .mceToolbar {height:26px} .defaultSkin .mceLeft {text-align:left} @@ -24,7 +24,7 @@ .defaultSkin .mceIframeContainer {border-top:1px solid #CCC; border-bottom:1px solid #CCC} .defaultSkin .mceStatusbar {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; display:block; height:20px} .defaultSkin .mceStatusbar div {float:left; margin:2px} -.defaultSkin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize} +.defaultSkin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0} .defaultSkin .mceStatusbar a:hover {text-decoration:underline} .defaultSkin table.mceToolbar {margin-left:3px} .defaultSkin span.mceIcon, .defaultSkin img.mceIcon {display:block; width:20px; height:20px} @@ -47,7 +47,6 @@ .defaultSkin .mceSeparator {display:block; background:url(../../img/icons.gif) -180px 0; width:2px; height:20px; margin:2px 2px 0 4px} /* ListBox */ -.defaultSkin .mceListBox {direction:ltr} .defaultSkin .mceListBox, .defaultSkin .mceListBox a {display:block} .defaultSkin .mceListBox .mceText {padding-left:4px; width:70px; text-align:left; border:1px solid #CCC; border-right:0; background:#FFF; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} .defaultSkin .mceListBox .mceOpen {width:9px; height:20px; background:url(../../img/icons.gif) -741px 0; margin-right:2px; border:1px solid #CCC;} @@ -63,7 +62,7 @@ .defaultSkin .mceSplitButton {width:32px; height:20px; direction:ltr} .defaultSkin .mceSplitButton a, .defaultSkin .mceSplitButton span {height:20px; display:block} .defaultSkin .mceSplitButton a.mceAction {width:20px; border:1px solid #F0F0EE; border-right:0;} -.defaultSkin .mceSplitButton span.mceAction {width:20px; background:url(../../img/icons.gif) 20px 20px;} +.defaultSkin .mceSplitButton span.mceAction {width:20px; background-image:url(../../img/icons.gif);} .defaultSkin .mceSplitButton a.mceOpen {width:9px; background:url(../../img/icons.gif) -741px 0; border:1px solid #F0F0EE;} .defaultSkin .mceSplitButton span.mceOpen {display:none} .defaultSkin table.mceSplitButtonEnabled:hover a.mceAction, .defaultSkin .mceSplitButtonHover a.mceAction, .defaultSkin .mceSplitButtonSelected a.mceAction {border:1px solid #0A246A; border-right:0; background-color:#B2BBD0} @@ -108,7 +107,6 @@ /* Progress,Resize */ .defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50); background:#FFF} .defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} -.defaultSkin .mcePlaceHolder {border:1px dotted gray} /* Formats */ .defaultSkin .mce_formatPreview a {font-size:10px} @@ -211,4 +209,5 @@ .defaultSkin span.mce_del {background-position:-940px -20px} .defaultSkin span.mce_ins {background-position:-960px -20px} .defaultSkin span.mce_pagebreak {background-position:0 -40px} +.defaultSkin span.mce_restoredraft {background-position:-20px -40px} .defaultSkin .mce_spellchecker span.mceAction {background-position:-540px -20px} diff --git a/program/js/tiny_mce/themes/advanced/skins/o2k7/content.css b/program/js/tiny_mce/themes/advanced/skins/o2k7/content.css index b8431d169..3cea5ff1c 100644 --- a/program/js/tiny_mce/themes/advanced/skins/o2k7/content.css +++ b/program/js/tiny_mce/themes/advanced/skins/o2k7/content.css @@ -8,8 +8,8 @@ h4 {font-size: 1em} h5 {font-size: .83em} h6 {font-size: .75em} .mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} -a.mceItemAnchor {width:12px; line-height:6px; overflow:hidden; padding-left:12px; background:url(../default/img/items.gif) no-repeat bottom left;} -img.mceItemAnchor {width:12px; height:12px; background:url(../default/img/items.gif) no-repeat;} +a.mceItemAnchor {display:inline-block; width:11px !important; height:11px !important; background:url(../default/img/items.gif) no-repeat 0 0;} +td.mceSelected, th.mceSelected {background-color:#3399ff !important} img {border:0;} table {cursor:default} table td, table th {cursor:text} @@ -17,7 +17,7 @@ ins {border-bottom:1px solid green; text-decoration: none; color:green} del {color:red; text-decoration:line-through} cite {border-bottom:1px dashed blue} acronym {border-bottom:1px dotted #CCC; cursor:help} -abbr, html\:abbr {border-bottom:1px dashed #CCC; cursor:help} +abbr {border-bottom:1px dashed #CCC; cursor:help} /* IE */ * html body { @@ -30,3 +30,6 @@ scrollbar-highlight-color:#F0F0EE; scrollbar-shadow-color:#F0F0EE; scrollbar-track-color:#F5F5F5; } + +img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} +font[face=mceinline] {font-family:inherit !important} diff --git a/program/js/tiny_mce/themes/advanced/skins/o2k7/dialog.css b/program/js/tiny_mce/themes/advanced/skins/o2k7/dialog.css index 6c37d6fb8..e3af1396e 100644 --- a/program/js/tiny_mce/themes/advanced/skins/o2k7/dialog.css +++ b/program/js/tiny_mce/themes/advanced/skins/o2k7/dialog.css @@ -42,10 +42,11 @@ width:94px; height:26px; background:url(../default/img/buttons.png) 0 -26px; cursor:pointer; padding-bottom:2px; +float:left; } -#insert {background:url(../default/img/buttons.png) 0 -52px;} -#cancel {background:url(../default/img/buttons.png) 0 0;} +#insert {background:url(../default/img/buttons.png) 0 -52px} +#cancel {background:url(../default/img/buttons.png) 0 0; float:right} /* Browse */ a.pickcolor, a.browse {text-decoration:none} diff --git a/program/js/tiny_mce/themes/advanced/skins/o2k7/ui.css b/program/js/tiny_mce/themes/advanced/skins/o2k7/ui.css index c10a3f016..aae0e2bf4 100644 --- a/program/js/tiny_mce/themes/advanced/skins/o2k7/ui.css +++ b/program/js/tiny_mce/themes/advanced/skins/o2k7/ui.css @@ -21,7 +21,7 @@ .o2k7Skin .mceIframeContainer {border-top:1px solid #ABC6DD; border-bottom:1px solid #ABC6DD} .o2k7Skin .mceStatusbar {display:block; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; height:20px} .o2k7Skin .mceStatusbar div {float:left; padding:2px} -.o2k7Skin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize} +.o2k7Skin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0} .o2k7Skin .mceStatusbar a:hover {text-decoration:underline} .o2k7Skin table.mceToolbar {margin-left:3px} .o2k7Skin .mceToolbar .mceToolbarStart span {display:block; background:url(img/button_bg.png) -22px 0; width:1px; height:22px; margin-left:3px;} @@ -65,7 +65,7 @@ .o2k7Skin .mceSplitButton, .o2k7Skin .mceSplitButton a, .o2k7Skin .mceSplitButton span {display:block; height:22px} .o2k7Skin .mceSplitButton {background:url(img/button_bg.png)} .o2k7Skin .mceSplitButton a.mceAction {width:22px} -.o2k7Skin .mceSplitButton span.mceAction {width:22px; background:url(../../img/icons.gif) 20px 20px} +.o2k7Skin .mceSplitButton span.mceAction {width:22px; background-image:url(../../img/icons.gif)} .o2k7Skin .mceSplitButton a.mceOpen {width:10px; background:url(img/button_bg.png) -44px 0} .o2k7Skin .mceSplitButton span.mceOpen {display:none} .o2k7Skin table.mceSplitButtonEnabled:hover a.mceAction, .o2k7Skin .mceSplitButtonHover a.mceAction, .o2k7Skin .mceSplitButtonSelected {background:url(img/button_bg.png) 0 -22px} @@ -109,7 +109,6 @@ /* Progress,Resize */ .o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF} .o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} -.o2k7Skin .mcePlaceHolder {border:1px dotted gray} /* Formats */ .o2k7Skin .mce_formatPreview a {font-size:10px} @@ -212,4 +211,5 @@ .o2k7Skin span.mce_del {background-position:-940px -20px} .o2k7Skin span.mce_ins {background-position:-960px -20px} .o2k7Skin span.mce_pagebreak {background-position:0 -40px} +.o2k7Skin span.mce_restoredraft {background-position:-20px -40px} .o2k7Skin .mce_spellchecker span.mceAction {background-position:-540px -20px} diff --git a/program/js/tiny_mce/themes/advanced/source_editor.htm b/program/js/tiny_mce/themes/advanced/source_editor.htm index 553e7bb2b..1c81d23ee 100644 --- a/program/js/tiny_mce/themes/advanced/source_editor.htm +++ b/program/js/tiny_mce/themes/advanced/source_editor.htm @@ -18,13 +18,8 @@
-
- -
- -
- -
+ +
diff --git a/program/js/tiny_mce/themes/simple/editor_template_src.js b/program/js/tiny_mce/themes/simple/editor_template_src.js index fb0bd7893..4b862d49d 100644 --- a/program/js/tiny_mce/themes/simple/editor_template_src.js +++ b/program/js/tiny_mce/themes/simple/editor_template_src.js @@ -1,11 +1,11 @@ /** - * $Id: editor_template_src.js 920 2008-09-09 14:05:33Z spocke $ + * editor_template_src.js * - * This file is meant to showcase how to create a simple theme. The advanced - * theme is more suitable for production use. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ (function() { diff --git a/program/js/tiny_mce/tiny_mce.js b/program/js/tiny_mce/tiny_mce.js index babc91e6a..e96c95151 100644 --- a/program/js/tiny_mce/tiny_mce.js +++ b/program/js/tiny_mce/tiny_mce.js @@ -1 +1 @@ -var tinymce={majorVersion:"3",minorVersion:"2.7",releaseDate:"2009-09-22",_init:function(){var o=this,k=document,l=window,j=navigator,b=j.userAgent,h,a,g,f,e,m;o.isOpera=l.opera&&opera.buildNumber;o.isWebKit=/WebKit/.test(b);o.isIE=!o.isWebKit&&!o.isOpera&&(/MSIE/gi).test(b)&&(/Explorer/gi).test(j.appName);o.isIE6=o.isIE&&/MSIE [56]/.test(b);o.isGecko=!o.isWebKit&&/Gecko/.test(b);o.isMac=b.indexOf("Mac")!=-1;o.isAir=/adobeair/i.test(b);if(l.tinyMCEPreInit){o.suffix=tinyMCEPreInit.suffix;o.baseURL=tinyMCEPreInit.base;o.query=tinyMCEPreInit.query;return}o.suffix="";a=k.getElementsByTagName("base");for(h=0;h=c.length){for(e=0,b=g.length;e=c.length||g[e]!=c[e]){f=e+1;break}}}if(g.length=g.length||g[e]!=c[e]){f=e+1;break}}}if(f==1){return h}for(e=0,b=g.length-(f-1);e=0;c--){if(f[c].length==0||f[c]=="."){continue}if(f[c]==".."){b++;continue}if(b>0){b--;continue}h.push(f[c])}c=e.length-b;if(c<=0){g=h.reverse().join("/")}else{g=e.slice(0,c).join("/")+"/"+h.reverse().join("/")}if(g.indexOf("/")!==0){g="/"+g}if(d&&g.lastIndexOf("/")!==g.length-1){g+=d}return g},getURI:function(d){var c,b=this;if(!b.source||d){c="";if(!d){if(b.protocol){c+=b.protocol+"://"}if(b.userInfo){c+=b.userInfo+"@"}if(b.host){c+=b.host}if(b.port){c+=":"+b.port}}if(b.path){c+=b.path}if(b.query){c+="?"+b.query}if(b.anchor){c+="#"+b.anchor}b.source=c}return b.source}})})();(function(){var a=tinymce.each;tinymce.create("static tinymce.util.Cookie",{getHash:function(d){var b=this.get(d),c;if(b){a(b.split("&"),function(e){e=e.split("=");c=c||{};c[unescape(e[0])]=unescape(e[1])})}return c},setHash:function(j,b,g,f,i,c){var h="";a(b,function(e,d){h+=(!h?"":"&")+escape(d)+"="+escape(e)});this.set(j,h,g,f,i,c)},get:function(i){var h=document.cookie,g,f=i+"=",d;if(!h){return}d=h.indexOf("; "+f);if(d==-1){d=h.indexOf(f);if(d!=0){return null}}else{d+=2}g=h.indexOf(";",d);if(g==-1){g=h.length}return unescape(h.substring(d+f.length,g))},set:function(i,b,g,f,h,c){document.cookie=i+"="+escape(b)+((g)?"; expires="+g.toGMTString():"")+((f)?"; path="+escape(f):"")+((h)?"; domain="+h:"")+((c)?"; secure":"")},remove:function(e,b){var c=new Date();c.setTime(c.getTime()-1000);this.set(e,"",c,b,c)}})})();tinymce.create("static tinymce.util.JSON",{serialize:function(e){var c,a,d=tinymce.util.JSON.serialize,b;if(e==null){return"null"}b=typeof e;if(b=="string"){a="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+e.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(g,f){c=a.indexOf(f);if(c+1){return"\\"+a.charAt(c+1)}g=f.charCodeAt().toString(16);return"\\u"+"0000".substring(g.length)+g})+'"'}if(b=="object"){if(e.hasOwnProperty&&e instanceof Array){for(c=0,a="[";c0?",":"")+d(e[c])}return a+"]"}a="{";for(c in e){a+=typeof e[c]!="function"?(a.length>1?',"':'"')+c+'":'+d(e[c]):""}return a+"}"}return""+e},parse:function(s){try{return eval("("+s+")")}catch(ex){}}});tinymce.create("static tinymce.util.XHR",{send:function(g){var a,e,b=window,h=0;g.scope=g.scope||this;g.success_scope=g.success_scope||g.scope;g.error_scope=g.error_scope||g.scope;g.async=g.async===false?false:true;g.data=g.data||"";function d(i){a=0;try{a=new ActiveXObject(i)}catch(c){}return a}a=b.XMLHttpRequest?new XMLHttpRequest():d("Microsoft.XMLHTTP")||d("Msxml2.XMLHTTP");if(a){if(a.overrideMimeType){a.overrideMimeType(g.content_type)}a.open(g.type||(g.data?"POST":"GET"),g.url,g.async);if(g.content_type){a.setRequestHeader("Content-Type",g.content_type)}a.setRequestHeader("X-Requested-With","XMLHttpRequest");a.send(g.data);function f(){if(!g.async||a.readyState==4||h++>10000){if(g.success&&h<10000&&a.status==200){g.success.call(g.success_scope,""+a.responseText,a,g)}else{if(g.error){g.error.call(g.error_scope,h>10000?"TIMED_OUT":"GENERAL",a,g)}}a=null}else{b.setTimeout(f,10)}}if(!g.async){return f()}e=b.setTimeout(f,10)}}});(function(){var c=tinymce.extend,b=tinymce.util.JSON,a=tinymce.util.XHR;tinymce.create("tinymce.util.JSONRequest",{JSONRequest:function(d){this.settings=c({},d);this.count=0},send:function(f){var e=f.error,d=f.success;f=c(this.settings,f);f.success=function(h,g){h=b.parse(h);if(typeof(h)=="undefined"){h={error:"JSON Parse error."}}if(h.error){e.call(f.error_scope||f.scope,h.error,g)}else{d.call(f.success_scope||f.scope,h.result)}};f.error=function(h,g){e.call(f.error_scope||f.scope,h,g)};f.data=b.serialize({id:f.id||"c"+(this.count++),method:f.method,params:f.params});f.content_type="application/json";a.send(f)},"static":{sendRPC:function(d){return new tinymce.util.JSONRequest().send(d)}}})}());(function(c){var e=c.each,b=c.is;var d=c.isWebKit,a=c.isIE;c.create("tinymce.dom.DOMUtils",{doc:null,root:null,files:null,pixelStyles:/^(top|left|bottom|right|width|height|borderWidth)$/,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},DOMUtils:function(i,g){var f=this;f.doc=i;f.win=window;f.files={};f.cssFlicker=false;f.counter=0;f.boxModel=!c.isIE||i.compatMode=="CSS1Compat";f.stdMode=i.documentMode===8;f.settings=g=c.extend({keep_values:false,hex_colors:1,process_html:1},g);if(c.isIE6){try{i.execCommand("BackgroundImageCache",false,true)}catch(h){f.cssFlicker=true}}c.addUnload(f.destroy,f)},getRoot:function(){var f=this,g=f.settings;return(g&&f.get(g.root_element))||f.doc.body},getViewPort:function(g){var h,f;g=!g?this.win:g;h=g.document;f=this.boxModel?h.documentElement:h.body;return{x:g.pageXOffset||f.scrollLeft,y:g.pageYOffset||f.scrollTop,w:g.innerWidth||f.clientWidth,h:g.innerHeight||f.clientHeight}},getRect:function(i){var h,f=this,g;i=f.get(i);h=f.getPos(i);g=f.getSize(i);return{x:h.x,y:h.y,w:g.w,h:g.h}},getSize:function(j){var g=this,f,i;j=g.get(j);f=g.getStyle(j,"width");i=g.getStyle(j,"height");if(f.indexOf("px")===-1){f=0}if(i.indexOf("px")===-1){i=0}return{w:parseInt(f)||j.offsetWidth||j.clientWidth,h:parseInt(i)||j.offsetHeight||j.clientHeight}},getParent:function(i,h,g){return this.getParents(i,h,g,false)},getParents:function(p,k,i,m){var h=this,g,j=h.settings,l=[];p=h.get(p);m=m===undefined;if(j.strict_root){i=i||h.getRoot()}if(b(k,"string")){g=k;if(k==="*"){k=function(f){return f.nodeType==1}}else{k=function(f){return h.is(f,g)}}}while(p){if(p==i||!p.nodeType||p.nodeType===9){break}if(!k||k(p)){if(m){l.push(p)}else{return p}}p=p.parentNode}return m?l:null},get:function(f){var g;if(f&&this.doc&&typeof(f)=="string"){g=f;f=this.doc.getElementById(f);if(f&&f.id!==g){return this.doc.getElementsByName(g)[1]}}return f},getNext:function(g,f){return this._findSib(g,f,"nextSibling")},getPrev:function(g,f){return this._findSib(g,f,"previousSibling")},select:function(h,g){var f=this;return c.dom.Sizzle(h,f.get(g)||f.get(f.settings.root_element)||f.doc,[])},is:function(g,f){return c.dom.Sizzle.matches(f,g.nodeType?[g]:g).length>0},add:function(j,l,f,i,k){var g=this;return this.run(j,function(n){var m,h;m=b(l,"string")?g.doc.createElement(l):l;g.setAttribs(m,f);if(i){if(i.nodeType){m.appendChild(i)}else{g.setHTML(m,i)}}return !k?n.appendChild(m):m})},create:function(i,f,g){return this.add(this.doc.createElement(i),i,f,g,1)},createHTML:function(m,f,j){var l="",i=this,g;l+="<"+m;for(g in f){if(f.hasOwnProperty(g)){l+=" "+g+'="'+i.encode(f[g])+'"'}}if(c.is(j)){return l+">"+j+""}return l+" />"},remove:function(h,f){var g=this;return this.run(h,function(m){var l,k,j;l=m.parentNode;if(!l){return null}if(f){for(j=m.childNodes.length-1;j>=0;j--){g.insertAfter(m.childNodes[j],m)}}if(g.fixPsuedoLeaks){l=m.cloneNode(true);f="IELeakGarbageBin";k=g.get(f)||g.add(g.doc.body,"div",{id:f,style:"display:none"});k.appendChild(m);k.innerHTML="";return l}return l.removeChild(m)})},setStyle:function(i,f,g){var h=this;return h.run(i,function(l){var k,j;k=l.style;f=f.replace(/-(\D)/g,function(n,m){return m.toUpperCase()});if(h.pixelStyles.test(f)&&(c.is(g,"number")||/^[\-0-9\.]+$/.test(g))){g+="px"}switch(f){case"opacity":if(a){k.filter=g===""?"":"alpha(opacity="+(g*100)+")";if(!i.currentStyle||!i.currentStyle.hasLayout){k.display="inline-block"}}k[f]=k["-moz-opacity"]=k["-khtml-opacity"]=g||"";break;case"float":a?k.styleFloat=g:k.cssFloat=g;break;default:k[f]=g||""}if(h.settings.update_styles){h.setAttrib(l,"mce_style")}})},getStyle:function(i,f,h){i=this.get(i);if(!i){return false}if(this.doc.defaultView&&h){f=f.replace(/[A-Z]/g,function(j){return"-"+j});try{return this.doc.defaultView.getComputedStyle(i,null).getPropertyValue(f)}catch(g){return null}}f=f.replace(/-(\D)/g,function(k,j){return j.toUpperCase()});if(f=="float"){f=a?"styleFloat":"cssFloat"}if(i.currentStyle&&h){return i.currentStyle[f]}return i.style[f]},setStyles:function(i,j){var g=this,h=g.settings,f;f=h.update_styles;h.update_styles=0;e(j,function(k,l){g.setStyle(i,l,k)});h.update_styles=f;if(h.update_styles){g.setAttrib(i,h.cssText)}},setAttrib:function(h,i,f){var g=this;if(!h||!i){return}if(g.settings.strict){i=i.toLowerCase()}return this.run(h,function(k){var j=g.settings;switch(i){case"style":if(!b(f,"string")){e(f,function(l,m){g.setStyle(k,m,l)});return}if(j.keep_values){if(f&&!g._isRes(f)){k.setAttribute("mce_style",f,2)}else{k.removeAttribute("mce_style",2)}}k.style.cssText=f;break;case"class":k.className=f||"";break;case"src":case"href":if(j.keep_values){if(j.url_converter){f=j.url_converter.call(j.url_converter_scope||g,f,i,k)}g.setAttrib(k,"mce_"+i,f,2)}break;case"shape":k.setAttribute("mce_style",f);break}if(b(f)&&f!==null&&f.length!==0){k.setAttribute(i,""+f,2)}else{k.removeAttribute(i,2)}})},setAttribs:function(g,h){var f=this;return this.run(g,function(i){e(h,function(j,k){f.setAttrib(i,k,j)})})},getAttrib:function(i,j,h){var f,g=this;i=g.get(i);if(!i||i.nodeType!==1){return false}if(!b(h)){h=""}if(/^(src|href|style|coords|shape)$/.test(j)){f=i.getAttribute("mce_"+j);if(f){return f}}if(a&&g.props[j]){f=i[g.props[j]];f=f&&f.nodeValue?f.nodeValue:f}if(!f){f=i.getAttribute(j,2)}if(/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(j)){if(i[g.props[j]]===true&&f===""){return j}return f?j:""}if(i.nodeName==="FORM"&&i.getAttributeNode(j)){return i.getAttributeNode(j).nodeValue}if(j==="style"){f=f||i.style.cssText;if(f){f=g.serializeStyle(g.parseStyle(f));if(g.settings.keep_values&&!g._isRes(f)){i.setAttribute("mce_style",f)}}}if(d&&j==="class"&&f){f=f.replace(/(apple|webkit)\-[a-z\-]+/gi,"")}if(a){switch(j){case"rowspan":case"colspan":if(f===1){f=""}break;case"size":if(f==="+0"||f===20||f===0){f=""}break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":if(f===0){f=""}break;case"hspace":if(f===-1){f=""}break;case"maxlength":case"tabindex":if(f===32768||f===2147483647||f==="32768"){f=""}break;case"multiple":case"compact":case"noshade":case"nowrap":if(f===65535){return j}return h;case"shape":f=f.toLowerCase();break;default:if(j.indexOf("on")===0&&f){f=(""+f).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1")}}}return(f!==undefined&&f!==null&&f!=="")?""+f:h},getPos:function(m,i){var g=this,f=0,l=0,j,k=g.doc,h;m=g.get(m);i=i||k.body;if(m){if(a&&!g.stdMode){m=m.getBoundingClientRect();j=g.boxModel?k.documentElement:k.body;f=g.getStyle(g.select("html")[0],"borderWidth");f=(f=="medium"||g.boxModel&&!g.isIE6)&&2||f;m.top+=g.win.self!=g.win.top?2:0;return{x:m.left+j.scrollLeft-f,y:m.top+j.scrollTop-f}}h=m;while(h&&h!=i&&h.nodeType){f+=h.offsetLeft||0;l+=h.offsetTop||0;h=h.offsetParent}h=m.parentNode;while(h&&h!=i&&h.nodeType){f-=h.scrollLeft||0;l-=h.scrollTop||0;h=h.parentNode}}return{x:f,y:l}},parseStyle:function(h){var i=this,j=i.settings,k={};if(!h){return k}function f(w,q,v){var o,u,m,n;o=k[w+"-top"+q];if(!o){return}u=k[w+"-right"+q];if(o!=u){return}m=k[w+"-bottom"+q];if(u!=m){return}n=k[w+"-left"+q];if(m!=n){return}k[v]=n;delete k[w+"-top"+q];delete k[w+"-right"+q];delete k[w+"-bottom"+q];delete k[w+"-left"+q]}function g(n,m,l,p){var o;o=k[m];if(!o){return}o=k[l];if(!o){return}o=k[p];if(!o){return}k[n]=k[m]+" "+k[l]+" "+k[p];delete k[m];delete k[l];delete k[p]}h=h.replace(/&(#?[a-z0-9]+);/g,"&$1_MCE_SEMI_");e(h.split(";"),function(m){var l,n=[];if(m){m=m.replace(/_MCE_SEMI_/g,";");m=m.replace(/url\([^\)]+\)/g,function(o){n.push(o);return"url("+n.length+")"});m=m.split(":");l=c.trim(m[1]);l=l.replace(/url\(([^\)]+)\)/g,function(p,o){return n[parseInt(o)-1]});l=l.replace(/rgb\([^\)]+\)/g,function(o){return i.toHex(o)});if(j.url_converter){l=l.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g,function(o,p){return"url("+j.url_converter.call(j.url_converter_scope||i,i.decode(p),"style",null)+")"})}k[c.trim(m[0]).toLowerCase()]=l}});f("border","","border");f("border","-width","border-width");f("border","-color","border-color");f("border","-style","border-style");f("padding","","padding");f("margin","","margin");g("border","border-width","border-style","border-color");if(a){if(k.border=="medium none"){k.border=""}}return k},serializeStyle:function(g){var f="";e(g,function(i,h){if(h&&i){if(c.isGecko&&h.indexOf("-moz-")===0){return}switch(h){case"color":case"background-color":i=i.toLowerCase();break}f+=(f?" ":"")+h+": "+i+";"}});return f},loadCSS:function(f){var h=this,i=h.doc,g;if(!f){f=""}g=h.select("head")[0];e(f.split(","),function(j){var k;if(h.files[j]){return}h.files[j]=true;k=h.create("link",{rel:"stylesheet",href:c._addVer(j)});if(a&&i.documentMode){k.onload=function(){i.recalc();k.onload=null}}g.appendChild(k)})},addClass:function(f,g){return this.run(f,function(h){var i;if(!g){return 0}if(this.hasClass(h,g)){return h.className}i=this.removeClass(h,g);return h.className=(i!=""?(i+" "):"")+g})},removeClass:function(h,i){var f=this,g;return f.run(h,function(k){var j;if(f.hasClass(k,i)){if(!g){g=new RegExp("(^|\\s+)"+i+"(\\s+|$)","g")}j=k.className.replace(g," ");return k.className=c.trim(j!=" "?j:"")}return k.className})},hasClass:function(g,f){g=this.get(g);if(!g||!f){return false}return(" "+g.className+" ").indexOf(" "+f+" ")!==-1},show:function(f){return this.setStyle(f,"display","block")},hide:function(f){return this.setStyle(f,"display","none")},isHidden:function(f){f=this.get(f);return !f||f.style.display=="none"||this.getStyle(f,"display")=="none"},uniqueId:function(f){return(!f?"mce_":f)+(this.counter++)},setHTML:function(i,g){var f=this;return this.run(i,function(m){var h,k,j,q,l,h;g=f.processHTML(g);if(a){function o(){try{m.innerHTML="
"+g;m.removeChild(m.firstChild)}catch(n){while(m.firstChild){m.firstChild.removeNode()}h=f.create("div");h.innerHTML="
"+g;e(h.childNodes,function(r,p){if(p){m.appendChild(r)}})}}if(f.settings.fix_ie_paragraphs){g=g.replace(/

<\/p>|]+)><\/p>|/gi,' 

')}o();if(f.settings.fix_ie_paragraphs){j=m.getElementsByTagName("p");for(k=j.length-1,h=0;k>=0;k--){q=j[k];if(!q.hasChildNodes()){if(!q.mce_keep){h=1;break}q.removeAttribute("mce_keep")}}}if(h){g=g.replace(/

]+)>|

/ig,'

');g=g.replace(/<\/p>/g,"
");o();if(f.settings.fix_ie_paragraphs){j=m.getElementsByTagName("DIV");for(k=j.length-1;k>=0;k--){q=j[k];if(q.mce_tmp){l=f.doc.createElement("p");q.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi,function(p,n){var r;if(n!=="mce_tmp"){r=q.getAttribute(n);if(!r&&n==="class"){r=q.className}l.setAttribute(n,r)}});for(h=0;h|]+)>/gi,"<$1b$2>");j=j.replace(/<(\/?)em>|]+)>/gi,"<$1i$2>")}else{if(a){j=j.replace(/'/g,"'");j=j.replace(/\s+(disabled|checked|readonly|selected)\s*=\s*[\"\']?(false|0)[\"\']?/gi,"")}}j=j.replace(/]+)\/>|/gi,"");if(i.keep_values){if(/)/g,"\n");h=h.replace(/^[\r\n]*|[\r\n]*$/g,"");h=h.replace(/^\s*(\/\/\s*|\]\]>|-->|\]\]-->)\s*$/g,"");return h}j=j.replace(/]+|)>([\s\S]*?)<\/script>/gi,function(h,m,l){if(!m){m=' type="text/javascript"'}m=m.replace(/src=\"([^\"]+)\"?/i,function(n,o){if(i.url_converter){o=g.encode(i.url_converter.call(i.url_converter_scope||g,g.decode(o),"src","script"))}return'mce_src="'+o+'"'});if(c.trim(l)){k.push(f(l));l=""}return""+l+""});j=j.replace(/]+|)>([\s\S]*?)<\/style>/gi,function(h,m,l){if(l){k.push(f(l));l=""}return""+l+""});j=j.replace(/]+|)>([\s\S]*?)<\/noscript>/g,function(h,m,l){return""})}j=j.replace(//g,"");j=j.replace(/<([\w:]+) [^>]*(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)[^>]*>/gi,function(l){function h(o,m,n){if(n==="false"||n==="0"){return""}return" "+m+'="'+m+'"'}l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\"]([^\"]+)[\"]/gi,h);l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\']([^\']+)[\']/gi,h);l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=([^\s\"\'>]+)/gi,h);l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)([\s>])/gi,' $1="$1"$2');return l});j=j.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi,function(h,m){function l(o,n,q){var p=q;if(h.indexOf("mce_"+n)!=-1){return o}if(n=="style"){if(g._isRes(q)){return o}p=g.encode(g.serializeStyle(g.parseStyle(p)))}else{if(n!="coords"&&n!="shape"){if(i.url_converter){p=g.encode(i.url_converter.call(i.url_converter_scope||g,g.decode(q),n,m))}}}return" "+n+'="'+q+'" mce_'+n+'="'+p+'"'}h=h.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi,l);h=h.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi,l);return h.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi,l)});j=j.replace(/MCE_SCRIPT:([0-9]+)/g,function(l,h){return k[h]})}return j},getOuterHTML:function(f){var g;f=this.get(f);if(!f){return null}if(f.outerHTML!==undefined){return f.outerHTML}g=(f.ownerDocument||this.doc).createElement("body");g.appendChild(f.cloneNode(true));return g.innerHTML},setOuterHTML:function(j,g,k){var f=this;function i(m,l,p){var q,o;o=p.createElement("body");o.innerHTML=l;q=o.lastChild;while(q){f.insertAfter(q.cloneNode(true),m);q=q.previousSibling}f.remove(m)}return this.run(j,function(l){l=f.get(l);if(l.nodeType==1){k=k||l.ownerDocument||f.doc;if(a){try{if(a&&l.nodeType==1){l.outerHTML=g}else{i(l,g,k)}}catch(h){i(l,g,k)}}else{i(l,g,k)}}})},decode:function(g){var h,i,f;if(/&[^;]+;/.test(g)){h=this.doc.createElement("div");h.innerHTML=g;i=h.firstChild;f="";if(i){do{f+=i.nodeValue}while(i.nextSibling)}return f||g}return g},encode:function(f){return f?(""+f).replace(/[<>&\"]/g,function(h,g){switch(h){case"&":return"&";case'"':return""";case"<":return"<";case">":return">"}return h}):f},insertAfter:function(h,g){var f=this;g=f.get(g);return this.run(h,function(k){var j,i;j=g.parentNode;i=g.nextSibling;if(i){j.insertBefore(k,i)}else{j.appendChild(k)}return k})},isBlock:function(f){if(f.nodeType&&f.nodeType!==1){return false}f=f.nodeName||f;return/^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TH|TBODY|TR|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(f)},replace:function(i,h,f){var g=this;if(b(h,"array")){i=i.cloneNode(true)}return g.run(h,function(j){if(f){e(j.childNodes,function(k){i.appendChild(k.cloneNode(true))})}if(g.fixPsuedoLeaks&&j.nodeType===1){j.parentNode.insertBefore(i,j);g.remove(j);return i}return j.parentNode.replaceChild(i,j)})},findCommonAncestor:function(h,f){var i=h,g;while(i){g=f;while(g&&i!=g){g=g.parentNode}if(i==g){break}i=i.parentNode}if(!i&&h.ownerDocument){return h.ownerDocument.documentElement}return i},toHex:function(f){var h=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(f);function g(i){i=parseInt(i).toString(16);return i.length>1?i:"0"+i}if(h){f="#"+g(h[1])+g(h[2])+g(h[3]);return f}return f},getClasses:function(){var l=this,g=[],k,m={},n=l.settings.class_filter,j;if(l.classes){return l.classes}function o(f){e(f.imports,function(i){o(i)});e(f.cssRules||f.rules,function(i){switch(i.type||1){case 1:if(i.selectorText){e(i.selectorText.split(","),function(p){p=p.replace(/^\s*|\s*$|^\s\./g,"");if(/\.mce/.test(p)||!/\.[\w\-]+$/.test(p)){return}j=p;p=p.replace(/.*\.([a-z0-9_\-]+).*/i,"$1");if(n&&!(p=n(p,j))){return}if(!m[p]){g.push({"class":p});m[p]=1}})}break;case 3:o(i.styleSheet);break}})}try{e(l.doc.styleSheets,o)}catch(h){}if(g.length>0){l.classes=g}return g},run:function(j,i,h){var g=this,k;if(g.doc&&typeof(j)==="string"){j=g.get(j)}if(!j){return false}h=h||this;if(!j.nodeType&&(j.length||j.length===0)){k=[];e(j,function(l,f){if(l){if(typeof(l)=="string"){l=g.doc.getElementById(l)}k.push(i.call(h,l,f))}});return k}return i.call(h,j)},getAttribs:function(g){var f;g=this.get(g);if(!g){return[]}if(a){f=[];if(g.nodeName=="OBJECT"){return g.attributes}if(g.nodeName==="OPTION"&&this.getAttrib(g,"selected")){f.push({specified:1,nodeName:"selected"})}g.cloneNode(false).outerHTML.replace(/<\/?[\w:]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=\w+|>/gi,"").replace(/[\w:]+/gi,function(h){f.push({specified:1,nodeName:h})});return f}return g.attributes},destroy:function(g){var f=this;if(f.events){f.events.destroy()}f.win=f.doc=f.root=f.events=null;if(!g){c.removeUnload(f.destroy)}},createRng:function(){var f=this.doc;return f.createRange?f.createRange():new c.dom.Range(this)},split:function(l,k,o){var p=this,f=p.createRng(),m,j,n;function g(r,q){r=r[q];if(r&&r[q]&&r[q].nodeType==1&&i(r[q])){p.remove(r[q])}}function i(q){q=p.getOuterHTML(q);q=q.replace(/<(img|hr|table)/gi,"-");q=q.replace(/<[^>]+>/g,"");return q.replace(/[ \t\r\n]+| | /g,"")==""}function h(r){var q=0;while(r.previousSibling){q++;r=r.previousSibling}return q}if(l&&k){f.setStart(l.parentNode,h(l));f.setEnd(k.parentNode,h(k));m=f.extractContents();f=p.createRng();f.setStart(k.parentNode,h(k)+1);f.setEnd(l.parentNode,h(l)+1);j=f.extractContents();n=l.parentNode;g(m,"lastChild");if(!i(m)){n.insertBefore(m,l)}if(o){n.replaceChild(o,k)}else{n.insertBefore(k,l)}g(j,"firstChild");if(!i(j)){n.insertBefore(j,l)}p.remove(l);return o||k}},bind:function(j,f,i,h){var g=this;if(!g.events){g.events=new c.dom.EventUtils()}return g.events.add(j,f,i,h||this)},unbind:function(i,f,h){var g=this;if(!g.events){g.events=new c.dom.EventUtils()}return g.events.remove(i,f,h)},_findSib:function(j,g,h){var i=this,k=g;if(j){if(b(k,"string")){k=function(f){return i.is(f,g)}}for(j=j[h];j;j=j[h]){if(k(j)){return j}}}return null},_isRes:function(f){return/^(top|left|bottom|right|width|height)/i.test(f)||/;\s*(top|left|bottom|right|width|height)/i.test(f)}});c.DOM=new c.dom.DOMUtils(document,{process_html:0})})(tinymce);(function(f){var h=0,c=1,e=2,d=tinymce.extend;function g(m,k){var j,l;if(m.parentNode!=k){return -1}for(l=k.firstChild,j=0;l!=m;l=l.nextSibling){j++}return j}function b(k){var j=0;while(k.previousSibling){j++;k=k.previousSibling}return j}function i(j,k){var l;if(j.nodeType==3){return j}if(k<0){return j}l=j.firstChild;while(l!=null&&k>0){--k;l=l.nextSibling}if(l!=null){return l}return j}function a(k){var j=k.doc;d(this,{dom:k,startContainer:j,startOffset:0,endContainer:j,endOffset:0,collapsed:true,commonAncestorContainer:j,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3})}d(a.prototype,{setStart:function(k,j){this._setEndPoint(true,k,j)},setEnd:function(k,j){this._setEndPoint(false,k,j)},setStartBefore:function(j){this.setStart(j.parentNode,b(j))},setStartAfter:function(j){this.setStart(j.parentNode,b(j)+1)},setEndBefore:function(j){this.setEnd(j.parentNode,b(j))},setEndAfter:function(j){this.setEnd(j.parentNode,b(j)+1)},collapse:function(k){var j=this;if(k){j.endContainer=j.startContainer;j.endOffset=j.startOffset}else{j.startContainer=j.endContainer;j.startOffset=j.endOffset}j.collapsed=true},selectNode:function(j){this.setStartBefore(j);this.setEndAfter(j)},selectNodeContents:function(j){this.setStart(j,0);this.setEnd(j,j.nodeType===1?j.childNodes.length:j.nodeValue.length)},compareBoundaryPoints:function(m,n){var l=this,p=l.startContainer,o=l.startOffset,k=l.endContainer,j=l.endOffset;if(m===0){return l._compareBoundaryPoints(p,o,p,o)}if(m===1){return l._compareBoundaryPoints(p,o,k,j)}if(m===2){return l._compareBoundaryPoints(k,j,k,j)}if(m===3){return l._compareBoundaryPoints(k,j,p,o)}},deleteContents:function(){this._traverse(e)},extractContents:function(){return this._traverse(h)},cloneContents:function(){return this._traverse(c)},insertNode:function(m){var j=this,l,k;if(m.nodeType===3||m.nodeType===4){l=j.startContainer.splitText(j.startOffset);j.startContainer.parentNode.insertBefore(m,l)}else{if(j.startContainer.childNodes.length>0){k=j.startContainer.childNodes[j.startOffset]}j.startContainer.insertBefore(m,k)}},surroundContents:function(l){var j=this,k=j.extractContents();j.insertNode(l);l.appendChild(k);j.selectNode(l)},cloneRange:function(){var j=this;return d(new a(j.dom),{startContainer:j.startContainer,startOffset:j.startOffset,endContainer:j.endContainer,endOffset:j.endOffset,collapsed:j.collapsed,commonAncestorContainer:j.commonAncestorContainer})},_isCollapsed:function(){return(this.startContainer==this.endContainer&&this.startOffset==this.endOffset)},_compareBoundaryPoints:function(m,p,k,o){var q,l,j,r,t,s;if(m==k){if(p==o){return 0}else{if(p0){l.collapse(k)}}l.collapsed=l._isCollapsed();l.commonAncestorContainer=l.dom.findCommonAncestor(l.startContainer,l.endContainer)},_traverse:function(r){var s=this,q,m=0,v=0,k,o,l,n,j,u;if(s.startContainer==s.endContainer){return s._traverseSameContainer(r)}for(q=s.endContainer,k=q.parentNode;k!=null;q=k,k=k.parentNode){if(k==s.startContainer){return s._traverseCommonStartContainer(q,r)}++m}for(q=s.startContainer,k=q.parentNode;k!=null;q=k,k=k.parentNode){if(k==s.endContainer){return s._traverseCommonEndContainer(q,r)}++v}o=v-m;l=s.startContainer;while(o>0){l=l.parentNode;o--}n=s.endContainer;while(o<0){n=n.parentNode;o++}for(j=l.parentNode,u=n.parentNode;j!=u;j=j.parentNode,u=u.parentNode){l=j;n=u}return s._traverseCommonAncestors(l,n,r)},_traverseSameContainer:function(o){var r=this,q,u,j,k,l,p,m;if(o!=e){q=r.dom.doc.createDocumentFragment()}if(r.startOffset==r.endOffset){return q}if(r.startContainer.nodeType==3){u=r.startContainer.nodeValue;j=u.substring(r.startOffset,r.endOffset);if(o!=c){r.startContainer.deleteData(r.startOffset,r.endOffset-r.startOffset);r.collapse(true)}if(o==e){return null}q.appendChild(r.dom.doc.createTextNode(j));return q}k=i(r.startContainer,r.startOffset);l=r.endOffset-r.startOffset;while(l>0){p=k.nextSibling;m=r._traverseFullySelected(k,o);if(q){q.appendChild(m)}--l;k=p}if(o!=c){r.collapse(true)}return q},_traverseCommonStartContainer:function(j,p){var s=this,r,k,l,m,q,o;if(p!=e){r=s.dom.doc.createDocumentFragment()}k=s._traverseRightBoundary(j,p);if(r){r.appendChild(k)}l=g(j,s.startContainer);m=l-s.startOffset;if(m<=0){if(p!=c){s.setEndBefore(j);s.collapse(false)}return r}k=j.previousSibling;while(m>0){q=k.previousSibling;o=s._traverseFullySelected(k,p);if(r){r.insertBefore(o,r.firstChild)}--m;k=q}if(p!=c){s.setEndBefore(j);s.collapse(false)}return r},_traverseCommonEndContainer:function(m,p){var s=this,r,o,j,k,q,l;if(p!=e){r=s.dom.doc.createDocumentFragment()}j=s._traverseLeftBoundary(m,p);if(r){r.appendChild(j)}o=g(m,s.endContainer);++o;k=s.endOffset-o;j=m.nextSibling;while(k>0){q=j.nextSibling;l=s._traverseFullySelected(j,p);if(r){r.appendChild(l)}--k;j=q}if(p!=c){s.setStartAfter(m);s.collapse(true)}return r},_traverseCommonAncestors:function(p,j,s){var w=this,l,v,o,q,r,k,u,m;if(s!=e){v=w.dom.doc.createDocumentFragment()}l=w._traverseLeftBoundary(p,s);if(v){v.appendChild(l)}o=p.parentNode;q=g(p,o);r=g(j,o);++q;k=r-q;u=p.nextSibling;while(k>0){m=u.nextSibling;l=w._traverseFullySelected(u,s);if(v){v.appendChild(l)}u=m;--k}l=w._traverseRightBoundary(j,s);if(v){v.appendChild(l)}if(s!=c){w.setStartAfter(p);w.collapse(true)}return v},_traverseRightBoundary:function(p,q){var s=this,l=i(s.endContainer,s.endOffset-1),r,o,n,j,k;var m=l!=s.endContainer;if(l==p){return s._traverseNode(l,m,false,q)}r=l.parentNode;o=s._traverseNode(r,false,false,q);while(r!=null){while(l!=null){n=l.previousSibling;j=s._traverseNode(l,m,false,q);if(q!=e){o.insertBefore(j,o.firstChild)}m=true;l=n}if(r==p){return o}l=r.previousSibling;r=r.parentNode;k=s._traverseNode(r,false,false,q);if(q!=e){k.appendChild(o)}o=k}return null},_traverseLeftBoundary:function(p,q){var s=this,m=i(s.startContainer,s.startOffset);var n=m!=s.startContainer,r,o,l,j,k;if(m==p){return s._traverseNode(m,n,true,q)}r=m.parentNode;o=s._traverseNode(r,false,true,q);while(r!=null){while(m!=null){l=m.nextSibling;j=s._traverseNode(m,n,true,q);if(q!=e){o.appendChild(j)}n=true;m=l}if(r==p){return o}m=r.nextSibling;r=r.parentNode;k=s._traverseNode(r,false,true,q);if(q!=e){k.appendChild(o)}o=k}return null},_traverseNode:function(j,o,r,s){var u=this,m,l,p,k,q;if(o){return u._traverseFullySelected(j,s)}if(j.nodeType==3){m=j.nodeValue;if(r){k=u.startOffset;l=m.substring(k);p=m.substring(0,k)}else{k=u.endOffset;l=m.substring(0,k);p=m.substring(k)}if(s!=c){j.nodeValue=p}if(s==e){return null}q=j.cloneNode(false);q.nodeValue=l;return q}if(s==e){return null}return j.cloneNode(false)},_traverseFullySelected:function(l,k){var j=this;if(k!=e){return k==c?l.cloneNode(true):l}l.parentNode.removeChild(l);return null}});f.Range=a})(tinymce.dom);(function(){function a(e){var d=this,h="\uFEFF",b,g;function c(j,i){if(j&&i){if(j.item&&i.item&&j.item(0)===i.item(0)){return 1}if(j.isEqual&&i.isEqual&&i.isEqual(j)){return 1}}return 0}function f(){var m=e.dom,j=e.getRng(),s=m.createRng(),p,k,n,q,o,l;function i(v){var t=v.parentNode.childNodes,u;for(u=t.length-1;u>=0;u--){if(t[u]==v){return u}}return -1}function r(v){var t=j.duplicate(),B,y,u,w,x=0,z=0,A,C;t.collapse(v);B=t.parentElement();t.pasteHTML(h);u=B.childNodes;for(y=0;y0&&(w.nodeType!==3||u[y-1].nodeType!==3)){z++}if(w.nodeType===3){A=w.nodeValue.indexOf(h);if(A!==-1){x+=A;break}x+=w.nodeValue.length}else{x=0}}t.moveStart("character",-1);t.text="";return{index:z,offset:x,parent:B}}n=j.item?j.item(0):j.parentElement();if(n.ownerDocument!=m.doc){return s}if(j.item||!n.hasChildNodes()){s.setStart(n.parentNode,i(n));s.setEnd(s.startContainer,s.startOffset+1);return s}l=e.isCollapsed();p=r(true);k=r(false);p.parent.normalize();k.parent.normalize();q=p.parent.childNodes[Math.min(p.index,p.parent.childNodes.length-1)];if(q.nodeType!=3){s.setStart(p.parent,p.index)}else{s.setStart(p.parent.childNodes[p.index],p.offset)}o=k.parent.childNodes[Math.min(k.index,k.parent.childNodes.length-1)];if(o.nodeType!=3){if(!l){k.index++}s.setEnd(k.parent,k.index)}else{s.setEnd(k.parent.childNodes[k.index],k.offset)}if(!l){q=s.startContainer;if(q.nodeType==1){s.setStart(q,Math.min(s.startOffset,q.childNodes.length))}o=s.endContainer;if(o.nodeType==1){s.setEnd(o,Math.min(s.endOffset,o.childNodes.length))}}d.addRange(s);return s}this.addRange=function(j){var o,m=e.dom.doc.body,p,k,q,l,n,i;q=j.startContainer;l=j.startOffset;n=j.endContainer;i=j.endOffset;o=m.createTextRange();q=q.nodeType==1?q.childNodes[Math.min(l,q.childNodes.length-1)]:q;n=n.nodeType==1?n.childNodes[Math.min(l==i?i:i-1,n.childNodes.length-1)]:n;if(q==n&&q.nodeType==1){if(/^(IMG|TABLE)$/.test(q.nodeName)&&l!=i){o=m.createControlRange();o.addElement(q)}else{o=m.createTextRange();if(!q.hasChildNodes()&&q.canHaveHTML){q.innerHTML=h}o.moveToElementText(q);if(q.innerHTML==h){o.collapse(true);q.removeChild(q.firstChild)}}if(l==i){o.collapse(i<=j.endContainer.childNodes.length-1)}o.select();return}function r(t,v){var u,s,w;if(t.nodeType!=3){return -1}u=t.nodeValue;s=m.createTextRange();t.nodeValue=u.substring(0,v)+h+u.substring(v);s.moveToElementText(t.parentNode);s.findText(h);w=Math.abs(s.moveStart("character",-1048575));t.nodeValue=u;return w}if(j.collapsed){pos=r(q,l);o=m.createTextRange();o.move("character",pos);o.select();return}else{if(q==n&&q.nodeType==3){p=r(q,l);o=m.createTextRange();o.move("character",p);o.moveEnd("character",i-l);o.select();return}p=r(q,l);k=r(n,i);o=m.createTextRange();if(p==-1){o.moveToElementText(q);p=0}else{o.move("character",p)}tmpRng=m.createTextRange();if(k==-1){tmpRng.moveToElementText(n)}else{tmpRng.move("character",k)}o.setEndPoint("EndToEnd",tmpRng);o.select();return}};this.getRangeAt=function(){if(!b||!c(g,e.getRng())){b=f();g=e.getRng()}return b};this.destroy=function(){g=b=null}}tinymce.dom.TridentSelection=a})();(function(){var p=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,i=0,d=Object.prototype.toString,n=false;var b=function(D,t,A,v){A=A||[];var e=t=t||document;if(t.nodeType!==1&&t.nodeType!==9){return[]}if(!D||typeof D!=="string"){return A}var B=[],C,y,G,F,z,s,r=true,w=o(t);p.lastIndex=0;while((C=p.exec(D))!==null){B.push(C[1]);if(C[2]){s=RegExp.rightContext;break}}if(B.length>1&&j.exec(D)){if(B.length===2&&f.relative[B[0]]){y=g(B[0]+B[1],t)}else{y=f.relative[B[0]]?[t]:b(B.shift(),t);while(B.length){D=B.shift();if(f.relative[D]){D+=B.shift()}y=g(D,y)}}}else{if(!v&&B.length>1&&t.nodeType===9&&!w&&f.match.ID.test(B[0])&&!f.match.ID.test(B[B.length-1])){var H=b.find(B.shift(),t,w);t=H.expr?b.filter(H.expr,H.set)[0]:H.set[0]}if(t){var H=v?{expr:B.pop(),set:a(v)}:b.find(B.pop(),B.length===1&&(B[0]==="~"||B[0]==="+")&&t.parentNode?t.parentNode:t,w);y=H.expr?b.filter(H.expr,H.set):H.set;if(B.length>0){G=a(y)}else{r=false}while(B.length){var u=B.pop(),x=u;if(!f.relative[u]){u=""}else{x=B.pop()}if(x==null){x=t}f.relative[u](G,x,w)}}else{G=B=[]}}if(!G){G=y}if(!G){throw"Syntax error, unrecognized expression: "+(u||D)}if(d.call(G)==="[object Array]"){if(!r){A.push.apply(A,G)}else{if(t&&t.nodeType===1){for(var E=0;G[E]!=null;E++){if(G[E]&&(G[E]===true||G[E].nodeType===1&&h(t,G[E]))){A.push(y[E])}}}else{for(var E=0;G[E]!=null;E++){if(G[E]&&G[E].nodeType===1){A.push(y[E])}}}}}else{a(G,A)}if(s){b(s,e,A,v);b.uniqueSort(A)}return A};b.uniqueSort=function(r){if(c){n=false;r.sort(c);if(n){for(var e=1;e":function(w,r,x){var u=typeof r==="string";if(u&&!/\W/.test(r)){r=x?r:r.toUpperCase();for(var s=0,e=w.length;s=0)){if(!s){e.push(v)}}else{if(s){r[u]=false}}}}return false},ID:function(e){return e[1].replace(/\\/g,"")},TAG:function(r,e){for(var s=0;e[s]===false;s++){}return e[s]&&o(e[s])?r[1]:r[1].toUpperCase()},CHILD:function(e){if(e[1]=="nth"){var r=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(e[2]=="even"&&"2n"||e[2]=="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(r[1]+(r[2]||1))-0;e[3]=r[3]-0}e[0]=i++;return e},ATTR:function(u,r,s,e,v,w){var t=u[1].replace(/\\/g,"");if(!w&&f.attrMap[t]){u[1]=f.attrMap[t]}if(u[2]==="~="){u[4]=" "+u[4]+" "}return u},PSEUDO:function(u,r,s,e,v){if(u[1]==="not"){if(u[3].match(p).length>1||/^\w/.test(u[3])){u[3]=b(u[3],null,null,r)}else{var t=b.filter(u[3],r,s,true^v);if(!s){e.push.apply(e,t)}return false}}else{if(f.match.POS.test(u[0])||f.match.CHILD.test(u[0])){return true}}return u},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(s,r,e){return !!b(e[3],s).length},header:function(e){return/h\d/i.test(e.nodeName)},text:function(e){return"text"===e.type},radio:function(e){return"radio"===e.type},checkbox:function(e){return"checkbox"===e.type},file:function(e){return"file"===e.type},password:function(e){return"password"===e.type},submit:function(e){return"submit"===e.type},image:function(e){return"image"===e.type},reset:function(e){return"reset"===e.type},button:function(e){return"button"===e.type||e.nodeName.toUpperCase()==="BUTTON"},input:function(e){return/input|select|textarea|button/i.test(e.nodeName)}},setFilters:{first:function(r,e){return e===0},last:function(s,r,e,t){return r===t.length-1},even:function(r,e){return e%2===0},odd:function(r,e){return e%2===1},lt:function(s,r,e){return re[3]-0},nth:function(s,r,e){return e[3]-0==r},eq:function(s,r,e){return e[3]-0==r}},filter:{PSEUDO:function(w,s,t,x){var r=s[1],u=f.filters[r];if(u){return u(w,t,s,x)}else{if(r==="contains"){return(w.textContent||w.innerText||"").indexOf(s[3])>=0}else{if(r==="not"){var v=s[3];for(var t=0,e=v.length;t=0)}}},ID:function(r,e){return r.nodeType===1&&r.getAttribute("id")===e},TAG:function(r,e){return(e==="*"&&r.nodeType===1)||r.nodeName===e},CLASS:function(r,e){return(" "+(r.className||r.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(v,t){var s=t[1],e=f.attrHandle[s]?f.attrHandle[s](v):v[s]!=null?v[s]:v.getAttribute(s),w=e+"",u=t[2],r=t[4];return e==null?u==="!=":u==="="?w===r:u==="*="?w.indexOf(r)>=0:u==="~="?(" "+w+" ").indexOf(r)>=0:!r?w&&e!==false:u==="!="?w!=r:u==="^="?w.indexOf(r)===0:u==="$="?w.substr(w.length-r.length)===r:u==="|="?w===r||w.substr(0,r.length+1)===r+"-":false},POS:function(u,r,s,v){var e=r[2],t=f.setFilters[e];if(t){return t(u,s,r,v)}}}};var j=f.match.POS;for(var l in f.match){f.match[l]=new RegExp(f.match[l].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var a=function(r,e){r=Array.prototype.slice.call(r);if(e){e.push.apply(e,r);return e}return r};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(k){a=function(u,t){var r=t||[];if(d.call(u)==="[object Array]"){Array.prototype.push.apply(r,u)}else{if(typeof u.length==="number"){for(var s=0,e=u.length;s";var e=document.documentElement;e.insertBefore(r,e.firstChild);if(!!document.getElementById(s)){f.find.ID=function(u,v,w){if(typeof v.getElementById!=="undefined"&&!w){var t=v.getElementById(u[1]);return t?t.id===u[1]||typeof t.getAttributeNode!=="undefined"&&t.getAttributeNode("id").nodeValue===u[1]?[t]:undefined:[]}};f.filter.ID=function(v,t){var u=typeof v.getAttributeNode!=="undefined"&&v.getAttributeNode("id");return v.nodeType===1&&u&&u.nodeValue===t}}e.removeChild(r)})();(function(){var e=document.createElement("div");e.appendChild(document.createComment(""));if(e.getElementsByTagName("*").length>0){f.find.TAG=function(r,v){var u=v.getElementsByTagName(r[1]);if(r[1]==="*"){var t=[];for(var s=0;u[s];s++){if(u[s].nodeType===1){t.push(u[s])}}u=t}return u}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){f.attrHandle.href=function(r){return r.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var e=b,s=document.createElement("div");s.innerHTML="

";if(s.querySelectorAll&&s.querySelectorAll(".TEST").length===0){return}b=function(w,v,t,u){v=v||document;if(!u&&v.nodeType===9&&!o(v)){try{return a(v.querySelectorAll(w),t)}catch(x){}}return e(w,v,t,u)};for(var r in e){b[r]=e[r]}})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var e=document.createElement("div");e.innerHTML="
";if(e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}f.order.splice(1,0,"CLASS");f.find.CLASS=function(r,s,t){if(typeof s.getElementsByClassName!=="undefined"&&!t){return s.getElementsByClassName(r[1])}}})()}function m(r,w,v,A,x,z){var y=r=="previousSibling"&&!z;for(var t=0,s=A.length;t0){u=e;break}}}e=e[r]}A[t]=u}}}var h=document.compareDocumentPosition?function(r,e){return r.compareDocumentPosition(e)&16}:function(r,e){return r!==e&&(r.contains?r.contains(e):true)};var o=function(e){return e.nodeType===9&&e.documentElement.nodeName!=="HTML"||!!e.ownerDocument&&e.ownerDocument.documentElement.nodeName!=="HTML"};var g=function(e,x){var t=[],u="",v,s=x.nodeType?[x]:x;while((v=f.match.PSEUDO.exec(e))){u+=v[0];e=e.replace(f.match.PSEUDO,"")}e=f.relative[e]?e+"*":e;for(var w=0,r=s.length;w=0;h--){k=g[h];if(k.obj===l){j._remove(k.obj,k.name,k.cfunc);k.obj=k.cfunc=null;g.splice(h,1)}}}},cancel:function(g){if(!g){return false}this.stop(g);return this.prevent(g)},stop:function(g){if(g.stopPropagation){g.stopPropagation()}else{g.cancelBubble=true}return false},prevent:function(g){if(g.preventDefault){g.preventDefault()}else{g.returnValue=false}return false},destroy:function(){var g=this;f(g.events,function(j,h){g._remove(j.obj,j.name,j.cfunc);j.obj=j.cfunc=null});g.events=[];g=null},_add:function(h,i,g){if(h.attachEvent){h.attachEvent("on"+i,g)}else{if(h.addEventListener){h.addEventListener(i,g,false)}else{h["on"+i]=g}}},_remove:function(i,j,h){if(i){try{if(i.detachEvent){i.detachEvent("on"+j,h)}else{if(i.removeEventListener){i.removeEventListener(j,h,false)}else{i["on"+j]=null}}}catch(g){}}},_pageInit:function(h){var g=this;if(g.domLoaded){return}g.domLoaded=true;f(g.inits,function(i){i()});g.inits=[]},_wait:function(i){var g=this,h=i.document;if(i.tinyMCE_GZ&&tinyMCE_GZ.loaded){g.domLoaded=1;return}if(h.attachEvent){h.attachEvent("onreadystatechange",function(){if(h.readyState==="complete"){h.detachEvent("onreadystatechange",arguments.callee);g._pageInit(i)}});if(h.documentElement.doScroll&&i==i.top){(function(){if(g.domLoaded){return}try{h.documentElement.doScroll("left")}catch(j){setTimeout(arguments.callee,0);return}g._pageInit(i)})()}}else{if(h.addEventListener){g._add(i,"DOMContentLoaded",function(){g._pageInit(i)})}}g._add(i,"load",function(){g._pageInit(i)})},_stoppers:{preventDefault:function(){this.returnValue=false},stopPropagation:function(){this.cancelBubble=true}}});a=d.dom.Event=new d.dom.EventUtils();a._wait(window);d.addUnload(function(){a.destroy()})})(tinymce);(function(a){var b=a.each;a.create("tinymce.dom.Element",{Element:function(g,e){var c=this,f,d;e=e||{};c.id=g;c.dom=f=e.dom||a.DOM;c.settings=e;if(!a.isIE){d=c.dom.get(c.id)}b(["getPos","getRect","getParent","add","setStyle","getStyle","setStyles","setAttrib","setAttribs","getAttrib","addClass","removeClass","hasClass","getOuterHTML","setOuterHTML","remove","show","hide","isHidden","setHTML","get"],function(h){c[h]=function(){var j=[g],k;for(k=0;k_';j.deleteContents();j.insertNode(f.getRng().createContextualFragment(i));l=f.dom.get("__caret");j=k.createRange();j.setStartBefore(l);j.setEndAfter(l);f.setRng(j);f.dom.remove("__caret")}else{if(j.item){k.execCommand("Delete",false,null);j=f.getRng()}j.pasteHTML(i)}f.onSetContent.dispatch(f,g)},getStart:function(){var f=this,g=f.getRng(),h;if(a){if(g.item){return g.item(0)}g=g.duplicate();g.collapse(1);h=g.parentElement();if(h&&h.nodeName=="BODY"){return h.firstChild}return h}else{h=g.startContainer;if(h.nodeName=="BODY"){return h.firstChild}return f.dom.getParent(h,"*")}},getEnd:function(){var f=this,g=f.getRng(),h;if(a){if(g.item){return g.item(0)}g=g.duplicate();g.collapse(0);h=g.parentElement();if(h&&h.nodeName=="BODY"){return h.lastChild}return h}else{h=g.endContainer;if(h.nodeName=="BODY"){return h.lastChild}return f.dom.getParent(h,"*")}},getBookmark:function(x){var j=this,m=j.getRng(),f,n,l,u=j.dom.getViewPort(j.win),v,p,z,o,w=-16777215,k,h=j.dom.getRoot(),g=0,i=0,y;n=u.x;l=u.y;if(x){return{rng:m,scrollX:n,scrollY:l}}if(a){if(m.item){v=m.item(0);d(j.dom.select(v.nodeName),function(s,r){if(v==s){p=r;return false}});return{tag:v.nodeName,index:p,scrollX:n,scrollY:l}}f=j.dom.doc.body.createTextRange();f.moveToElementText(h);f.collapse(true);z=Math.abs(f.move("character",w));f=m.duplicate();f.collapse(true);p=Math.abs(f.move("character",w));f=m.duplicate();f.collapse(false);o=Math.abs(f.move("character",w))-p;return{start:p-z,length:o,scrollX:n,scrollY:l}}v=j.getNode();k=j.getSel();if(!k){return null}if(v&&v.nodeName=="IMG"){return{scrollX:n,scrollY:l}}function q(A,D,t){var s=j.dom.doc.createTreeWalker(A,NodeFilter.SHOW_TEXT,null,false),E,B=0,C={};while((E=s.nextNode())!=null){if(E==D){C.start=B}if(E==t){C.end=B;return C}B+=e(E.nodeValue||"").length}return null}if(k.anchorNode==k.focusNode&&k.anchorOffset==k.focusOffset){v=q(h,k.anchorNode,k.focusNode);if(!v){return{scrollX:n,scrollY:l}}e(k.anchorNode.nodeValue||"").replace(/^\s+/,function(r){g=r.length});return{start:Math.max(v.start+k.anchorOffset-g,0),end:Math.max(v.end+k.focusOffset-g,0),scrollX:n,scrollY:l,beg:k.anchorOffset-g==0}}else{v=q(h,m.startContainer,m.endContainer);if(!v){return{scrollX:n,scrollY:l}}return{start:Math.max(v.start+m.startOffset-g,0),end:Math.max(v.end+m.endOffset-i,0),scrollX:n,scrollY:l,beg:m.startOffset-g==0}}},moveToBookmark:function(n){var o=this,g=o.getRng(),p=o.getSel(),j=o.dom.getRoot(),m,h,k;function i(q,t,D){var B=o.dom.doc.createTreeWalker(q,NodeFilter.SHOW_TEXT,null,false),x,s=0,A={},u,C,z,y;while((x=B.nextNode())!=null){z=y=0;k=x.nodeValue||"";h=e(k).length;s+=h;if(s>=t&&!A.startNode){u=t-(s-h);if(n.beg&&u>=h){continue}A.startNode=x;A.startOffset=u+y}if(s>=D){A.endNode=x;A.endOffset=D-(s-h)+y;return A}}return null}if(!n){return false}o.win.scrollTo(n.scrollX,n.scrollY);if(a){o.tridentSel.destroy();if(g=n.rng){try{g.select()}catch(l){}return true}o.win.focus();if(n.tag){g=j.createControlRange();d(o.dom.select(n.tag),function(r,q){if(q==n.index){g.addElement(r)}})}else{try{if(n.start<0){return true}g=p.createRange();g.moveToElementText(j);g.collapse(true);g.moveStart("character",n.start);g.moveEnd("character",n.length)}catch(f){return true}}try{g.select()}catch(l){}return true}if(!p){return false}if(n.rng){p.removeAllRanges();p.addRange(n.rng)}else{if(b(n.start)&&b(n.end)){try{m=i(j,n.start,n.end);if(m){g=o.dom.doc.createRange();g.setStart(m.startNode,m.startOffset);g.setEnd(m.endNode,m.endOffset);p.removeAllRanges();p.addRange(g)}if(!c.isOpera){o.win.focus()}}catch(l){}}}},select:function(g,l){var p=this,f=p.getRng(),q=p.getSel(),o,m,k,j=p.win.document;function h(u,t){var s,r;if(u){s=j.createTreeWalker(u,NodeFilter.SHOW_TEXT,null,false);while(u=s.nextNode()){r=u;if(c.trim(u.nodeValue).length!=0){if(t){return u}else{r=u}}}}return r}if(a){try{o=j.body;if(/^(IMG|TABLE)$/.test(g.nodeName)){f=o.createControlRange();f.addElement(g)}else{f=o.createTextRange();f.moveToElementText(g)}f.select()}catch(i){}}else{if(l){m=h(g,1)||p.dom.select("br:first",g)[0];k=h(g,0)||p.dom.select("br:last",g)[0];if(m&&k){f=j.createRange();if(m.nodeName=="BR"){f.setStartBefore(m)}else{f.setStart(m,0)}if(k.nodeName=="BR"){f.setEndBefore(k)}else{f.setEnd(k,k.nodeValue.length)}}else{f.selectNode(g)}}else{f.selectNode(g)}p.setRng(f)}return g},isCollapsed:function(){var f=this,h=f.getRng(),g=f.getSel();if(!h||h.item){return false}return !g||h.boundingWidth==0||h.collapsed},collapse:function(f){var g=this,h=g.getRng(),i;if(h.item){i=h.item(0);h=this.win.document.body.createTextRange();h.moveToElementText(i)}h.collapse(!!f);g.setRng(h)},getSel:function(){var g=this,f=this.win;return f.getSelection?f.getSelection():f.document.selection},getRng:function(j){var g=this,h,i;if(j&&g.tridentSel){return g.tridentSel.getRangeAt(0)}try{if(h=g.getSel()){i=h.rangeCount>0?h.getRangeAt(0):(h.createRange?h.createRange():g.win.document.createRange())}}catch(f){}if(!i){i=a?g.win.document.body.createTextRange():g.win.document.createRange()}return i},setRng:function(i){var h,g=this;if(!g.tridentSel){h=g.getSel();if(h){h.removeAllRanges();h.addRange(i)}}else{if(i.cloneRange){g.tridentSel.addRange(i);return}try{i.select()}catch(f){}}},setNode:function(g){var f=this;f.setContent(f.dom.getOuterHTML(g));return g},getNode:function(){var f=this,h=f.getRng(),g=f.getSel(),i;if(!a){if(!h){return f.dom.getRoot()}i=h.commonAncestorContainer;if(!h.collapsed){if(c.isWebKit&&g.anchorNode&&g.anchorNode.nodeType==1){return g.anchorNode.childNodes[g.anchorOffset]}if(h.startContainer==h.endContainer){if(h.startOffset-h.endOffset<2){if(h.startContainer.hasChildNodes()){i=h.startContainer.childNodes[h.startOffset]}}}}return f.dom.getParent(i,"*")}return h.item?h.item(0):h.parentElement()},getSelectedBlocks:function(g,f){var i=this,j=i.dom,m,h,l,k=[];m=j.getParent(g||i.getStart(),j.isBlock);h=j.getParent(f||i.getEnd(),j.isBlock);if(m){k.push(m)}if(m&&h&&m!=h){l=m;while((l=l.nextSibling)&&l!=h){if(j.isBlock(l)){k.push(l)}}}if(h&&m!=h){k.push(h)}return k},destroy:function(g){var f=this;f.win=null;if(f.tridentSel){f.tridentSel.destroy()}if(!g){c.removeUnload(f.destroy)}}})})(tinymce);(function(a){a.create("tinymce.dom.XMLWriter",{node:null,XMLWriter:function(c){function b(){var e=document.implementation;if(!e||!e.createDocument){try{return new ActiveXObject("MSXML2.DOMDocument")}catch(d){}try{return new ActiveXObject("Microsoft.XmlDom")}catch(d){}}else{return e.createDocument("","",null)}}this.doc=b();this.valid=a.isOpera||a.isWebKit;this.reset()},reset:function(){var b=this,c=b.doc;if(c.firstChild){c.removeChild(c.firstChild)}b.node=c.appendChild(c.createElement("html"))},writeStartElement:function(c){var b=this;b.node=b.node.appendChild(b.doc.createElement(c))},writeAttribute:function(c,b){if(this.valid){b=b.replace(/>/g,"%MCGT%")}this.node.setAttribute(c,b)},writeEndElement:function(){this.node=this.node.parentNode},writeFullEndElement:function(){var b=this,c=b.node;c.appendChild(b.doc.createTextNode(""));b.node=c.parentNode},writeText:function(b){if(this.valid){b=b.replace(/>/g,"%MCGT%")}this.node.appendChild(this.doc.createTextNode(b))},writeCDATA:function(b){this.node.appendChild(this.doc.createCDATASection(b))},writeComment:function(b){if(a.isIE){b=b.replace(/^\-|\-$/g," ")}this.node.appendChild(this.doc.createComment(b.replace(/\-\-/g," ")))},getContent:function(){var b;b=this.doc.xml||new XMLSerializer().serializeToString(this.doc);b=b.replace(/<\?[^?]+\?>||<\/html>||]+>/g,"");b=b.replace(/ ?\/>/g," />");if(this.valid){b=b.replace(/\%MCGT%/g,">")}return b}})})(tinymce);(function(a){a.create("tinymce.dom.StringWriter",{str:null,tags:null,count:0,settings:null,indent:null,StringWriter:function(b){this.settings=a.extend({indent_char:" ",indentation:0},b);this.reset()},reset:function(){this.indent="";this.str="";this.tags=[];this.count=0},writeStartElement:function(b){this._writeAttributesEnd();this.writeRaw("<"+b);this.tags.push(b);this.inAttr=true;this.count++;this.elementCount=this.count},writeAttribute:function(d,b){var c=this;c.writeRaw(" "+c.encode(d)+'="'+c.encode(b)+'"')},writeEndElement:function(){var b;if(this.tags.length>0){b=this.tags.pop();if(this._writeAttributesEnd(1)){this.writeRaw("")}if(this.settings.indentation>0){this.writeRaw("\n")}}},writeFullEndElement:function(){if(this.tags.length>0){this._writeAttributesEnd();this.writeRaw("");if(this.settings.indentation>0){this.writeRaw("\n")}}},writeText:function(b){this._writeAttributesEnd();this.writeRaw(this.encode(b));this.count++},writeCDATA:function(b){this._writeAttributesEnd();this.writeRaw("");this.count++},writeComment:function(b){this._writeAttributesEnd();this.writeRaw("");this.count++},writeRaw:function(b){this.str+=b},encode:function(b){return b.replace(/[<>&"]/g,function(c){switch(c){case"<":return"<";case">":return">";case"&":return"&";case'"':return"""}return c})},getContent:function(){return this.str},_writeAttributesEnd:function(b){if(!this.inAttr){return}this.inAttr=false;if(b&&this.elementCount==this.count){this.writeRaw(" />");return false}this.writeRaw(">");return true}})})(tinymce);(function(e){var g=e.extend,f=e.each,b=e.util.Dispatcher,d=e.isIE,a=e.isGecko;function c(h){return h.replace(/([?+*])/g,".$1")}e.create("tinymce.dom.Serializer",{Serializer:function(j){var i=this;i.key=0;i.onPreProcess=new b(i);i.onPostProcess=new b(i);try{i.writer=new e.dom.XMLWriter()}catch(h){i.writer=new e.dom.StringWriter()}i.settings=j=g({dom:e.DOM,valid_nodes:0,node_filter:0,attr_filter:0,invalid_attrs:/^(mce_|_moz_|sizset|sizcache)/,closed:/^(br|hr|input|meta|img|link|param|area)$/,entity_encoding:"named",entities:"160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro",valid_elements:"*[*]",extended_valid_elements:0,valid_child_elements:0,invalid_elements:0,fix_table_elements:1,fix_list_elements:true,fix_content_duplication:true,convert_fonts_to_spans:false,font_size_classes:0,font_size_style_values:0,apply_source_formatting:0,indent_mode:"simple",indent_char:"\t",indent_levels:1,remove_linebreaks:1,remove_redundant_brs:1,element_format:"xhtml"},j);i.dom=j.dom;if(j.remove_redundant_brs){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/(
\s*)+<\/(p|h[1-6]|div|li)>/gi,function(n,m,o){if(/^
\s*<\//.test(n)){return""}return n})})}if(j.element_format=="html"){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/<([^>]+) \/>/g,"<$1>")})}if(j.fix_list_elements){i.onPreProcess.add(function(v,s){var l,y,w=["ol","ul"],u,t,q,k=/^(OL|UL)$/,z;function m(r,x){var o=x.split(","),p;while((r=r.previousSibling)!=null){for(p=0;p=1767){f(i.dom.select("p table",l.node).reverse(),function(p){var o=i.dom.getParent(p.parentNode,"table,p");if(o.nodeName!="TABLE"){try{i.dom.split(o,p)}catch(m){}}})}})}},setEntities:function(p){var n=this,j,m,h={},o="",k;if(n.entityLookup){return}j=p.split(",");for(m=0;m1){f(q[1].split("|"),function(u){var p={},t;k=k||[];u=u.replace(/::/g,"~");u=/^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(u);u[2]=u[2].replace(/~/g,":");if(u[1]=="!"){r=r||[];r.push(u[2])}if(u[1]=="-"){for(t=0;t=1767)){p=j.createHTMLDocument("");f(r.nodeName=="BODY"?r.childNodes:[r],function(h){p.body.appendChild(p.importNode(h,true))});if(r.nodeName!="BODY"){r=p.body.firstChild}else{r=p.body}i=k.dom.doc;k.dom.doc=p}k.key=""+(parseInt(k.key)+1);if(!q.no_events){q.node=r;k.onPreProcess.dispatch(k,q)}k.writer.reset();k._serializeNode(r,q.getInner);q.content=k.writer.getContent();if(i){k.dom.doc=i}if(!q.no_events){k.onPostProcess.dispatch(k,q)}k._postProcess(q);q.node=null;return e.trim(q.content)},_postProcess:function(n){var i=this,k=i.settings,j=n.content,m=[],l;if(n.format=="html"){l=i._protect({content:j,patterns:[{pattern:/(]*>)(.*?)(<\/script>)/g},{pattern:/(]*>)(.*?)(<\/noscript>)/g},{pattern:/(]*>)(.*?)(<\/style>)/g},{pattern:/(]*>)(.*?)(<\/pre>)/g,encode:1},{pattern:/()/g}]});j=l.content;if(k.entity_encoding!=="raw"){j=i._encode(j)}if(!n.set){j=j.replace(/

\s+<\/p>|]+)>\s+<\/p>/g,k.entity_encoding=="numeric"?" 

":" 

");if(k.remove_linebreaks){j=j.replace(/\r?\n|\r/g," ");j=j.replace(/(<[^>]+>)\s+/g,"$1 ");j=j.replace(/\s+(<\/[^>]+>)/g," $1");j=j.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g,"<$1 $2>");j=j.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g,"<$1>");j=j.replace(/\s+<\/(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g,"")}if(k.apply_source_formatting&&k.indent_mode=="simple"){j=j.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g,"\n<$1$2$3>\n");j=j.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g,"\n<$1$2>");j=j.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g,"\n");j=j.replace(/\n\n/g,"\n")}}j=i._unprotect(j,l);j=j.replace(//g,"");if(k.entity_encoding=="raw"){j=j.replace(/

 <\/p>|]+)> <\/p>/g,"\u00a0

")}j=j.replace(/]+|)>([\s\S]*?)<\/noscript>/g,function(h,p,o){return""+i.dom.decode(o.replace(//g,""))+""})}n.content=j},_serializeNode:function(D,o){var z=this,A=z.settings,x=z.writer,q,j,u,F,E,G,B,h,y,k,r,C,p,m;if(!A.node_filter||A.node_filter(D)){switch(D.nodeType){case 1:if(D.hasAttribute?D.hasAttribute("mce_bogus"):D.getAttribute("mce_bogus")){return}p=false;q=D.hasChildNodes();k=D.getAttribute("mce_name")||D.nodeName.toLowerCase();if(d){if(D.scopeName!=="HTML"&&D.scopeName!=="html"){k=D.scopeName+":"+k}}if(k.indexOf("mce:")===0){k=k.substring(4)}if(!z.validElementsRE||!z.validElementsRE.test(k)||(z.invalidElementsRE&&z.invalidElementsRE.test(k))||o){p=true;break}if(d){if(A.fix_content_duplication){if(D.mce_serialized==z.key){return}D.mce_serialized=z.key}if(k.charAt(0)=="/"){k=k.substring(1)}}else{if(a){if(D.nodeName==="BR"&&D.getAttribute("type")=="_moz"){return}}}if(z.childRules){if(z.parentElementsRE.test(z.elementName)){if(!z.childRules[z.elementName].test(k)){p=true;break}}z.elementName=k}r=z.findRule(k);k=r.name||k;m=A.closed.test(k);if((!q&&r.noEmpty)||(d&&!k)){p=true;break}if(r.requiredAttribs){G=r.requiredAttribs;for(F=G.length-1;F>=0;F--){if(this.dom.getAttrib(D,G[F])!==""){break}}if(F==-1){p=true;break}}x.writeStartElement(k);if(r.attribs){for(F=0,B=r.attribs,E=B.length;F-1;F--){h=B[F];if(h.specified){G=h.nodeName.toLowerCase();if(A.invalid_attrs.test(G)||!r.validAttribsRE.test(G)){continue}C=z.findAttribRule(r,G);y=z._getAttrib(D,C,G);if(y!==null){x.writeAttribute(G,y)}}}}if(k==="script"&&e.trim(D.innerHTML)){x.writeText("// ");x.writeCDATA(D.innerHTML.replace(/|<\[CDATA\[|\]\]>/g,""));q=false;break}if(r.padd){if(q&&(u=D.firstChild)&&u.nodeType===1&&D.childNodes.length===1){if(u.hasAttribute?u.hasAttribute("mce_bogus"):u.getAttribute("mce_bogus")){x.writeText("\u00a0")}}else{if(!q){x.writeText("\u00a0")}}}break;case 3:if(z.childRules&&z.parentElementsRE.test(z.elementName)){if(!z.childRules[z.elementName].test(D.nodeName)){return}}return x.writeText(D.nodeValue);case 4:return x.writeCDATA(D.nodeValue);case 8:return x.writeComment(D.nodeValue)}}else{if(D.nodeType==1){q=D.hasChildNodes()}}if(q&&!m){u=D.firstChild;while(u){z._serializeNode(u);z.elementName=k;u=u.nextSibling}}if(!p){if(!m){x.writeFullEndElement()}else{x.writeEndElement()}}},_protect:function(j){var i=this;j.items=j.items||[];function h(l){return l.replace(/[\r\n\\]/g,function(m){if(m==="\n"){return"\\n"}else{if(m==="\\"){return"\\\\"}}return"\\r"})}function k(l){return l.replace(/\\[\\rn]/g,function(m){if(m==="\\n"){return"\n"}else{if(m==="\\\\"){return"\\"}}return"\r"})}f(j.patterns,function(l){j.content=k(h(j.content).replace(l.pattern,function(n,o,m,p){m=k(m);if(l.encode){m=i._encode(m)}j.items.push(m);return o+""+p}))});return j},_unprotect:function(i,j){i=i.replace(/\"))}if(a&&j.ListBox){if(a.Button||a.SplitButton){e+=b.createHTML("td",{"class":"mceToolbarEnd"},b.createHTML("span",null,""))}}if(b.stdMode){e+=''+j.renderHTML()+""}else{e+=""+j.renderHTML()+""}if(f&&j.ListBox){if(f.Button||f.SplitButton){e+=b.createHTML("td",{"class":"mceToolbarStart"},b.createHTML("span",null,""))}}}g="mceToolbarEnd";if(j.Button){g+=" mceToolbarEndButton"}else{if(j.SplitButton){g+=" mceToolbarEndSplitButton"}else{if(j.ListBox){g+=" mceToolbarEndListBox"}}}e+=b.createHTML("td",{"class":g},b.createHTML("span",null,""));return b.createHTML("table",{id:l.id,"class":"mceToolbar"+(m["class"]?" "+m["class"]:""),cellpadding:"0",cellspacing:"0",align:l.settings.align||""},""+e+"")}});(function(b){var a=b.util.Dispatcher,c=b.each;b.create("tinymce.AddOnManager",{items:[],urls:{},lookup:{},onAdd:new a(this),get:function(d){return this.lookup[d]},requireLangPack:function(f){var d,e=b.EditorManager.settings;if(e&&e.language){d=this.urls[f]+"/langs/"+e.language+".js";if(!b.dom.Event.domLoaded&&!e.strict_mode){b.ScriptLoader.load(d)}else{b.ScriptLoader.add(d)}}},add:function(e,d){this.items.push(d);this.lookup[e]=d;this.onAdd.dispatch(this,e,d);return d},load:function(h,e,d,g){var f=this;if(f.urls[h]){return}if(e.indexOf("/")!=0&&e.indexOf("://")==-1){e=b.baseURL+"/"+e}f.urls[h]=e.substring(0,e.lastIndexOf("/"));b.ScriptLoader.add(e,d,g)}});b.PluginManager=new b.AddOnManager();b.ThemeManager=new b.AddOnManager()}(tinymce));(function(f){var g=f.each,h=f.extend,e=f.DOM,a=f.dom.Event,c=f.ThemeManager,b=f.PluginManager,d=f.explode;f.create("static tinymce.EditorManager",{editors:{},i18n:{},activeEditor:null,preInit:function(){var i=this,j=window.location;f.documentBaseURL=j.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,"");if(!/[\/\\]$/.test(f.documentBaseURL)){f.documentBaseURL+="/"}f.baseURL=new f.util.URI(f.documentBaseURL).toAbsolute(f.baseURL);f.EditorManager.baseURI=new f.util.URI(f.baseURL);i.onBeforeUnload=new f.util.Dispatcher(i);a.add(window,"beforeunload",function(k){i.onBeforeUnload.dispatch(i,k)})},init:function(q){var p=this,l,k=f.ScriptLoader,o,n,i=[],m;function j(u,v,r){var t=u[v];if(!t){return}if(f.is(t,"string")){r=t.replace(/\.\w+$/,"");r=r?f.resolve(r):0;t=f.resolve(t)}return t.apply(r||this,Array.prototype.slice.call(arguments,2))}q=h({theme:"simple",language:"en",strict_loading_mode:document.contentType=="application/xhtml+xml"},q);p.settings=q;if(!a.domLoaded&&!q.strict_loading_mode){if(q.language){k.add(f.baseURL+"/langs/"+q.language+".js")}if(q.theme&&q.theme.charAt(0)!="-"&&!c.urls[q.theme]){c.load(q.theme,"themes/"+q.theme+"/editor_template"+f.suffix+".js")}if(q.plugins){l=d(q.plugins);g(l,function(r){if(r&&r.charAt(0)!="-"&&!b.urls[r]){if(!f.isWebKit&&r=="safari"){return}b.load(r,"plugins/"+r+"/editor_plugin"+f.suffix+".js")}})}k.loadQueue()}a.add(document,"init",function(){var r,t;j(q,"onpageload");if(q.browsers){r=false;g(d(q.browsers),function(u){switch(u){case"ie":case"msie":if(f.isIE){r=true}break;case"gecko":if(f.isGecko){r=true}break;case"safari":case"webkit":if(f.isWebKit){r=true}break;case"opera":if(f.isOpera){r=true}break}});if(!r){return}}switch(q.mode){case"exact":r=q.elements||"";if(r.length>0){g(d(r),function(u){if(e.get(u)){m=new f.Editor(u,q);i.push(m);m.render(1)}else{o=0;g(document.forms,function(v){g(v.elements,function(w){if(w.name===u){u="mce_editor_"+o;e.setAttrib(w,"id",u);m=new f.Editor(u,q);i.push(m);m.render(1)}})})}})}break;case"textareas":case"specific_textareas":function s(v,u){return u.constructor===RegExp?u.test(v.className):e.hasClass(v,u)}g(e.select("textarea"),function(u){if(q.editor_deselector&&s(u,q.editor_deselector)){return}if(!q.editor_selector||s(u,q.editor_selector)){n=e.get(u.name);if(!u.id&&!n){u.id=u.name}if(!u.id||p.get(u.id)){u.id=e.uniqueId()}m=new f.Editor(u.id,q);i.push(m);m.render(1)}});break}if(q.oninit){r=t=0;g(i,function(u){t++;if(!u.initialized){u.onInit.add(function(){r++;if(r==t){j(q,"oninit")}})}else{r++}if(r==t){j(q,"oninit")}})}})},get:function(i){return this.editors[i]},getInstanceById:function(i){return this.get(i)},add:function(i){this.editors[i.id]=i;this._setActive(i);return i},remove:function(j){var i=this;if(!i.editors[j.id]){return null}delete i.editors[j.id];if(i.activeEditor==j){i._setActive(null);g(i.editors,function(k){i._setActive(k);return false})}j.destroy();return j},execCommand:function(o,m,l){var n=this,k=n.get(l),i;switch(o){case"mceFocus":k.focus();return true;case"mceAddEditor":case"mceAddControl":if(!n.get(l)){new f.Editor(l,n.settings).render()}return true;case"mceAddFrameControl":i=l.window;i.tinyMCE=tinyMCE;i.tinymce=f;f.DOM.doc=i.document;f.DOM.win=i;k=new f.Editor(l.element_id,l);k.render();if(f.isIE){function j(){k.destroy();i.detachEvent("onunload",j);i=i.tinyMCE=i.tinymce=null}i.attachEvent("onunload",j)}l.page_window=null;return true;case"mceRemoveEditor":case"mceRemoveControl":if(k){k.remove()}return true;case"mceToggleEditor":if(!k){n.execCommand("mceAddControl",0,l);return true}if(k.isHidden()){k.show()}else{k.hide()}return true}if(n.activeEditor){return n.activeEditor.execCommand(o,m,l)}return false},execInstanceCommand:function(m,l,k,j){var i=this.get(m);if(i){return i.execCommand(l,k,j)}return false},triggerSave:function(){g(this.editors,function(i){i.save()})},addI18n:function(k,l){var i,j=this.i18n;if(!f.is(k,"string")){g(k,function(n,m){g(n,function(q,p){g(q,function(s,r){if(p==="common"){j[m+"."+r]=s}else{j[m+"."+p+"."+r]=s}})})})}else{g(l,function(n,m){j[k+"."+m]=n})}},_setActive:function(i){this.selectedInstance=this.activeEditor=i}});f.EditorManager.preInit()})(tinymce);var tinyMCE=window.tinyMCE=tinymce.EditorManager;(function(n){var o=n.DOM,k=n.dom.Event,f=n.extend,l=n.util.Dispatcher;var j=n.each,a=n.isGecko,b=n.isIE,e=n.isWebKit;var d=n.is,h=n.ThemeManager,c=n.PluginManager,i=n.EditorManager;var p=n.inArray,m=n.grep,g=n.explode;n.create("tinymce.Editor",{Editor:function(u,r){var q=this;q.id=q.editorId=u;q.execCommands={};q.queryStateCommands={};q.queryValueCommands={};q.isNotDirty=false;q.plugins={};j(["onPreInit","onBeforeRenderUI","onPostRender","onInit","onRemove","onActivate","onDeactivate","onClick","onEvent","onMouseUp","onMouseDown","onDblClick","onKeyDown","onKeyUp","onKeyPress","onContextMenu","onSubmit","onReset","onPaste","onPreProcess","onPostProcess","onBeforeSetContent","onBeforeGetContent","onSetContent","onGetContent","onLoadContent","onSaveContent","onNodeChange","onChange","onBeforeExecCommand","onExecCommand","onUndo","onRedo","onVisualAid","onSetProgressState"],function(s){q[s]=new l(q)});q.settings=r=f({id:u,language:"en",docs_language:"en",theme:"simple",skin:"default",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:n.documentBaseURL,add_form_submit_trigger:1,submit_patch:1,add_unload_trigger:1,convert_urls:1,relative_urls:1,remove_script_host:1,table_inline_editing:0,object_resizing:1,cleanup:1,accessibility_focus:1,custom_shortcuts:1,custom_undo_redo_keyboard_shortcuts:1,custom_undo_redo_restore_selection:1,custom_undo_redo:1,doctype:'',visual_table_class:"mceItemTable",visual:1,inline_styles:true,convert_fonts_to_spans:true,font_size_style_values:"xx-small,x-small,small,medium,large,x-large,xx-large",apply_source_formatting:1,directionality:"ltr",forced_root_block:"p",valid_elements:"@[id|class|style|title|dir';if(G.document_base_url!=n.documentBaseURL){F.iframeHTML+=''}F.iframeHTML+='';if(n.relaxedDomain){F.iframeHTML+=''); - }; + if (callback) { + // Store away callback for later execution + if (!scriptLoadedCallbacks[url]) + scriptLoadedCallbacks[url] = []; - if (!tinymce.is(u, 'string')) { - each(u, function(u) { - loadScript(u); + scriptLoadedCallbacks[url].push({ + func : callback, + scope : scope || this }); + } + }; - if (cb) - cb.call(s || t); - } else { - loadScript(u); + this.loadQueue = function(callback, scope) { + this.loadScripts(queue, callback, scope); + }; - if (cb) - cb.call(s || t); - } - }, + this.loadScripts = function(scripts, callback, scope) { + var loadScripts; - loadQueue : function(cb, s) { - var t = this; + function execScriptLoadedCallbacks(url) { + // Execute URL callback functions + tinymce.each(scriptLoadedCallbacks[url], function(callback) { + callback.func.call(callback.scope); + }); + + scriptLoadedCallbacks[url] = undefined; + }; - if (!t.queueLoading) { - t.queueLoading = 1; - t.queueCallbacks = []; + queueLoadedCallbacks.push({ + func : callback, + scope : scope || this + }); - t.loadScripts(t.queue, function() { - t.queueLoading = 0; + loadScripts = function() { + var loadingScripts = tinymce.grep(scripts); - if (cb) - cb.call(s || t); + // Current scripts has been handled + scripts.length = 0; - each(t.queueCallbacks, function(o) { - o.func.call(o.scope); - }); + // Load scripts that needs to be loaded + tinymce.each(loadingScripts, function(url) { + // Script is already loaded then execute script callbacks directly + if (states[url] == LOADED) { + execScriptLoadedCallbacks(url); + return; + } + + // Is script not loading then start loading it + if (states[url] != LOADING) { + states[url] = LOADING; + loading++; + + loadScript(url, function() { + states[url] = LOADED; + loading--; + + execScriptLoadedCallbacks(url); + + // Load more scripts if they where added by the recently loaded script + loadScripts(); + }); + } }); - } else if (cb) - t.queueCallbacks.push({func : cb, scope : s || t}); - }, - eval : function(co) { - var w = window; + // No scripts are currently loading then execute all pending queue loaded callbacks + if (!loading) { + tinymce.each(queueLoadedCallbacks, function(callback) { + callback.func.call(callback.scope); + }); - // Evaluate script - if (!w.execScript) { - try { - eval.call(w, co); - } catch (ex) { - eval(co, w); // Firefox 3.0a8 + queueLoadedCallbacks.length = 0; } - } else - w.execScript(co); // IE - }, + }; - loadScripts : function(sc, cb, s) { - var t = this, lo = t.lookup; + loadScripts(); + }; + }; - function done(o) { - o.state = 2; // Has been loaded + // Global script loader + tinymce.ScriptLoader = new tinymce.dom.ScriptLoader(); +})(tinymce); - // Run callback - if (o.func) - o.func.call(o.scope || t); - }; +tinymce.dom.TreeWalker = function(start_node, root_node) { + var node = start_node; - function allDone() { - var l; + function findSibling(node, start_name, sibling_name, shallow) { + var sibling, parent; - // Check if all files are loaded - l = sc.length; - each(sc, function(o) { - o = lo[o.url]; + if (node) { + // Walk into nodes if it has a start + if (!shallow && node[start_name]) + return node[start_name]; - if (o.state === 2) {// It has finished loading - done(o); - l--; - } else - load(o); - }); + // Return the sibling if it has one + if (node != root_node) { + sibling = node[sibling_name]; + if (sibling) + return sibling; - // They are all loaded - if (l === 0 && cb) { - cb.call(s || t); - cb = 0; + // Walk up the parents to look for siblings + for (parent = node.parentNode; parent && parent != root_node; parent = parent.parentNode) { + sibling = parent[sibling_name]; + if (sibling) + return sibling; } - }; + } + } + }; - function load(o) { - if (o.state > 0) - return; + this.current = function() { + return node; + }; + + this.next = function(shallow) { + return (node = findSibling(node, 'firstChild', 'nextSibling', shallow)); + }; + + this.prev = function(shallow) { + return (node = findSibling(node, 'lastChild', 'lastSibling', shallow)); + }; +}; + +(function() { + var transitional = {}; + + function unpack(lookup, data) { + var key; + + function replace(value) { + return value.replace(/[A-Z]+/g, function(key) { + return replace(lookup[key]); + }); + }; + + // Unpack lookup + for (key in lookup) { + if (lookup.hasOwnProperty(key)) + lookup[key] = replace(lookup[key]); + } + + // Unpack and parse data into object map + replace(data).replace(/#/g, '#text').replace(/(\w+)\[([^\]]+)\]/g, function(str, name, children) { + var i, map = {}; - o.state = 1; // Is loading + children = children.split(/\|/); + + for (i = children.length - 1; i >= 0; i--) + map[children[i]] = 1; + + transitional[name] = map; + }); + }; - tinymce.dom.ScriptLoader.loadScript(o.url, function() { - done(o); - allDone(); + // This is the XHTML 1.0 transitional elements with it's children packed to reduce it's size + // we will later include the attributes here and use it as a default for valid elements but it + // requires us to rewrite the serializer engine + unpack({ + Z : '#|H|K|N|O|P', + Y : '#|X|form|R|Q', + X : 'p|T|div|U|W|isindex|fieldset|table', + W : 'pre|hr|blockquote|address|center|noframes', + U : 'ul|ol|dl|menu|dir', + ZC : '#|p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q', + T : 'h1|h2|h3|h4|h5|h6', + ZB : '#|X|S|Q', + S : 'R|P', + ZA : '#|a|G|J|M|O|P', + R : '#|a|H|K|N|O', + Q : 'noscript|P', + P : 'ins|del|script', + O : 'input|select|textarea|label|button', + N : 'M|L', + M : 'em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym', + L : 'sub|sup', + K : 'J|I', + J : 'tt|i|b|u|s|strike', + I : 'big|small|font|basefont', + H : 'G|F', + G : 'br|span|bdo', + F : 'object|applet|img|map|iframe' + }, 'script[]' + + 'style[]' + + 'object[#|param|X|form|a|H|K|N|O|Q]' + + 'param[]' + + 'p[S]' + + 'a[Z]' + + 'br[]' + + 'span[S]' + + 'bdo[S]' + + 'applet[#|param|X|form|a|H|K|N|O|Q]' + + 'h1[S]' + + 'img[]' + + 'map[X|form|Q|area]' + + 'h2[S]' + + 'iframe[#|X|form|a|H|K|N|O|Q]' + + 'h3[S]' + + 'tt[S]' + + 'i[S]' + + 'b[S]' + + 'u[S]' + + 's[S]' + + 'strike[S]' + + 'big[S]' + + 'small[S]' + + 'font[S]' + + 'basefont[]' + + 'em[S]' + + 'strong[S]' + + 'dfn[S]' + + 'code[S]' + + 'q[S]' + + 'samp[S]' + + 'kbd[S]' + + 'var[S]' + + 'cite[S]' + + 'abbr[S]' + + 'acronym[S]' + + 'sub[S]' + + 'sup[S]' + + 'input[]' + + 'select[optgroup|option]' + + 'optgroup[option]' + + 'option[]' + + 'textarea[]' + + 'label[S]' + + 'button[#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]' + + 'h4[S]' + + 'ins[#|X|form|a|H|K|N|O|Q]' + + 'h5[S]' + + 'del[#|X|form|a|H|K|N|O|Q]' + + 'h6[S]' + + 'div[#|X|form|a|H|K|N|O|Q]' + + 'ul[li]' + + 'li[#|X|form|a|H|K|N|O|Q]' + + 'ol[li]' + + 'dl[dt|dd]' + + 'dt[S]' + + 'dd[#|X|form|a|H|K|N|O|Q]' + + 'menu[li]' + + 'dir[li]' + + 'pre[ZA]' + + 'hr[]' + + 'blockquote[#|X|form|a|H|K|N|O|Q]' + + 'address[S|p]' + + 'center[#|X|form|a|H|K|N|O|Q]' + + 'noframes[#|X|form|a|H|K|N|O|Q]' + + 'isindex[]' + + 'fieldset[#|legend|X|form|a|H|K|N|O|Q]' + + 'legend[S]' + + 'table[caption|col|colgroup|thead|tfoot|tbody|tr]' + + 'caption[S]' + + 'col[]' + + 'colgroup[col]' + + 'thead[tr]' + + 'tr[th|td]' + + 'th[#|X|form|a|H|K|N|O|Q]' + + 'form[#|X|a|H|K|N|O|Q]' + + 'noscript[#|X|form|a|H|K|N|O|Q]' + + 'td[#|X|form|a|H|K|N|O|Q]' + + 'tfoot[tr]' + + 'tbody[tr]' + + 'area[]' + + 'base[]' + + 'body[#|X|form|a|H|K|N|O|Q]' + ); + + tinymce.dom.Schema = function() { + var t = this, elements = transitional; + + t.isValid = function(name, child_name) { + var element = elements[name]; + + return !!(element && (!child_name || element[child_name])); + }; + }; +})(); +(function(tinymce) { + tinymce.dom.RangeUtils = function(dom) { + var INVISIBLE_CHAR = '\uFEFF'; + + this.walk = function(rng, callback) { + var startContainer = rng.startContainer, + startOffset = rng.startOffset, + endContainer = rng.endContainer, + endOffset = rng.endOffset, + ancestor, startPoint, + endPoint, node, parent, siblings, nodes; + + // Handle table cell selection the table plugin enables + // you to fake select table cells and perform formatting actions on them + nodes = dom.select('td.mceSelected,th.mceSelected'); + if (nodes.length > 0) { + tinymce.each(nodes, function(node) { + callback([node]); }); - /* - tinymce.util.XHR.send({ - url : o.url, - error : t.settings.error, - success : function(co) { - t.eval(co); - done(o); - allDone(); + return; + } + + function collectSiblings(node, name, end_node) { + var siblings = []; + + for (; node && node != end_node; node = node[name]) + siblings.push(node); + + return siblings; + }; + + function findEndPoint(node, root) { + do { + if (node.parentNode == root) + return node; + + node = node.parentNode; + } while(node); + }; + + function walkBoundary(start_node, end_node, next) { + var siblingName = next ? 'nextSibling' : 'previousSibling'; + + for (node = start_node, parent = node.parentNode; node && node != end_node; node = parent) { + parent = node.parentNode; + siblings = collectSiblings(node == start_node ? node : node[siblingName], siblingName); + + if (siblings.length) { + if (!next) + siblings.reverse(); + + callback(siblings); } - }); - */ + } }; - each(sc, function(o) { - var u = o.url; + // If index based start position then resolve it + if (startContainer.nodeType == 1 && startContainer.hasChildNodes()) + startContainer = startContainer.childNodes[startOffset]; - // Add to queue if needed - if (!lo[u]) { - lo[u] = o; - t.queue.push(o); - } else - o = lo[u]; + // If index based end position then resolve it + if (endContainer.nodeType == 1 && endContainer.hasChildNodes()) + endContainer = endContainer.childNodes[Math.min(startOffset == endOffset ? endOffset : endOffset - 1, endContainer.childNodes.length - 1)]; - // Is already loading or has been loaded - if (o.state > 0) - return; + // Find common ancestor and end points + ancestor = dom.findCommonAncestor(startContainer, endContainer); - if (!Event.domLoaded && !t.settings.strict_mode) { - var ix, ol = ''; + // Same container + if (startContainer == endContainer) + return callback([startContainer]); - // Add onload events - if (cb || o.func) { - o.state = 1; // Is loading + // Process left side + for (node = startContainer; node; node = node.parentNode) { + if (node == endContainer) + return walkBoundary(startContainer, ancestor, true); - ix = tinymce.dom.ScriptLoader._addOnLoad(function() { - done(o); - allDone(); - }); + if (node == ancestor) + break; + } - if (tinymce.isIE) - ol = ' onreadystatechange="'; - else - ol = ' onload="'; + // Process right side + for (node = endContainer; node; node = node.parentNode) { + if (node == startContainer) + return walkBoundary(endContainer, ancestor); - ol += 'tinymce.dom.ScriptLoader._onLoad(this,\'' + u + '\',' + ix + ');"'; - } + if (node == ancestor) + break; + } - document.write(''); + // Find start/end point + startPoint = findEndPoint(startContainer, ancestor) || startContainer; + endPoint = findEndPoint(endContainer, ancestor) || endContainer; - if (!o.func) - done(o); - } else - load(o); - }); + // Walk left leaf + walkBoundary(startContainer, startPoint, true); - allDone(); - }, + // Walk the middle from start to end point + siblings = collectSiblings( + startPoint == startContainer ? startPoint : startPoint.nextSibling, + 'nextSibling', + endPoint == endContainer ? endPoint.nextSibling : endPoint + ); - // Static methods - 'static' : { - _addOnLoad : function(f) { - var t = this; + if (siblings.length) + callback(siblings); - t._funcs = t._funcs || []; - t._funcs.push(f); + // Walk right leaf + walkBoundary(endContainer, endPoint); + }; - return t._funcs.length - 1; - }, + /* this.split = function(rng) { + var startContainer = rng.startContainer, + startOffset = rng.startOffset, + endContainer = rng.endContainer, + endOffset = rng.endOffset; - _onLoad : function(e, u, ix) { - if (!tinymce.isIE || e.readyState == 'complete') - this._funcs[ix].call(this); - }, + function splitText(node, offset) { + if (offset == node.nodeValue.length) + node.appendData(INVISIBLE_CHAR); - loadScript : function(u, cb) { - var id = tinymce.DOM.uniqueId(), e; + node = node.splitText(offset); - function done() { - Event.clear(id); - tinymce.DOM.remove(id); + if (node.nodeValue === INVISIBLE_CHAR) + node.nodeValue = ''; - if (cb) { - cb.call(document, u); - cb = 0; - } - }; + return node; + }; - if (tinymce.isIE) { -/* Event.add(e, 'readystatechange', function(e) { - if (e.target && e.target.readyState == 'complete') - done(); - });*/ + // Handle single text node + if (startContainer == endContainer) { + if (startContainer.nodeType == 3) { + if (startOffset != 0) + startContainer = endContainer = splitText(startContainer, startOffset); - tinymce.util.XHR.send({ - url : tinymce._addVer(u), - async : false, - success : function(co) { - window.execScript(co); - done(); - } - }); - } else { - e = tinymce.DOM.create('script', {id : id, type : 'text/javascript', src : tinymce._addVer(u)}); - Event.add(e, 'load', done); + if (endOffset - startOffset != startContainer.nodeValue.length) + splitText(startContainer, endOffset - startOffset); + } + } else { + // Split startContainer text node if needed + if (startContainer.nodeType == 3 && startOffset != 0) { + startContainer = splitText(startContainer, startOffset); + startOffset = 0; + } - // Check for head or body - (document.getElementsByTagName('head')[0] || document.body).appendChild(e); + // Split endContainer text node if needed + if (endContainer.nodeType == 3 && endOffset != endContainer.nodeValue.length) { + endContainer = splitText(endContainer, endOffset).previousSibling; + endOffset = endContainer.nodeValue.length; } } - } - }); - // Global script loader - tinymce.ScriptLoader = new tinymce.dom.ScriptLoader(); + return { + startContainer : startContainer, + startOffset : startOffset, + endContainer : endContainer, + endOffset : endOffset + }; + }; +*/ + }; })(tinymce); + (function(tinymce) { // Shorten class names var DOM = tinymce.DOM, is = tinymce.is; @@ -7005,7 +7312,8 @@ window.tinymce.dom.Sizzle = Sizzle; tinymce.dom.Event.clear(this.id); } }); -})(tinymce);tinymce.create('tinymce.ui.Container:tinymce.ui.Control', { +})(tinymce); +tinymce.create('tinymce.ui.Container:tinymce.ui.Control', { Container : function(id, s) { this.parent(id, s); @@ -7026,6 +7334,7 @@ window.tinymce.dom.Sizzle = Sizzle; } }); + tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { Separator : function(id, s) { this.parent(id, s); @@ -7036,6 +7345,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { return tinymce.DOM.createHTML('span', {'class' : this.classPrefix}); } }); + (function(tinymce) { var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk; @@ -7065,6 +7375,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { } }); })(tinymce); + (function(tinymce) { var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk; @@ -7162,7 +7473,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { return m; } }); -})(tinymce);(function(tinymce) { +})(tinymce); +(function(tinymce) { var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element; tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', { @@ -7489,7 +7801,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { DOM.addClass(ro, 'mceLast'); } }); -})(tinymce);(function(tinymce) { +})(tinymce); +(function(tinymce) { var DOM = tinymce.DOM; tinymce.create('tinymce.ui.Button:tinymce.ui.Control', { @@ -7522,6 +7835,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { } }); })(tinymce); + (function(tinymce) { var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; @@ -7669,16 +7983,16 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { hideMenu : function(e) { var t = this; - // Prevent double toogles by canceling the mouse click event to the button - if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open')) - return; - - if (!e || !DOM.getParent(e.target, '.mceMenu')) { - DOM.removeClass(t.id, t.classPrefix + 'Selected'); - Event.remove(DOM.doc, 'mousedown', t.hideMenu, t); + if (t.menu && t.menu.isMenuVisible) { + // Prevent double toogles by canceling the mouse click event to the button + if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open')) + return; - if (t.menu) + if (!e || !DOM.getParent(e.target, '.mceMenu')) { + DOM.removeClass(t.id, t.classPrefix + 'Selected'); + Event.remove(DOM.doc, 'mousedown', t.hideMenu, t); t.menu.hideMenu(); + } } }, @@ -7704,13 +8018,25 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { }); each(t.items, function(o) { - o.id = DOM.uniqueId(); - o.onclick = function() { - if (t.settings.onselect(o.value) !== false) - t.select(o.value); // Must be runned after - }; + // No value then treat it as a title + if (o.value === undefined) { + m.add({ + title : o.title, + 'class' : 'mceMenuItemTitle', + onclick : function() { + if (t.settings.onselect('') !== false) + t.select(''); // Must be runned after + } + }); + } else { + o.id = DOM.uniqueId(); + o.onclick = function() { + if (t.settings.onselect(o.value) !== false) + t.select(o.value); // Must be runned after + }; - m.add(o); + m.add(o); + } }); t.onRenderMenu.dispatch(t, m); @@ -7779,7 +8105,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { Event.clear(this.id + '_open'); } }); -})(tinymce);(function(tinymce) { +})(tinymce); +(function(tinymce) { var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', { @@ -7907,7 +8234,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { t.onPostRender.dispatch(t, DOM.get(t.id)); } }); -})(tinymce);(function(tinymce) { +})(tinymce); +(function(tinymce) { var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each; tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', { @@ -7996,6 +8324,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { } }); })(tinymce); + (function(tinymce) { var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each; @@ -8061,6 +8390,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { } }); })(tinymce); + (function(tinymce) { var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each; @@ -8169,7 +8499,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { style : { backgroundColor : '#' + c }, - mce_color : '#' + c + _mce_color : '#' + c }); }); @@ -8191,7 +8521,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { e = e.target; - if (e.nodeName == 'A' && (c = e.getAttribute('mce_color'))) + if (e.nodeName == 'A' && (c = e.getAttribute('_mce_color'))) t.setColor(c); return Event.cancel(e); // Prevent IE auto save warning @@ -8227,6 +8557,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { } }); })(tinymce); + tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { renderHTML : function() { var t = this, h = '', c, co, dom = tinymce.DOM, s = t.settings, i, pr, nx, cl; @@ -8289,6 +8620,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || ''}, '' + h + ''); } }); + (function(tinymce) { var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each; @@ -8304,16 +8636,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }, requireLangPack : function(n) { - var u, s = tinymce.EditorManager.settings; + var s = tinymce.settings; - if (s && s.language) { - u = this.urls[n] + '/langs/' + s.language + '.js'; - - if (!tinymce.dom.Event.domLoaded && !s.strict_mode) - tinymce.ScriptLoader.load(u); - else - tinymce.ScriptLoader.add(u); - } + if (s && s.language) + tinymce.ScriptLoader.add(this.urls[n] + '/langs/' + s.language + '.js'); }, add : function(id, o) { @@ -8345,39 +8671,44 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { (function(tinymce) { // Shorten names - var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode; + var each = tinymce.each, extend = tinymce.extend, + DOM = tinymce.DOM, Event = tinymce.dom.Event, + ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, + explode = tinymce.explode, + Dispatcher = tinymce.util.Dispatcher, undefined, instanceCounter = 0; - tinymce.create('static tinymce.EditorManager', { - editors : {}, + // Setup some URLs where the editor API is located and where the document is + tinymce.documentBaseURL = window.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); + if (!/[\/\\]$/.test(tinymce.documentBaseURL)) + tinymce.documentBaseURL += '/'; - i18n : {}, - - activeEditor : null, + tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL); - preInit : function() { - var t = this, lo = window.location; + tinymce.baseURI = new tinymce.util.URI(tinymce.baseURL); - // Setup some URLs where the editor API is located and where the document is - tinymce.documentBaseURL = lo.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); - if (!/[\/\\]$/.test(tinymce.documentBaseURL)) - tinymce.documentBaseURL += '/'; + // Add before unload listener + // This was required since IE was leaking memory if you added and removed beforeunload listeners + // with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event + tinymce.onBeforeUnload = new Dispatcher(tinymce); - tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL); - tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL); + // Must be on window or IE will leak if the editor is placed in frame or iframe + Event.add(window, 'beforeunload', function(e) { + tinymce.onBeforeUnload.dispatch(tinymce, e); + }); - // Add before unload listener - // This was required since IE was leaking memory if you added and removed beforeunload listeners - // with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event - t.onBeforeUnload = new tinymce.util.Dispatcher(t); + tinymce.onAddEditor = new Dispatcher(tinymce); - // Must be on window or IE will leak if the editor is placed in frame or iframe - Event.add(window, 'beforeunload', function(e) { - t.onBeforeUnload.dispatch(t, e); - }); - }, + tinymce.onRemoveEditor = new Dispatcher(tinymce); + + tinymce.EditorManager = extend(tinymce, { + editors : [], + + i18n : {}, + + activeEditor : null, init : function(s) { - var t = this, pl, sl = tinymce.ScriptLoader, c, e, el = [], ed; + var t = this, pl, sl = tinymce.ScriptLoader, e, el = [], ed; function execCallback(se, n, s) { var f = se[n]; @@ -8396,83 +8727,17 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { s = extend({ theme : "simple", - language : "en", - strict_loading_mode : document.contentType == 'application/xhtml+xml' + language : "en" }, s); t.settings = s; - // If page not loaded and strict mode isn't enabled then load them - if (!Event.domLoaded && !s.strict_loading_mode) { - // Load language - if (s.language) - sl.add(tinymce.baseURL + '/langs/' + s.language + '.js'); - - // Load theme - if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme]) - ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js'); - - // Load plugins - if (s.plugins) { - pl = explode(s.plugins); - - // Load rest if plugins - each(pl, function(v) { - if (v && v.charAt(0) != '-' && !PluginManager.urls[v]) { - // Skip safari plugin for other browsers - if (!tinymce.isWebKit && v == 'safari') - return; - - PluginManager.load(v, 'plugins/' + v + '/editor_plugin' + tinymce.suffix + '.js'); - } - }); - } - - sl.loadQueue(); - } - // Legacy call Event.add(document, 'init', function() { var l, co; execCallback(s, 'onpageload'); - // Verify that it's a valid browser - if (s.browsers) { - l = false; - - each(explode(s.browsers), function(v) { - switch (v) { - case 'ie': - case 'msie': - if (tinymce.isIE) - l = true; - break; - - case 'gecko': - if (tinymce.isGecko) - l = true; - break; - - case 'safari': - case 'webkit': - if (tinymce.isWebKit) - l = true; - break; - - case 'opera': - if (tinymce.isOpera) - l = true; - - break; - } - }); - - // Not a valid one - if (!l) - return; - } - switch (s.mode) { case "exact": l = s.elements || ''; @@ -8484,12 +8749,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { el.push(ed); ed.render(1); } else { - c = 0; - each(document.forms, function(f) { each(f.elements, function(e) { if (e.name === v) { - v = 'mce_editor_' + c; + v = 'mce_editor_' + instanceCounter++; DOM.setAttrib(e, 'id', v); ed = new tinymce.Editor(v, s); @@ -8535,7 +8798,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { if (s.oninit) { l = co = 0; - each (el, function(ed) { + each(el, function(ed) { co++; if (!ed.initialized) { @@ -8559,6 +8822,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }, get : function(id) { + if (id === undefined) + return this.editors; + return this.editors[id]; }, @@ -8566,35 +8832,44 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { return this.get(id); }, - add : function(e) { - this.editors[e.id] = e; - this._setActive(e); + add : function(editor) { + var self = this, editors = self.editors; - return e; + // Add named and index editor instance + editors[editor.id] = editor; + editors.push(editor); + + self._setActive(editor); + self.onAddEditor.dispatch(self, editor); + + + return editor; }, - remove : function(e) { - var t = this; + remove : function(editor) { + var t = this, i, editors = t.editors; // Not in the collection - if (!t.editors[e.id]) + if (!editors[editor.id]) return null; - delete t.editors[e.id]; - - // Select another editor since the active one was removed - if (t.activeEditor == e) { - t._setActive(null); + delete editors[editor.id]; - each(t.editors, function(e) { - t._setActive(e); - return false; // Break - }); + for (i = 0; i < editors.length; i++) { + if (editors[i] == editor) { + editors.splice(i, 1); + break; + } } - e.destroy(); + // Select another editor since the active one was removed + if (t.activeEditor == editor) + t._setActive(editors[0]); - return e; + editor.destroy(); + t.onRemoveEditor.dispatch(t, editor); + + return editor; }, execCommand : function(c, u, v) { @@ -8707,20 +8982,19 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // Private methods - _setActive : function(e) { - this.selectedInstance = this.activeEditor = e; + _setActive : function(editor) { + this.selectedInstance = this.activeEditor = editor; } }); - - tinymce.EditorManager.preInit(); })(tinymce); -var tinyMCE = window.tinyMCE = tinymce.EditorManager; (function(tinymce) { - var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher; - var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit; - var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager; - var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode; + // Shorten these names + var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, + Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isGecko = tinymce.isGecko, + isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is, + ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, + inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode; tinymce.create('tinymce.Editor', { Editor : function(id, s) { @@ -8836,11 +9110,9 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; custom_undo_redo_keyboard_shortcuts : 1, custom_undo_redo_restore_selection : 1, custom_undo_redo : 1, - doctype : '', + doctype : tinymce.isIE6 ? '' : '', // Use old doctype on IE 6 to avoid horizontal scroll visual_table_class : 'mceItemTable', visual : 1, - inline_styles : true, - convert_fonts_to_spans : true, font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', apply_source_formatting : 1, directionality : 'ltr', @@ -8854,14 +9126,15 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; indentation : '30px', keep_styles : 1, fix_table_elements : 1, - removeformat_selector : 'span,b,strong,em,i,font,u,strike' + inline_styles : 1, + convert_fonts_to_spans : true }, s); t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, { base_uri : tinyMCE.baseURI }); - t.baseURI = EditorManager.baseURI; + t.baseURI = tinymce.baseURI; // Call setup t.execCallback('setup', t); @@ -8878,21 +9151,12 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; return; } - // Force strict loading mode if render us called by user and not internally - if (!nst) { - s.strict_loading_mode = 1; - tinyMCE.settings = s; - } + tinyMCE.settings = s; // Element not found, then skip initialization if (!t.getElement()) return; - if (s.strict_loading_mode) { - sl.settings.strict_mode = s.strict_loading_mode; - tinymce.DOM.settings.strict = 1; - } - // Add hidden input for non input elements inside form elements if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form')) DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id); @@ -8942,7 +9206,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; n._mceOldSubmit = n.submit; n.submit = function() { // Save all instances - EditorManager.triggerSave(); + tinymce.triggerSave(); t.isNotDirty = 1; return t.formElement._mceOldSubmit(t.formElement); @@ -8963,8 +9227,8 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; each(explode(s.plugins), function(p) { if (p && p.charAt(0) != '-' && !PluginManager.urls[p]) { - // Skip safari plugin for other browsers - if (!isWebKit && p == 'safari') + // Skip safari plugin, since it is removed as of 3.3b1 + if (p == 'safari') return; PluginManager.load(p, 'plugins/' + p + '/editor_plugin' + tinymce.suffix + '.js'); @@ -8984,7 +9248,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; init : function() { var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re; - EditorManager.add(t); + tinymce.add(t); if (s.theme) { s.theme = s.theme.replace(/-/, ''); @@ -9022,23 +9286,15 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; t.controlManager = new tinymce.ControlManager(t); - t.undoManager = new tinymce.UndoManager(t); - - // Pass through - t.undoManager.onAdd.add(function(um, l) { - if (!l.initial) - return t.onChange.dispatch(t, l, um); - }); - - t.undoManager.onUndo.add(function(um, l) { - return t.onUndo.dispatch(t, l, um); - }); - - t.undoManager.onRedo.add(function(um, l) { - return t.onRedo.dispatch(t, l, um); - }); - if (s.custom_undo_redo) { + // Add initial undo level + t.onBeforeExecCommand.add(function(ed, cmd, ui, val, a) { + if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo)) { + if (!t.undoManager.hasUndo()) + t.undoManager.add(); + } + }); + t.onExecCommand.add(function(ed, cmd, ui, val, a) { if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo)) t.undoManager.add(); @@ -9113,7 +9369,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; if (s.document_base_url != tinymce.documentBaseURL) t.iframeHTML += ''; - t.iframeHTML += ''; + t.iframeHTML += ''; if (tinymce.relaxedDomain) t.iframeHTML += ''; @@ -9202,19 +9458,107 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; hex_colors : s.force_hex_style_colors, class_filter : s.class_filter, update_styles : 1, - fix_ie_paragraphs : 1 + fix_ie_paragraphs : 1, + valid_styles : s.valid_styles }); + t.schema = new tinymce.dom.Schema(); + t.serializer = new tinymce.dom.Serializer(extend(s, { valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements, - dom : t.dom + dom : t.dom, + schema : t.schema })); t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer); + t.formatter = new tinymce.Formatter(this); + + // Register default formats + t.formatter.register({ + alignleft : [ + {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}}, + {selector : 'img,table', styles : {'float' : 'left'}} + ], + + aligncenter : [ + {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}}, + {selector : 'img', styles : {display : 'block', marginLeft : 'auto', marginRight : 'auto'}}, + {selector : 'table', styles : {marginLeft : 'auto', marginRight : 'auto'}} + ], + + alignright : [ + {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}}, + {selector : 'img,table', styles : {'float' : 'right'}} + ], + + alignfull : [ + {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'justify'}} + ], + + bold : [ + {inline : 'strong'}, + {inline : 'span', styles : {fontWeight : 'bold'}}, + {inline : 'b'} + ], + + italic : [ + {inline : 'em'}, + {inline : 'span', styles : {fontStyle : 'italic'}}, + {inline : 'i'} + ], + + underline : [ + {inline : 'span', styles : {textDecoration : 'underline'}, exact : true}, + {inline : 'u'} + ], + + strikethrough : [ + {inline : 'span', styles : {textDecoration : 'line-through'}, exact : true}, + {inline : 'u'} + ], + + forecolor : {inline : 'span', styles : {color : '%value'}}, + hilitecolor : {inline : 'span', styles : {backgroundColor : '%value'}}, + fontname : {inline : 'span', styles : {fontFamily : '%value'}}, + fontsize : {inline : 'span', styles : {fontSize : '%value'}}, + blockquote : {block : 'blockquote', wrapper : 1}, + + removeformat : [ + {selector : 'b,strong,em,i,font,u,strike', remove : 'all', split : true, expand : false, block_expand : true, deep : true}, + {selector : 'span', attributes : ['style', 'class'], remove : 'empty', split : true, expand : false, deep : true}, + {selector : '*', attributes : ['style', 'class'], split : false, expand : false, deep : true} + ] + }); + + // Register default block formats + each('p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp'.split(/\s/), function(name) { + t.formatter.register(name, {block : name}); + }); + + // Register user defined formats + t.formatter.register(t.settings.formats); + + t.undoManager = new tinymce.UndoManager(t); + + // Pass through + t.undoManager.onAdd.add(function(um, l) { + if (!l.initial) + return t.onChange.dispatch(t, l, um); + }); + + t.undoManager.onUndo.add(function(um, l) { + return t.onUndo.dispatch(t, l, um); + }); + + t.undoManager.onRedo.add(function(um, l) { + return t.onRedo.dispatch(t, l, um); + }); + t.forceBlocks = new tinymce.ForceBlocks(t, { forced_root_block : s.forced_root_block }); + t.editorCommands = new tinymce.EditorCommands(t); // Pass through @@ -9254,7 +9598,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; } else n = 'div'; - o.content = o.content.replace(new RegExp('<(' + v + ')([^>]*)>', 'g'), '<' + n + ' mce_name="$1"$2>'); + o.content = o.content.replace(new RegExp('<(' + v + ')([^>]*)>', 'g'), '<' + n + ' _mce_name="$1"$2>'); o.content = o.content.replace(new RegExp('', 'g'), ''); }); }; @@ -9337,12 +9681,6 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; }; } - if (s.convert_fonts_to_spans) - t._convertFonts(); - - if (s.inline_styles) - t._convertInlineElements(); - if (s.cleanup_callback) { t.onBeforeSetContent.add(function(ed, o) { o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o); @@ -9399,7 +9737,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; var pn = n.parentNode; if (ed.dom.isBlock(pn) && pn.lastChild === n) - ed.dom.add(pn, 'br', {'mce_bogus' : 1}); + ed.dom.add(pn, 'br', {'_mce_bogus' : 1}); }); }; @@ -9430,7 +9768,6 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')}); t.startContent = t.getContent({format : 'raw'}); - t.undoManager.add({initial : true}); t.initialized = true; t.onInit.dispatch(t); @@ -9449,7 +9786,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; // Handle auto focus if (s.auto_focus) { setTimeout(function () { - var ed = EditorManager.get(s.auto_focus); + var ed = tinymce.get(s.auto_focus); ed.selection.select(ed.getBody(), 1); ed.selection.collapse(1); @@ -9466,22 +9803,20 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; var oed, t = this, ce = t.settings.content_editable; if (!sf) { - // Is not content editable or the selection is outside the area in IE - // the IE statement is needed to avoid bluring if element selections inside layers since - // the layer is like it's own document in IE - if (!ce && (!isIE || t.selection.getNode().ownerDocument != t.getDoc())) + // Is not content editable + if (!ce) t.getWin().focus(); } - if (EditorManager.activeEditor != t) { - if ((oed = EditorManager.activeEditor) != null) + if (tinymce.activeEditor != t) { + if ((oed = tinymce.activeEditor) != null) oed.onDeactivate.dispatch(oed, t); t.onActivate.dispatch(t, oed); } - EditorManager._setActive(t); + tinymce._setActive(t); }, execCallback : function(n) { @@ -9508,7 +9843,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; }, translate : function(s) { - var c = this.settings.language || 'en', i18n = EditorManager.i18n; + var c = this.settings.language || 'en', i18n = tinymce.i18n; if (!s) return ''; @@ -9519,7 +9854,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; }, getLang : function(n, dv) { - return EditorManager.i18n[(this.settings.language || 'en') + '.' + n] || (is(dv) ? dv : '{#' + n + '}'); + return tinymce.i18n[(this.settings.language || 'en') + '.' + n] || (is(dv) ? dv : '{#' + n + '}'); }, getParam : function(n, dv, ty) { @@ -9551,10 +9886,22 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; // Fix for bug #1896577 it seems that this can not be fired while the editor is loading if (t.initialized) { + o = o || {}; + n = isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n; // Fix for IE initial state + + // Get parents and add them to object + o.parents = []; + t.dom.getParent(n, function(node) { + if (node.nodeName == 'BODY') + return true; + + o.parents.push(node); + }); + t.onNodeChange.dispatch( t, o ? o.controlManager || t.controlManager : t.controlManager, - isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n, // Fix for IE initial state + n, s.isCollapsed(), o ); @@ -9697,7 +10044,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; t.onExecCommand.dispatch(t, cmd, ui, val, a); }, - queryCommandState : function(c) { + queryCommandState : function(cmd) { var t = this, o, s; // Is hidden then return undefined @@ -9705,7 +10052,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; return; // Registred commands - if (o = t.queryStateCommands[c]) { + if (o = t.queryStateCommands[cmd]) { s = o.func.call(o.scope); // Fall though on true @@ -9714,13 +10061,13 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; } // Registred commands - o = t.editorCommands.queryCommandState(c); + o = t.editorCommands.queryCommandState(cmd); if (o !== -1) return o; // Browser commands try { - return this.getDoc().queryCommandState(c); + return this.getDoc().queryCommandState(cmd); } catch (ex) { // Fails sometimes see bug: 1896577 } @@ -9863,7 +10210,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content // It will also be impossible to place the caret in the editor unless there is a BR element present if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) { - o.content = t.dom.setHTML(t.getBody(), '
'); + o.content = t.dom.setHTML(t.getBody(), '
'); o.format = 'raw'; } @@ -10032,7 +10379,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; // Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command t.onExecCommand.listeners = []; - EditorManager.remove(t); + tinymce.remove(t); DOM.remove(e); }, @@ -10159,7 +10506,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; each(ed.dom.select('img'), function(e) { var v; - if (v = e.getAttribute('mce_src')) + if (v = e.getAttribute('_mce_src')) e.src = t.documentBaseURI.toAbsolute(v); }) });*/ @@ -10169,7 +10516,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; e = e.target; - if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src'))) + if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('_mce_src'))) e.src = t.documentBaseURI.toAbsolute(v); }); } @@ -10210,6 +10557,19 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; t.onMouseDown.add(setOpts); } + // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250 + // WebKit can't even do simple things like selecting an image + // This also fixes so it's possible to select mceItemAnchors + if (tinymce.isWebKit) { + t.onClick.add(function(ed, e) { + e = e.target; + + // Needs tobe the setBaseAndExtend or it will fail to select floated images + if (e.nodeName == 'IMG' || (e.nodeName == 'A' && t.dom.hasClass(e, 'mceItemAnchor'))) + t.selection.getSel().setBaseAndExtent(e, 0, e, 1); + }); + } + // Add node change handlers t.onMouseUp.add(t.nodeChanged); t.onClick.add(t.nodeChanged); @@ -10241,7 +10601,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; // BlockFormat shortcuts keys for (i=1; i<=6; i++) - t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, '']); + t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, 'h' + i]); t.addShortcut('ctrl+7', '', ['FormatBlock', false, '

']); t.addShortcut('ctrl+8', '', ['FormatBlock', false, '

']); @@ -10347,7 +10707,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; case 8: // Fix IE control + backspace browser bug if (t.selection.getRng().item) { - t.selection.getRng().item(0).removeNode(); + ed.dom.remove(t.selection.getRng().item(0)); return Event.cancel(e); } } @@ -10377,43 +10737,21 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; t.undoManager.add(); }; - // Add undo level on editor blur - if (tinymce.isIE) { - t.dom.bind(t.getWin(), 'blur', function(e) { - var n; - - // Check added for fullscreen bug - if (t.selection) { - n = t.selection.getNode(); - - // Add undo level is selection was lost to another document - if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc()) - addUndo(); - } - }); - } else { - t.dom.bind(t.getDoc(), 'blur', function() { - if (t.selection && !t.removed) - addUndo(); - }); - } - - t.onMouseDown.add(addUndo); + t.dom.bind(t.getDoc(), 'focusout', function(e) { + if (!t.removed && t.undoManager.typing) + addUndo(); + }); t.onKeyUp.add(function(ed, e) { - if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey) { - t.undoManager.typing = 0; - t.undoManager.add(); - } + if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey) + addUndo(); }); t.onKeyDown.add(function(ed, e) { // Is caracter positon keys if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45) { - if (t.undoManager.typing) { - t.undoManager.add(); - t.undoManager.typing = 0; - } + if (t.undoManager.typing) + addUndo(); return; } @@ -10423,137 +10761,14 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; t.undoManager.typing = 1; } }); - } - }, - - _convertInlineElements : function() { - var t = this, s = t.settings, dom = t.dom, v, e, na, st, sp; - - function convert(ed, o) { - if (!s.inline_styles) - return; - - if (o.get) { - each(t.dom.select('table,u,strike', o.node), function(n) { - switch (n.nodeName) { - case 'TABLE': - if (v = dom.getAttrib(n, 'height')) { - dom.setStyle(n, 'height', v); - dom.setAttrib(n, 'height', ''); - } - break; - - case 'U': - case 'STRIKE': - //sp = dom.create('span', {style : dom.getAttrib(n, 'style')}); - n.style.textDecoration = n.nodeName == 'U' ? 'underline' : 'line-through'; - dom.setAttrib(n, 'mce_style', ''); - dom.setAttrib(n, 'mce_name', 'span'); - break; - } - }); - } else if (o.set) { - each(t.dom.select('table,span', o.node).reverse(), function(n) { - if (n.nodeName == 'TABLE') { - if (v = dom.getStyle(n, 'height')) - dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, '')); - } else { - // Convert spans to elements - if (n.style.textDecoration == 'underline') - na = 'u'; - else if (n.style.textDecoration == 'line-through') - na = 'strike'; - else - na = ''; - - if (na) { - n.style.textDecoration = ''; - dom.setAttrib(n, 'mce_style', ''); - - e = dom.create(na, { - style : dom.getAttrib(n, 'style') - }); - - dom.replace(e, n, 1); - } - } - }); - } - }; - - t.onPreProcess.add(convert); - if (!s.cleanup_on_startup) { - t.onSetContent.add(function(ed, o) { - if (o.initial) - convert(t, {node : t.getBody(), set : 1}); + t.onMouseDown.add(function() { + if (t.undoManager.typing) + addUndo(); }); } }, - _convertFonts : function() { - var t = this, s = t.settings, dom = t.dom, fz, fzn, sl, cl; - - // No need - if (!s.inline_styles) - return; - - // Font pt values and font size names - fz = [8, 10, 12, 14, 18, 24, 36]; - fzn = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large']; - - if (sl = s.font_size_style_values) - sl = explode(sl); - - if (cl = s.font_size_classes) - cl = explode(cl); - - function process(no) { - var n, sp, nl, x; - - // Keep unit tests happy - if (!s.inline_styles) - return; - - nl = t.dom.select('font', no); - for (x = nl.length - 1; x >= 0; x--) { - n = nl[x]; - - sp = dom.create('span', { - style : dom.getAttrib(n, 'style'), - 'class' : dom.getAttrib(n, 'class') - }); - - dom.setStyles(sp, { - fontFamily : dom.getAttrib(n, 'face'), - color : dom.getAttrib(n, 'color'), - backgroundColor : n.style.backgroundColor - }); - - if (n.size) { - if (sl) - dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]); - else - dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]); - } - - dom.setAttrib(sp, 'mce_style', ''); - dom.replace(sp, n, 1); - } - }; - - // Run on cleanup - t.onPreProcess.add(function(ed, o) { - if (o.get) - process(o.node); - }); - - t.onSetContent.add(function(ed, o) { - if (o.initial) - process(o.node); - }); - }, - _isHidden : function() { var s; @@ -10617,2615 +10832,2977 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager; } }); })(tinymce); + (function(tinymce) { - var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit; + // Added for compression purposes + var each = tinymce.each, undefined, TRUE = true, FALSE = false; - tinymce.create('tinymce.EditorCommands', { - EditorCommands : function(ed) { - this.editor = ed; - }, + tinymce.EditorCommands = function(editor) { + var dom = editor.dom, + selection = editor.selection, + commands = {state: {}, exec : {}, value : {}}, + settings = editor.settings, + bookmark; - execCommand : function(cmd, ui, val) { - var t = this, ed = t.editor, f; + function execCommand(command, ui, value) { + var func; - switch (cmd) { - // Ignore these - case 'mceResetDesignMode': - case 'mceBeginUndoLevel': - return true; + command = command.toLowerCase(); + if (func = commands.exec[command]) { + func(command, ui, value); + return TRUE; + } - // Ignore these - case 'unlink': - t.UnLink(); - return true; + return FALSE; + }; - // Bundle these together - case 'JustifyLeft': - case 'JustifyCenter': - case 'JustifyRight': - case 'JustifyFull': - t.mceJustify(cmd, cmd.substring(7).toLowerCase()); - return true; + function queryCommandState(command) { + var func; - default: - f = this[cmd]; + command = command.toLowerCase(); + if (func = commands.state[command]) + return func(command); - if (f) { - f.call(this, ui, val); - return true; - } - } + return -1; + }; - return false; - }, + function queryCommandValue(command) { + var func; - Indent : function() { - var ed = this.editor, d = ed.dom, s = ed.selection, e, iv, iu; + command = command.toLowerCase(); + if (func = commands.value[command]) + return func(command); - // Setup indent level - iv = ed.settings.indentation; - iu = /[a-z%]+$/i.exec(iv); - iv = parseInt(iv); + return FALSE; + }; + + function addCommands(command_list, type) { + type = type || 'exec'; - if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) { - each(s.getSelectedBlocks(), function(e) { - d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu); + each(command_list, function(callback, command) { + each(command.toLowerCase().split(','), function(command) { + commands[type][command] = callback; }); + }); + }; - return; - } + // Expose public methods + tinymce.extend(this, { + execCommand : execCommand, + queryCommandState : queryCommandState, + queryCommandValue : queryCommandValue, + addCommands : addCommands + }); - ed.getDoc().execCommand('Indent', false, null); + // Private methods - if (isIE) { - d.getParent(s.getNode(), function(n) { - if (n.nodeName == 'BLOCKQUOTE') { - n.dir = n.style.cssText = ''; - } - }); - } - }, + function execNativeCommand(command, ui, value) { + if (ui === undefined) + ui = FALSE; - Outdent : function() { - var ed = this.editor, d = ed.dom, s = ed.selection, e, v, iv, iu; + if (value === undefined) + value = null; - // Setup indent level - iv = ed.settings.indentation; - iu = /[a-z%]+$/i.exec(iv); - iv = parseInt(iv); + return editor.getDoc().execCommand(command, ui, value); + }; - if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) { - each(s.getSelectedBlocks(), function(e) { - v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv); - d.setStyle(e, 'paddingLeft', v ? v + iu : ''); - }); + function isFormatMatch(name) { + return editor.formatter.match(name); + }; - return; - } + function toggleFormat(name, value) { + editor.formatter.toggle(name, value ? {value : value} : undefined); + }; - ed.getDoc().execCommand('Outdent', false, null); - }, + function storeSelection(type) { + bookmark = selection.getBookmark(type); + }; -/* - mceSetAttribute : function(u, v) { - var ed = this.editor, d = ed.dom, e; + function restoreSelection() { + selection.moveToBookmark(bookmark); + }; - if (e = d.getParent(ed.selection.getNode(), d.isBlock)) - d.setAttrib(e, v.name, v.value); - }, -*/ - mceSetContent : function(u, v) { - this.editor.setContent(v); - }, + // Add execCommand overrides + addCommands({ + // Ignore these, added for compatibility + 'mceResetDesignMode,mceBeginUndoLevel' : function() {}, - mceToggleVisualAid : function() { - var ed = this.editor; + // Add undo manager logic + 'mceEndUndoLevel,mceAddUndoLevel' : function() { + editor.undoManager.add(); + }, - ed.hasVisual = !ed.hasVisual; - ed.addVisual(); - }, + 'Cut,Copy,Paste' : function(command) { + var doc = editor.getDoc(), failed; - mceReplaceContent : function(u, v) { - var s = this.editor.selection; + // Try executing the native command + try { + execNativeCommand(command); + } catch (ex) { + // Command failed + failed = TRUE; + } - s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'}))); - }, + // Present alert message about clipboard access not being available + if (failed || !doc.queryCommandEnabled(command)) { + if (tinymce.isGecko) { + editor.windowManager.confirm(editor.getLang('clipboard_msg'), function(state) { + if (state) + open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', '_blank'); + }); + } else + editor.windowManager.alert(editor.getLang('clipboard_no_support')); + } + }, - mceInsertLink : function(u, v) { - var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'a'); + // Override unlink command + unlink : function(command) { + if (selection.isCollapsed()) + selection.select(selection.getNode()); - if (tinymce.is(v, 'string')) - v = {href : v}; + execNativeCommand(command); + selection.collapse(FALSE); + }, - function set(e) { - each(v, function(v, k) { - ed.dom.setAttrib(e, k, v); - }); - }; + // Override justify commands to use the text formatter engine + 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) { + var align = command.substring(7); - if (!e) { - ed.execCommand('CreateLink', false, 'javascript:mctmp(0);'); - each(ed.dom.select('a[href=javascript:mctmp(0);]'), function(e) { - set(e); + // Remove all other alignments first + each('left,center,right,full'.split(','), function(name) { + if (align != name) + editor.formatter.remove('align' + name); }); - } else { - if (v.href) - set(e); - else - ed.dom.remove(e, 1); - } - }, - UnLink : function() { - var ed = this.editor, s = ed.selection; - - if (s.isCollapsed()) - s.select(s.getNode()); - - ed.getDoc().execCommand('unlink', false, null); - s.collapse(0); - }, + toggleFormat('align' + align); + }, - FontName : function(u, v) { - var t = this, ed = t.editor, s = ed.selection, e; + // Override list commands to fix WebKit bug + 'InsertUnorderedList,InsertOrderedList' : function(command) { + var listElm, listParent; - if (!v) { - if (s.isCollapsed()) - s.select(s.getNode()); - } else { - if (ed.settings.convert_fonts_to_spans) - t._applyInlineStyle('span', {style : {fontFamily : v}}); - else - ed.getDoc().execCommand('FontName', false, v); - } - }, + execNativeCommand(command); - FontSize : function(u, v) { - var ed = this.editor, s = ed.settings, fc, fs; + // WebKit produces lists within block elements so we need to split them + // we will replace the native list creation logic to custom logic later on + // TODO: Remove this when the list creation logic is removed + listElm = dom.getParent(selection.getNode(), 'ol,ul'); + if (listElm) { + listParent = listElm.parentNode; - // Use style options instead - if (s.convert_fonts_to_spans && v >= 1 && v <= 7) { - fs = tinymce.explode(s.font_size_style_values); - fc = tinymce.explode(s.font_size_classes); + // If list is within a text block then split that block + if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) { + storeSelection(); + dom.split(listParent, listElm); + restoreSelection(); + } + } + }, - if (fc) - v = fc[v - 1] || v; - else - v = fs[v - 1] || v; - } + // Override commands to use the text formatter engine + 'Bold,Italic,Underline,Strikethrough' : function(command) { + toggleFormat(command); + }, - if (v >= 1 && v <= 7) - ed.getDoc().execCommand('FontSize', false, v); - else - this._applyInlineStyle('span', {style : {fontSize : v}}); - }, + // Override commands to use the text formatter engine + 'ForeColor,HiliteColor,FontName' : function(command, ui, value) { + toggleFormat(command, value); + }, - queryCommandValue : function(c) { - var f = this['queryValue' + c]; + FontSize : function(command, ui, value) { + var fontClasses, fontSizes; - if (f) - return f.call(this, c); + // Convert font size 1-7 to styles + if (value >= 1 && value <= 7) { + fontSizes = tinymce.explode(settings.font_size_style_values); + fontClasses = tinymce.explode(settings.font_size_classes); - return false; - }, + if (fontClasses) + value = fontClasses[value - 1] || value; + else + value = fontSizes[value - 1] || value; + } - queryCommandState : function(cmd) { - var f; + toggleFormat(command, value); + }, - switch (cmd) { - // Bundle these together - case 'JustifyLeft': - case 'JustifyCenter': - case 'JustifyRight': - case 'JustifyFull': - return this.queryStateJustify(cmd, cmd.substring(7).toLowerCase()); + RemoveFormat : function(command) { + editor.formatter.remove(command); + }, - default: - if (f = this['queryState' + cmd]) - return f.call(this, cmd); - } + mceBlockQuote : function(command) { + toggleFormat('blockquote'); + }, - return -1; - }, + FormatBlock : function(command, ui, value) { + return toggleFormat(value); + }, - _queryState : function(c) { - try { - return this.editor.getDoc().queryCommandState(c); - } catch (ex) { - // Ignore exception - } - }, + mceCleanup : function() { + storeSelection(); + editor.setContent(editor.getContent({cleanup : TRUE}), {cleanup : TRUE}); + restoreSelection(); + }, - _queryVal : function(c) { - try { - return this.editor.getDoc().queryCommandValue(c); - } catch (ex) { - // Ignore exception - } - }, + mceRemoveNode : function(command, ui, value) { + var node = value || selection.getNode(); - queryValueFontSize : function() { - var ed = this.editor, v = 0, p; + // Make sure that the body node isn't removed + if (node != ed.getBody()) { + storeSelection(); + editor.dom.remove(node, TRUE); + restoreSelection(); + } + }, - if (p = ed.dom.getParent(ed.selection.getNode(), 'span')) - v = p.style.fontSize; + mceSelectNodeDepth : function(command, ui, value) { + var counter = 0; - if (!v && (isOpera || isWebKit)) { - if (p = ed.dom.getParent(ed.selection.getNode(), 'font')) - v = p.size; + dom.getParent(selection.getNode(), function(node) { + if (node.nodeType == 1 && counter++ == value) { + selection.select(node); + return FALSE; + } + }, editor.getBody()); + }, - return v; - } + mceSelectNode : function(command, ui, value) { + selection.select(value); + }, - return v || this._queryVal('FontSize'); - }, + mceInsertContent : function(command, ui, value) { + selection.setContent(value); + }, - queryValueFontName : function() { - var ed = this.editor, v = 0, p; + mceInsertRawHTML : function(command, ui, value) { + selection.setContent('tiny_mce_marker'); + editor.setContent(editor.getContent().replace(/tiny_mce_marker/g, value)); + }, - if (p = ed.dom.getParent(ed.selection.getNode(), 'font')) - v = p.face; + mceSetContent : function(command, ui, value) { + editor.setContent(value); + }, - if (p = ed.dom.getParent(ed.selection.getNode(), 'span')) - v = p.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase(); + 'Indent,Outdent' : function(command) { + var intentValue, indentUnit, value; - if (!v) - v = this._queryVal('FontName'); + // Setup indent level + intentValue = settings.indentation; + indentUnit = /[a-z%]+$/i.exec(intentValue); + intentValue = parseInt(intentValue); - return v; - }, + if (!queryCommandState('InsertUnorderedList') && !queryCommandState('InsertOrderedList')) { + each(selection.getSelectedBlocks(), function(element) { + if (command == 'outdent') { + value = Math.max(0, parseInt(element.style.paddingLeft || 0) - intentValue); + dom.setStyle(element, 'paddingLeft', value ? value + indentUnit : ''); + } else + dom.setStyle(element, 'paddingLeft', (parseInt(element.style.paddingLeft || 0) + intentValue) + indentUnit); + }); + } else + execNativeCommand(command); + }, - mceJustify : function(c, v) { - var ed = this.editor, se = ed.selection, n = se.getNode(), nn = n.nodeName, bl, nb, dom = ed.dom, rm; + mceRepaint : function() { + var bookmark; - if (ed.settings.inline_styles && this.queryStateJustify(c, v)) - rm = 1; + if (tinymce.isGecko) { + try { + storeSelection(TRUE); - bl = dom.getParent(n, ed.dom.isBlock); + if (selection.getSel()) + selection.getSel().selectAllChildren(editor.getBody()); - if (nn == 'IMG') { - if (v == 'full') - return; + selection.collapse(TRUE); + restoreSelection(); + } catch (ex) { + // Ignore + } + } + }, - if (rm) { - if (v == 'center') - dom.setStyle(bl || n.parentNode, 'textAlign', ''); + mceToggleFormat : function(command, ui, value) { + editor.formatter.toggle(value); + }, - dom.setStyle(n, 'float', ''); - this.mceRepaint(); - return; - } + InsertHorizontalRule : function() { + selection.setContent('
'); + }, - if (v == 'center') { - // Do not change table elements - if (bl && /^(TD|TH)$/.test(bl.nodeName)) - bl = 0; + mceToggleVisualAid : function() { + editor.hasVisual = !editor.hasVisual; + editor.addVisual(); + }, - if (!bl || bl.childNodes.length > 1) { - nb = dom.create('p'); - nb.appendChild(n.cloneNode(false)); + mceReplaceContent : function(command, ui, value) { + selection.setContent(value.replace(/\{\$selection\}/g, selection.getContent({format : 'text'}))); + }, - if (bl) - dom.insertAfter(nb, bl); - else - dom.insertAfter(nb, n); + mceInsertLink : function(command, ui, value) { + var link = dom.getParent(selection.getNode(), 'a'); - dom.remove(n); - n = nb.firstChild; - bl = nb; - } + if (tinymce.is(value, 'string')) + value = {href : value}; - dom.setStyle(bl, 'textAlign', v); - dom.setStyle(n, 'float', ''); + if (!link) { + execNativeCommand('CreateLink', FALSE, 'javascript:mctmp(0);'); + each(dom.select('a[href=javascript:mctmp(0);]'), function(link) { + dom.setAttribs(link, value); + }); } else { - dom.setStyle(n, 'float', v); - dom.setStyle(bl || n.parentNode, 'textAlign', ''); + if (value.href) + dom.setAttribs(link, value); + else + ed.dom.remove(link, TRUE); } - - this.mceRepaint(); - return; } + }); - // Handle the alignment outselfs, less quirks in all browsers - if (ed.settings.inline_styles && ed.settings.forced_root_block) { - if (rm) - v = ''; - - each(se.getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) { - dom.setAttrib(e, 'align', ''); - dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v); - }); + // Add queryCommandState overrides + addCommands({ + // Override justify commands + 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) { + return isFormatMatch('align' + command.substring(7)); + }, - return; - } else if (!rm) - ed.getDoc().execCommand(c, false, null); - - if (ed.settings.inline_styles) { - if (rm) { - dom.getParent(ed.selection.getNode(), function(n) { - if (n.style && n.style.textAlign) - dom.setStyle(n, 'textAlign', ''); - }); + 'Bold,Italic,Underline,Strikethrough' : function(command) { + return isFormatMatch(command); + }, - return; - } + mceBlockQuote : function() { + return isFormatMatch('blockquote'); + }, - each(dom.select('*'), function(n) { - var v = n.align; + Outdent : function() { + var node; - if (v) { - if (v == 'full') - v = 'justify'; + if (settings.inline_styles) { + if ((node = dom.getParent(selection.getStart(), dom.isBlock)) && parseInt(node.style.paddingLeft) > 0) + return TRUE; - dom.setStyle(n, 'textAlign', v); - dom.setAttrib(n, 'align', ''); - } - }); - } - }, + if ((node = dom.getParent(selection.getEnd(), dom.isBlock)) && parseInt(node.style.paddingLeft) > 0) + return TRUE; + } - mceSetCSSClass : function(u, v) { - this.mceSetStyleInfo(0, {command : 'setattrib', name : 'class', value : v}); - }, + return queryCommandState('InsertUnorderedList') || queryCommandState('InsertOrderedList') || (!settings.inline_styles && !!dom.getParent(selection.getNode(), 'BLOCKQUOTE')); + }, - getSelectedElement : function() { - var t = this, ed = t.editor, dom = ed.dom, se = ed.selection, r = se.getRng(), r1, r2, sc, ec, so, eo, e, sp, ep, re; + 'InsertUnorderedList,InsertOrderedList' : function(command) { + return dom.getParent(selection.getNode(), command == 'insertunorderedlist' ? 'UL' : 'OL'); + } + }, 'state'); - if (se.isCollapsed() || r.item) - return se.getNode(); + // Add queryCommandValue overrides + addCommands({ + 'FontSize,FontName' : function(command) { + var value = 0, parent; - // Setup regexp - re = ed.settings.merge_styles_invalid_parents; - if (tinymce.is(re, 'string')) - re = new RegExp(re, 'i'); + if (parent = dom.getParent(selection.getNode(), 'span')) { + if (command == 'fontsize') + value = parent.style.fontSize; + else + value = parent.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase(); + } - if (isIE) { - r1 = r.duplicate(); - r1.collapse(true); - sc = r1.parentElement(); + return value; + } + }, 'value'); - r2 = r.duplicate(); - r2.collapse(false); - ec = r2.parentElement(); + // Add undo manager logic + if (settings.custom_undo_redo) { + addCommands({ + Undo : function() { + editor.undoManager.undo(); + }, - if (sc != ec) { - r1.move('character', 1); - sc = r1.parentElement(); + Redo : function() { + editor.undoManager.redo(); } + }); + } + }; +})(tinymce); +(function(tinymce) { + var Dispatcher = tinymce.util.Dispatcher; - if (sc == ec) { - r1 = r.duplicate(); - r1.moveToElementText(sc); + tinymce.UndoManager = function(editor) { + var self, index = 0, data = []; - if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0) - return re && re.test(sc.nodeName) ? null : sc; - } - } else { - function getParent(n) { - return dom.getParent(n, '*'); - }; + function getContent() { + return tinymce.trim(editor.getContent({format : 'raw', no_events : 1})); + }; - sc = r.startContainer; - ec = r.endContainer; - so = r.startOffset; - eo = r.endOffset; + return self = { + typing : 0, - if (!r.collapsed) { - if (sc == ec) { - if (so - eo < 2) { - if (sc.hasChildNodes()) { - sp = sc.childNodes[so]; - return re && re.test(sp.nodeName) ? null : sp; - } - } - } - } + onAdd : new Dispatcher(self), + onUndo : new Dispatcher(self), + onRedo : new Dispatcher(self), - if (sc.nodeType != 3 || ec.nodeType != 3) - return null; + add : function(level) { + var i, settings = editor.settings, lastLevel; - if (so == 0) { - sp = getParent(sc); + level = level || {}; + level.content = getContent(); - if (sp && sp.firstChild != sc) - sp = null; + // Add undo level if needed + lastLevel = data[index]; + if (lastLevel && lastLevel.content == level.content) { + if (index > 0 || data.length == 1) + return null; } - if (so == sc.nodeValue.length) { - e = sc.nextSibling; + // Time to compress + if (settings.custom_undo_redo_levels) { + if (data.length > settings.custom_undo_redo_levels) { + for (i = 0; i < data.length - 1; i++) + data[i] = data[i + 1]; - if (e && e.nodeType == 1) - sp = sc.nextSibling; + data.length--; + index = data.length; + } } - if (eo == 0) { - e = ec.previousSibling; + // Get a non intrusive normalized bookmark + level.bookmark = editor.selection.getBookmark(2, true); - if (e && e.nodeType == 1) - ep = e; + // Crop array if needed + if (index < data.length - 1) { + // Treat first level as initial + if (index == 0) + data = []; + else + data.length = index + 1; } - if (eo == ec.nodeValue.length) { - ep = getParent(ec); + data.push(level); + index = data.length - 1; - if (ep && ep.lastChild != ec) - ep = null; - } + self.onAdd.dispatch(self, level); + editor.isNotDirty = 0; - // Same element - if (sp == ep) - return re && sp && re.test(sp.nodeName) ? null : sp; - } + return level; + }, - return null; - }, + undo : function() { + var level, i; - mceSetStyleInfo : function(u, v) { - var t = this, ed = t.editor, d = ed.getDoc(), dom = ed.dom, e, b, s = ed.selection, nn = v.wrapper || 'span', b = s.getBookmark(), re; + if (self.typing) { + self.add(); + self.typing = 0; + } - function set(n, e) { - if (n.nodeType == 1) { - switch (v.command) { - case 'setattrib': - return dom.setAttrib(n, v.name, v.value); + if (index > 0) { + level = data[--index]; - case 'setstyle': - return dom.setStyle(n, v.name, v.value); + editor.setContent(level.content, {format : 'raw'}); + editor.selection.moveToBookmark(level.bookmark); - case 'removeformat': - return dom.setAttrib(n, 'class', ''); - } + self.onUndo.dispatch(self, level); } - }; - // Setup regexp - re = ed.settings.merge_styles_invalid_parents; - if (tinymce.is(re, 'string')) - re = new RegExp(re, 'i'); - - // Set style info on selected element - if ((e = t.getSelectedElement()) && !ed.settings.force_span_wrappers) - set(e, 1); - else { - // Generate wrappers and set styles on them - d.execCommand('FontName', false, '__'); - each(dom.select('span,font'), function(n) { - var sp, e; + return level; + }, - if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') { - sp = dom.create(nn, {mce_new : '1'}); + redo : function() { + var level; - set(sp); + if (index < data.length - 1) { + level = data[++index]; - each (n.childNodes, function(n) { - sp.appendChild(n.cloneNode(true)); - }); + editor.setContent(level.content, {format : 'raw'}); + editor.selection.moveToBookmark(level.bookmark); - dom.replace(sp, n); - } - }); - } + self.onRedo.dispatch(self, level); + } - // Remove wrappers inside new ones - each(dom.select(nn).reverse(), function(n) { - var p = n.parentNode; + return level; + }, - // Check if it's an old span in a new wrapper - if (!dom.getAttrib(n, 'mce_new')) { - // Find new wrapper - p = dom.getParent(n, '*[mce_new]'); + clear : function() { + data = []; + index = self.typing = 0; + }, - if (p) - dom.remove(n, 1); - } - }); + hasUndo : function() { + return index > 0 || self.typing; + }, - // Merge wrappers with parent wrappers - each(dom.select(nn).reverse(), function(n) { - var p = n.parentNode; + hasRedo : function() { + return index < data.length - 1; + } + }; + }; +})(tinymce); - if (!p || !dom.getAttrib(n, 'mce_new')) - return; +(function(tinymce) { + // Shorten names + var Event = tinymce.dom.Event, + isIE = tinymce.isIE, + isGecko = tinymce.isGecko, + isOpera = tinymce.isOpera, + each = tinymce.each, + extend = tinymce.extend, + TRUE = true, + FALSE = false; - if (ed.settings.force_span_wrappers && p.nodeName != 'SPAN') - return; + // Checks if the selection/caret is at the end of the specified block element + function isAtEnd(rng, par) { + var rng2 = par.ownerDocument.createRange(); - // Has parent of the same type and only child - if (p.nodeName == nn.toUpperCase() && p.childNodes.length == 1) - return dom.remove(p, 1); + rng2.setStart(rng.endContainer, rng.endOffset); + rng2.setEndAfter(par); - // Has parent that is more suitable to have the class and only child - if (n.nodeType == 1 && (!re || !re.test(p.nodeName)) && p.childNodes.length == 1) { - set(p); // Set style info on parent instead - dom.setAttrib(n, 'class', ''); - } - }); + // Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element + return rng2.cloneContents().textContent.length == 0; + }; - // Remove empty wrappers - each(dom.select(nn).reverse(), function(n) { - if (dom.getAttrib(n, 'mce_new') || (dom.getAttribs(n).length <= 1 && n.className === '')) { - if (!dom.getAttrib(n, 'class') && !dom.getAttrib(n, 'style')) - return dom.remove(n, 1); + function isEmpty(n) { + n = n.innerHTML; - dom.setAttrib(n, 'mce_new', ''); // Remove mce_new marker - } - }); + n = n.replace(/<(img|hr|table|input|select|textarea)[ \>]/gi, '-'); // Keep these convert them to - chars + n = n.replace(/<[^>]+>/g, ''); // Remove all tags - s.moveToBookmark(b); - }, + return n.replace(/[ \u00a0\t\r\n]+/g, '') == ''; + }; - queryStateJustify : function(c, v) { - var ed = this.editor, n = ed.selection.getNode(), dom = ed.dom; + function splitList(selection, dom, li) { + var listBlock, block; - if (n && n.nodeName == 'IMG') { - if (dom.getStyle(n, 'float') == v) - return 1; + if (isEmpty(li)) { + listBlock = dom.getParent(li, 'ul,ol'); - return n.parentNode.style.textAlign == v; + if (!dom.getParent(listBlock.parentNode, 'ul,ol')) { + dom.split(listBlock, li); + block = dom.create('p', 0, '
'); + dom.replace(block, li); + selection.select(block, 1); } - n = dom.getParent(ed.selection.getStart(), function(n) { - return n.nodeType == 1 && n.style.textAlign; - }); - - if (v == 'full') - v = 'justify'; + return FALSE; + } - if (ed.settings.inline_styles) - return (n && n.style.textAlign == v); + return TRUE; + }; - return this._queryState(c); - }, + tinymce.create('tinymce.ForceBlocks', { + ForceBlocks : function(ed) { + var t = this, s = ed.settings, elm; - ForeColor : function(ui, v) { - var ed = this.editor; + t.editor = ed; + t.dom = ed.dom; + elm = (s.forced_root_block || 'p').toLowerCase(); + s.element = elm.toUpperCase(); - if (ed.settings.convert_fonts_to_spans) { - this._applyInlineStyle('span', {style : {color : v}}); - return; - } else - ed.getDoc().execCommand('ForeColor', false, v); - }, + ed.onPreInit.add(t.setup, t); - HiliteColor : function(ui, val) { - var t = this, ed = t.editor, d = ed.getDoc(); + t.reOpera = new RegExp('(\\u00a0| | )<\/' + elm + '>', 'gi'); + t.rePadd = new RegExp(']+)><\\\/p>|]+)\\\/>|]+)>\\s+<\\\/p>|

<\\\/p>||

\\s+<\\\/p>'.replace(/p/g, elm), 'gi'); + t.reNbsp2BR1 = new RegExp(']+)>[\\s\\u00a0]+<\\\/p>|

[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi'); + t.reNbsp2BR2 = new RegExp('<%p()([^>]+)>( | )<\\\/%p>|<%p>( | )<\\\/%p>'.replace(/%p/g, elm), 'gi'); + t.reBR2Nbsp = new RegExp(']+)>\\s*
\\s*<\\\/p>|

\\s*
\\s*<\\\/p>'.replace(/p/g, elm), 'gi'); - if (ed.settings.convert_fonts_to_spans) { - this._applyInlineStyle('span', {style : {backgroundColor : val}}); - return; - } + function padd(ed, o) { + if (isOpera) + o.content = o.content.replace(t.reOpera, ''); - function set(s) { - if (!isGecko) - return; + o.content = o.content.replace(t.rePadd, '<' + elm + '$1$2$3$4$5$6>\u00a0'); - try { - // Try new Gecko method - d.execCommand("styleWithCSS", 0, s); - } catch (ex) { - // Use old - d.execCommand("useCSS", 0, !s); - } + if (!isIE && !isOpera && o.set) { + // Use   instead of BR in padded paragraphs + o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2>
'); + o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2>
'); + } else + o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0'); }; - if (isGecko || isOpera) { - set(true); - d.execCommand('hilitecolor', false, val); - set(false); - } else - d.execCommand('BackColor', false, val); - }, + ed.onBeforeSetContent.add(padd); + ed.onPostProcess.add(padd); - FormatBlock : function(ui, val) { - var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b; + if (s.forced_root_block) { + ed.onInit.add(t.forceRoots, t); + ed.onSetContent.add(t.forceRoots, t); + ed.onBeforeGetContent.add(t.forceRoots, t); + } + }, - function isBlock(n) { - return /^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName); - }; + setup : function() { + var t = this, ed = t.editor, s = ed.settings, dom = ed.dom, selection = ed.selection; - bl = dom.getParent(s.getNode(), function(n) { - return isBlock(n); - }); + // Force root blocks when typing and when getting output + if (s.forced_root_block) { + ed.onBeforeExecCommand.add(t.forceRoots, t); + ed.onKeyUp.add(t.forceRoots, t); + ed.onPreProcess.add(t.forceRoots, t); + } - // IE has an issue where it removes the parent div if you change format on the paragrah in

Content

- // FF and Opera doesn't change parent DIV elements if you switch format - if (bl) { - if ((isIE && isBlock(bl.parentNode)) || bl.nodeName == 'DIV') { - // Rename block element - nb = ed.dom.create(val); + if (s.force_br_newlines) { + // Force IE to produce BRs on enter + if (isIE) { + ed.onKeyPress.add(function(ed, e) { + var n; - each(dom.getAttribs(bl), function(v) { - dom.setAttrib(nb, v.nodeName, dom.getAttrib(bl, v.nodeName)); + if (e.keyCode == 13 && selection.getNode().nodeName != 'LI') { + selection.setContent('
', {format : 'raw'}); + n = dom.get('__'); + n.removeAttribute('id'); + selection.select(n); + selection.collapse(); + return Event.cancel(e); + } }); - - b = s.getBookmark(); - dom.replace(nb, bl, 1); - s.moveToBookmark(b); - ed.nodeChanged(); - return; } } - val = ed.settings.forced_root_block ? (val || '

') : val; - - if (val.indexOf('<') == -1) - val = '<' + val + '>'; - - if (tinymce.isGecko) - val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1'); - - ed.getDoc().execCommand('FormatBlock', false, val); - }, - - mceCleanup : function() { - var ed = this.editor, s = ed.selection, b = s.getBookmark(); - ed.setContent(ed.getContent()); - s.moveToBookmark(b); - }, - - mceRemoveNode : function(ui, val) { - var ed = this.editor, s = ed.selection, b, n = val || s.getNode(); - - // Make sure that the body node isn't removed - if (n == ed.getBody()) - return; - - b = s.getBookmark(); - ed.dom.remove(n, 1); - s.moveToBookmark(b); - ed.nodeChanged(); - }, - - mceSelectNodeDepth : function(ui, val) { - var ed = this.editor, s = ed.selection, c = 0; + if (!isIE && s.force_p_newlines) { + ed.onKeyPress.add(function(ed, e) { + if (e.keyCode == 13 && !e.shiftKey && !t.insertPara(e)) + Event.cancel(e); + }); - ed.dom.getParent(s.getNode(), function(n) { - if (n.nodeType == 1 && c++ == val) { - s.select(n); - ed.nodeChanged(); - return false; + if (isGecko) { + ed.onKeyDown.add(function(ed, e) { + if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) + t.backspaceDelete(e, e.keyCode == 8); + }); } - }, ed.getBody()); - }, - - mceSelectNode : function(u, v) { - this.editor.selection.select(v); - }, + } - mceInsertContent : function(ui, val) { - this.editor.selection.setContent(val); - }, + // Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973 + if (tinymce.isWebKit) { + function insertBr(ed) { + var rng = selection.getRng(), br, div = dom.create('div', null, ' '), divYPos, vpHeight = dom.getViewPort(ed.getWin()).h; - mceInsertRawHTML : function(ui, val) { - var ed = this.editor; + // Insert BR element + rng.insertNode(br = dom.create('br')); - ed.selection.setContent('tiny_mce_marker'); - ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val)); - }, + // Place caret after BR + rng.setStartAfter(br); + rng.setEndAfter(br); + selection.setRng(rng); - mceRepaint : function() { - var s, b, e = this.editor; + // Could not place caret after BR then insert an nbsp entity and move the caret + if (selection.getSel().focusNode == br.previousSibling) { + selection.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'), br)); + selection.collapse(TRUE); + } - if (tinymce.isGecko) { - try { - s = e.selection; - b = s.getBookmark(true); + // Create a temporary DIV after the BR and get the position as it + // seems like getPos() returns 0 for text nodes and BR elements. + dom.insertAfter(div, br); + divYPos = dom.getPos(div).y; + dom.remove(div); - if (s.getSel()) - s.getSel().selectAllChildren(e.getBody()); + // Scroll to new position, scrollIntoView can't be used due to bug: http://bugs.webkit.org/show_bug.cgi?id=16117 + if (divYPos > vpHeight) // It is not necessary to scroll if the DIV is inside the view port. + ed.getWin().scrollTo(0, divYPos); + }; - s.collapse(true); - s.moveToBookmark(b); - } catch (ex) { - // Ignore - } + ed.onKeyPress.add(function(ed, e) { + if (e.keyCode == 13 && (e.shiftKey || s.force_br_newlines)) { + insertBr(ed); + Event.cancel(e); + } + }); } - }, - queryStateUnderline : function() { - var ed = this.editor, n = ed.selection.getNode(); - - if (n && n.nodeName == 'A') - return false; + // Padd empty inline elements within block elements + // For example:

becomes

 

+ ed.onPreProcess.add(function(ed, o) { + each(dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) { + if (isEmpty(p)) { + each(dom.select('span,em,strong,b,i', o.node), function(n) { + if (!n.hasChildNodes()) { + n.appendChild(ed.getDoc().createTextNode('\u00a0')); + return FALSE; // Break the loop one padding is enough + } + }); + } + }); + }); - return this._queryState('Underline'); - }, + // IE specific fixes + if (isIE) { + // Replaces IE:s auto generated paragraphs with the specified element name + if (s.element != 'P') { + ed.onKeyPress.add(function(ed, e) { + t.lastElm = selection.getNode().nodeName; + }); - queryStateOutdent : function() { - var ed = this.editor, n; + ed.onKeyUp.add(function(ed, e) { + var bl, n = selection.getNode(), b = ed.getBody(); - if (ed.settings.inline_styles) { - if ((n = ed.dom.getParent(ed.selection.getStart(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0) - return true; + if (b.childNodes.length === 1 && n.nodeName == 'P') { + n = dom.rename(n, s.element); + selection.select(n); + selection.collapse(); + ed.nodeChanged(); + } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') { + bl = dom.getParent(n, 'p'); - if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0) - return true; + if (bl) { + dom.rename(bl, s.element); + ed.nodeChanged(); + } + } + }); + } } - - return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList() || (!ed.settings.inline_styles && !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE')); - }, - - queryStateInsertUnorderedList : function() { - return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL'); - }, - - queryStateInsertOrderedList : function() { - return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL'); - }, - - queryStatemceBlockQuote : function() { - return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';}); }, - _applyInlineStyle : function(na, at, op) { - var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh, found; - - na = na.toUpperCase(); - - if (op && op.check_classes && at['class']) - op.check_classes.push(at['class']); - - function removeEmpty() { - each(dom.select(na).reverse(), function(n) { - var c = 0; + find : function(n, t, s) { + var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, FALSE), c = -1; - // Check if there is any attributes - each(dom.getAttribs(n), function(an) { - if (an.nodeName.substring(0, 1) != '_' && dom.getAttrib(n, an.nodeName) != '') { - //console.log(dom.getOuterHTML(n), dom.getAttrib(n, an.nodeName)); - c++; - } - }); + while (n = w.nextNode()) { + c++; - // No attributes then remove the element and keep the children - if (c == 0) - dom.remove(n, 1); - }); - }; + // Index by node + if (t == 0 && n == s) + return c; - function replaceFonts() { - var bm; + // Node by index + if (t == 1 && c == s) + return n; + } - each(dom.select('span,font'), function(n) { - if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline') { - if (!bm) - bm = ed.selection.getBookmark(); + return -1; + }, - at._mce_new = '1'; - dom.replace(dom.create(na, at), n, 1); - } - }); + forceRoots : function(ed, e) { + var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF; + var nx, bl, bp, sp, le, nl = b.childNodes, i, n, eid; - // Remove redundant elements - each(dom.select(na + '[_mce_new]'), function(n) { - function removeStyle(n) { - if (n.nodeType == 1) { - each(at.style, function(v, k) { - dom.setStyle(n, k, ''); - }); + // Fix for bug #1863847 + //if (e && e.keyCode == 13) + // return TRUE; - // Remove spans with the same class or marked classes - if (at['class'] && n.className && op) { - each(op.check_classes, function(c) { - if (dom.hasClass(n, c)) - dom.removeClass(n, c); - }); - } - } - }; + // Wrap non blocks into blocks + for (i = nl.length - 1; i >= 0; i--) { + nx = nl[i]; - // Remove specified style information from child elements - each(dom.select(na, n), removeStyle); + // Ignore internal elements + if (nx.nodeType === 1 && nx.getAttribute('_mce_type')) { + bl = null; + continue; + } - // Remove the specified style information on parent if current node is only child (IE) - if (n.parentNode && n.parentNode.nodeType == 1 && n.parentNode.childNodes.length == 1) - removeStyle(n.parentNode); + // Is text or non block element + if (nx.nodeType === 3 || (!t.dom.isBlock(nx) && nx.nodeType !== 8 && !/^(script|mce:script|style|mce:style)$/i.test(nx.nodeName))) { + if (!bl) { + // Create new block but ignore whitespace + if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) { + // Store selection + if (si == -2 && r) { + if (!isIE) { + // If selection is element then mark it + if (r.startContainer.nodeType == 1 && (n = r.startContainer.childNodes[r.startOffset]) && n.nodeType == 1) { + // Save the id of the selected element + eid = n.getAttribute("id"); + n.setAttribute("id", "__mce"); + } else { + // If element is inside body, might not be the case in contentEdiable mode + if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) { + so = r.startOffset; + eo = r.endOffset; + si = t.find(b, 0, r.startContainer); + ei = t.find(b, 0, r.endContainer); + } + } + } else { + tr = d.body.createTextRange(); + tr.moveToElementText(b); + tr.collapse(1); + bp = tr.move('character', c) * -1; - // Remove the child elements style info if a parent already has it - dom.getParent(n.parentNode, function(pn) { - if (pn.nodeType == 1) { - if (at.style) { - each(at.style, function(v, k) { - var sv; + tr = r.duplicate(); + tr.collapse(1); + sp = tr.move('character', c) * -1; - if (!lo[k] && (sv = dom.getStyle(pn, k))) { - if (sv === v) - dom.setStyle(n, k, ''); + tr = r.duplicate(); + tr.collapse(0); + le = (tr.move('character', c) * -1) - sp; - lo[k] = 1; - } - }); + si = sp - bp; + ei = le; + } } - // Remove spans with the same class or marked classes - if (at['class'] && pn.className && op) { - each(op.check_classes, function(c) { - if (dom.hasClass(pn, c)) - dom.removeClass(n, c); - }); - } + // Uses replaceChild instead of cloneNode since it removes selected attribute from option elements on IE + // See: http://support.microsoft.com/kb/829907 + bl = ed.dom.create(ed.settings.forced_root_block); + nx.parentNode.replaceChild(bl, nx); + bl.appendChild(nx); } - - return false; - }); - - n.removeAttribute('_mce_new'); - }); - - removeEmpty(); - ed.selection.moveToBookmark(bm); - - return !!bm; - }; - - // Create inline elements - ed.focus(); - ed.getDoc().execCommand('FontName', false, 'mceinline'); - replaceFonts(); - - if (kh = t._applyInlineStyle.keyhandler) { - ed.onKeyUp.remove(kh); - ed.onKeyPress.remove(kh); - ed.onKeyDown.remove(kh); - ed.onSetContent.remove(t._applyInlineStyle.chandler); + } else { + if (bl.hasChildNodes()) + bl.insertBefore(nx, bl.firstChild); + else + bl.appendChild(nx); + } + } else + bl = null; // Time to create new block } - if (ed.selection.isCollapsed()) { - // IE will format the current word so this code can't be executed on that browser + // Restore selection + if (si != -2) { if (!isIE) { - each(dom.getParents(ed.selection.getNode(), 'span'), function(n) { - each(at.style, function(v, k) { - var kv; - - if (kv = dom.getStyle(n, k)) { - if (kv == v) { - dom.setStyle(n, k, ''); - found = 2; - return false; - } - - found = 1; - return false; - } - }); - - if (found) - return false; - }); - - if (found == 2) { - bm = ed.selection.getBookmark(); - - removeEmpty(); + bl = b.getElementsByTagName(ed.settings.element)[0]; + r = d.createRange(); - ed.selection.moveToBookmark(bm); + // Select last location or generated block + if (si != -1) + r.setStart(t.find(b, 1, si), so); + else + r.setStart(bl, 0); - // Node change needs to be detached since the onselect event - // for the select box will run the onclick handler after onselect call. Todo: Add a nicer fix! - window.setTimeout(function() { - ed.nodeChanged(); - }, 1); + // Select last location or generated block + if (ei != -1) + r.setEnd(t.find(b, 1, ei), eo); + else + r.setEnd(bl, 0); - return; + if (s) { + s.removeAllRanges(); + s.addRange(r); + } + } else { + try { + r = s.createRange(); + r.moveToElementText(b); + r.collapse(1); + r.moveStart('character', si); + r.moveEnd('character', ei); + r.select(); + } catch (ex) { + // Ignore } } + } else if (!isIE && (n = ed.dom.get('__mce'))) { + // Restore the id of the selected element + if (eid) + n.setAttribute('id', eid); + else + n.removeAttribute('id'); - // Start collecting styles - t._pendingStyles = tinymce.extend(t._pendingStyles || {}, at.style); - - t._applyInlineStyle.chandler = ed.onSetContent.add(function() { - delete t._pendingStyles; - }); + // Move caret before selected element + r = d.createRange(); + r.setStartBefore(n); + r.setEndBefore(n); + se.setRng(r); + } + }, - t._applyInlineStyle.keyhandler = kh = function(e) { - // Use pending styles - if (t._pendingStyles) { - at.style = t._pendingStyles; - delete t._pendingStyles; - } + getParentBlock : function(n) { + var d = this.dom; - if (replaceFonts()) { - ed.onKeyDown.remove(t._applyInlineStyle.keyhandler); - ed.onKeyPress.remove(t._applyInlineStyle.keyhandler); - } + return d.getParent(n, d.isBlock); + }, - if (e.type == 'keyup') - ed.onKeyUp.remove(t._applyInlineStyle.keyhandler); - }; + insertPara : function(e) { + var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body; + var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car; - ed.onKeyDown.add(kh); - ed.onKeyPress.add(kh); - ed.onKeyUp.add(kh); - } else - t._pendingStyles = 0; - } - }); -})(tinymce);(function(tinymce) { - tinymce.create('tinymce.UndoManager', { - index : 0, - data : null, - typing : 0, + // If root blocks are forced then use Operas default behavior since it's really good +// Removed due to bug: #1853816 +// if (se.forced_root_block && isOpera) +// return TRUE; - UndoManager : function(ed) { - var t = this, Dispatcher = tinymce.util.Dispatcher; + // Setup before range + rb = d.createRange(); - t.editor = ed; - t.data = []; - t.onAdd = new Dispatcher(this); - t.onUndo = new Dispatcher(this); - t.onRedo = new Dispatcher(this); - }, + // If is before the first block element and in body, then move it into first block element + rb.setStart(s.anchorNode, s.anchorOffset); + rb.collapse(TRUE); - add : function(l) { - var t = this, i, ed = t.editor, b, s = ed.settings, la; + // Setup after range + ra = d.createRange(); - l = l || {}; - l.content = l.content || ed.getContent({format : 'raw', no_events : 1}); + // If is before the first block element and in body, then move it into first block element + ra.setStart(s.focusNode, s.focusOffset); + ra.collapse(TRUE); - // Add undo level if needed - l.content = l.content.replace(/^\s*|\s*$/g, ''); - la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index]; - if (!l.initial && la && l.content == la.content) - return null; + // Setup start/end points + dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0; + sn = dir ? s.anchorNode : s.focusNode; + so = dir ? s.anchorOffset : s.focusOffset; + en = dir ? s.focusNode : s.anchorNode; + eo = dir ? s.focusOffset : s.anchorOffset; - // Time to compress - if (s.custom_undo_redo_levels) { - if (t.data.length > s.custom_undo_redo_levels) { - for (i = 0; i < t.data.length - 1; i++) - t.data[i] = t.data[i + 1]; + // If selection is in empty table cell + if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) { + if (sn.firstChild.nodeName == 'BR') + dom.remove(sn.firstChild); // Remove BR - t.data.length--; - t.index = t.data.length; + // Create two new block elements + if (sn.childNodes.length == 0) { + ed.dom.add(sn, se.element, null, '
'); + aft = ed.dom.add(sn, se.element, null, '
'); + } else { + n = sn.innerHTML; + sn.innerHTML = ''; + ed.dom.add(sn, se.element, null, n); + aft = ed.dom.add(sn, se.element, null, '
'); } - } - - if (s.custom_undo_redo_restore_selection && !l.initial) - l.bookmark = b = l.bookmark || ed.selection.getBookmark(); - - if (t.index < t.data.length) - t.index++; - // Only initial marked undo levels should be allowed as first item - // This to workaround a bug with Firefox and the blur event - if (t.data.length === 0 && !l.initial) - return null; - - // Add level - t.data.length = t.index + 1; - t.data[t.index++] = l; + // Move caret into the last one + r = d.createRange(); + r.selectNodeContents(aft); + r.collapse(1); + ed.selection.setRng(r); - if (l.initial) - t.index = 0; + return FALSE; + } - // Set initial bookmark use first real undo level - if (t.data.length == 2 && t.data[0].initial) - t.data[0].bookmark = b; - - t.onAdd.dispatch(t, l); - ed.isNotDirty = 0; + // If the caret is in an invalid location in FF we need to move it into the first block + if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) { + sn = en = sn.firstChild; + so = eo = 0; + rb = d.createRange(); + rb.setStart(sn, 0); + ra = d.createRange(); + ra.setStart(en, 0); + } - //console.dir(t.data); + // Never use body as start or end node + sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes + sn = sn.nodeName == "BODY" ? sn.firstChild : sn; + en = en.nodeName == "HTML" ? d.body : en; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes + en = en.nodeName == "BODY" ? en.firstChild : en; - return l; - }, + // Get start and end blocks + sb = t.getParentBlock(sn); + eb = t.getParentBlock(en); + bn = sb ? sb.nodeName : se.element; // Get block name to create - undo : function() { - var t = this, ed = t.editor, l = l, i; + // Return inside list use default browser behavior + if (n = t.dom.getParent(sb, 'li,pre')) { + if (n.nodeName == 'LI') + return splitList(ed.selection, t.dom, n); - if (t.typing) { - t.add(); - t.typing = 0; + return TRUE; } - if (t.index > 0) { - // If undo on last index then take snapshot - if (t.index == t.data.length && t.index > 1) { - i = t.index; - t.typing = 0; - - if (!t.add()) - t.index = i; - - --t.index; - } + // If caption or absolute layers then always generate new blocks within + if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { + bn = se.element; + sb = null; + } - l = t.data[--t.index]; - ed.setContent(l.content, {format : 'raw'}); - ed.selection.moveToBookmark(l.bookmark); + // If caption or absolute layers then always generate new blocks within + if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { + bn = se.element; + eb = null; + } - t.onUndo.dispatch(t, l); + // Use P instead + if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) { + bn = se.element; + sb = eb = null; } - return l; - }, + // Setup new before and after blocks + bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn); + aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn); - redo : function() { - var t = this, ed = t.editor, l = null; + // Remove id from after clone + aft.removeAttribute('id'); - if (t.index < t.data.length - 1) { - l = t.data[++t.index]; - ed.setContent(l.content, {format : 'raw'}); - ed.selection.moveToBookmark(l.bookmark); + // Is header and cursor is at the end, then force paragraph under + if (/^(H[1-6])$/.test(bn) && isAtEnd(r, sb)) + aft = ed.dom.create(se.element); - t.onRedo.dispatch(t, l); - } + // Find start chop node + n = sc = sn; + do { + if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) + break; - return l; - }, + sc = n; + } while ((n = n.previousSibling ? n.previousSibling : n.parentNode)); - clear : function() { - var t = this; + // Find end chop node + n = ec = en; + do { + if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) + break; - t.data = []; - t.index = 0; - t.typing = 0; - t.add({initial : true}); - }, + ec = n; + } while ((n = n.nextSibling ? n.nextSibling : n.parentNode)); - hasUndo : function() { - return this.index != 0 || this.typing; - }, + // Place first chop part into before block element + if (sc.nodeName == bn) + rb.setStart(sc, 0); + else + rb.setStartBefore(sc); - hasRedo : function() { - return this.index < this.data.length - 1; - } - }); -})(tinymce); -(function(tinymce) { - // Shorten names - var Event, isIE, isGecko, isOpera, each, extend; + rb.setEnd(sn, so); + bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari - Event = tinymce.dom.Event; - isIE = tinymce.isIE; - isGecko = tinymce.isGecko; - isOpera = tinymce.isOpera; - each = tinymce.each; - extend = tinymce.extend; + // Place secnd chop part within new block element + try { + ra.setEndAfter(ec); + } catch(ex) { + //console.debug(s.focusNode, s.focusOffset); + } - // Checks if the selection/caret is at the end of the specified block element - function isAtEnd(rng, par) { - var rng2 = par.ownerDocument.createRange(); + ra.setStart(en, eo); + aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari - rng2.setStart(rng.endContainer, rng.endOffset); - rng2.setEndAfter(par); + // Create range around everything + r = d.createRange(); + if (!sc.previousSibling && sc.parentNode.nodeName == bn) { + r.setStartBefore(sc.parentNode); + } else { + if (rb.startContainer.nodeName == bn && rb.startOffset == 0) + r.setStartBefore(rb.startContainer); + else + r.setStart(rb.startContainer, rb.startOffset); + } - // Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element - return rng2.cloneContents().textContent.length == 0; - }; + if (!ec.nextSibling && ec.parentNode.nodeName == bn) + r.setEndAfter(ec.parentNode); + else + r.setEnd(ra.endContainer, ra.endOffset); - function isEmpty(n) { - n = n.innerHTML; + // Delete and replace it with new block elements + r.deleteContents(); - n = n.replace(/<(img|hr|table|input|select|textarea)[ \>]/gi, '-'); // Keep these convert them to - chars - n = n.replace(/<[^>]+>/g, ''); // Remove all tags + if (isOpera) + ed.getWin().scrollTo(0, vp.y); - return n.replace(/[ \t\r\n]+/g, '') == ''; - }; + // Never wrap blocks in blocks + if (bef.firstChild && bef.firstChild.nodeName == bn) + bef.innerHTML = bef.firstChild.innerHTML; - tinymce.create('tinymce.ForceBlocks', { - ForceBlocks : function(ed) { - var t = this, s = ed.settings, elm; + if (aft.firstChild && aft.firstChild.nodeName == bn) + aft.innerHTML = aft.firstChild.innerHTML; - t.editor = ed; - t.dom = ed.dom; - elm = (s.forced_root_block || 'p').toLowerCase(); - s.element = elm.toUpperCase(); + // Padd empty blocks + if (isEmpty(bef)) + bef.innerHTML = '
'; - ed.onPreInit.add(t.setup, t); + function appendStyles(e, en) { + var nl = [], nn, n, i; - t.reOpera = new RegExp('(\\u00a0| | )<\/' + elm + '>', 'gi'); - t.rePadd = new RegExp(']+)><\\\/p>|]+)\\\/>|]+)>\\s+<\\\/p>|

<\\\/p>||

\\s+<\\\/p>'.replace(/p/g, elm), 'gi'); - t.reNbsp2BR1 = new RegExp(']+)>[\\s\\u00a0]+<\\\/p>|

[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi'); - t.reNbsp2BR2 = new RegExp('<%p()([^>]+)>( | )<\\\/%p>|<%p>( | )<\\\/%p>'.replace(/%p/g, elm), 'gi'); - t.reBR2Nbsp = new RegExp(']+)>\\s*
\\s*<\\\/p>|

\\s*
\\s*<\\\/p>'.replace(/p/g, elm), 'gi'); + e.innerHTML = ''; - function padd(ed, o) { - if (isOpera) - o.content = o.content.replace(t.reOpera, ''); + // Make clones of style elements + if (se.keep_styles) { + n = en; + do { + // We only want style specific elements + if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(n.nodeName)) { + nn = n.cloneNode(FALSE); + dom.setAttrib(nn, 'id', ''); // Remove ID since it needs to be unique + nl.push(nn); + } + } while (n = n.parentNode); + } - o.content = o.content.replace(t.rePadd, '<' + elm + '$1$2$3$4$5$6>\u00a0'); + // Append style elements to aft + if (nl.length > 0) { + for (i = nl.length - 1, nn = e; i >= 0; i--) + nn = nn.appendChild(nl[i]); - if (!isIE && !isOpera && o.set) { - // Use   instead of BR in padded paragraphs - o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2>
'); - o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2>
'); + // Padd most inner style element + nl[0].innerHTML = isOpera ? ' ' : '
'; // Extra space for Opera so that the caret can move there + return nl[0]; // Move caret to most inner element } else - o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0'); + e.innerHTML = isOpera ? ' ' : '
'; // Extra space for Opera so that the caret can move there }; - ed.onBeforeSetContent.add(padd); - ed.onPostProcess.add(padd); + // Fill empty afterblook with current style + if (isEmpty(aft)) + car = appendStyles(aft, en); - if (s.forced_root_block) { - ed.onInit.add(t.forceRoots, t); - ed.onSetContent.add(t.forceRoots, t); - ed.onBeforeGetContent.add(t.forceRoots, t); + // Opera needs this one backwards for older versions + if (isOpera && parseFloat(opera.version()) < 9.5) { + r.insertNode(bef); + r.insertNode(aft); + } else { + r.insertNode(aft); + r.insertNode(bef); } - }, - setup : function() { - var t = this, ed = t.editor, s = ed.settings; + // Normalize + aft.normalize(); + bef.normalize(); - // Force root blocks when typing and when getting output - if (s.forced_root_block) { - ed.onKeyUp.add(t.forceRoots, t); - ed.onPreProcess.add(t.forceRoots, t); - } + function first(n) { + return d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, FALSE).nextNode() || n; + }; - if (s.force_br_newlines) { - // Force IE to produce BRs on enter - if (isIE) { - ed.onKeyPress.add(function(ed, e) { - var n, s = ed.selection; + // Move cursor and scroll into view + r = d.createRange(); + r.selectNodeContents(isGecko ? first(car || aft) : car || aft); + r.collapse(1); + s.removeAllRanges(); + s.addRange(r); - if (e.keyCode == 13 && s.getNode().nodeName != 'LI') { - s.setContent('
', {format : 'raw'}); - n = ed.dom.get('__'); - n.removeAttribute('id'); - s.select(n); - s.collapse(); - return Event.cancel(e); - } - }); - } + // scrollIntoView seems to scroll the parent window in most browsers now including FF 3.0b4 so it's time to stop using it and do it our selfs + y = ed.dom.getPos(aft).y; + ch = aft.clientHeight; - return; + // Is element within viewport + if (y < vp.y || y + ch > vp.y + vp.h) { + ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + 25); // Needs to be hardcoded to roughly one line of text if a huge text block is broken into two blocks + //console.debug('SCROLL!', 'vp.y: ' + vp.y, 'y' + y, 'vp.h' + vp.h, 'clientHeight' + aft.clientHeight, 'yyy: ' + (y < vp.y ? y : y - vp.h + aft.clientHeight)); } - if (!isIE && s.force_p_newlines) { -/* ed.onPreProcess.add(function(ed, o) { - each(ed.dom.select('br', o.node), function(n) { - var p = n.parentNode; - - // Replace


with

 

- if (p && p.nodeName == 'p' && (p.childNodes.length == 1 || p.lastChild == n)) { - p.replaceChild(ed.getDoc().createTextNode('\u00a0'), n); - } - }); - });*/ + return FALSE; + }, - ed.onKeyPress.add(function(ed, e) { - if (e.keyCode == 13 && !e.shiftKey) { - if (!t.insertPara(e)) - Event.cancel(e); - } - }); + backspaceDelete : function(e, bs) { + var t = this, ed = t.editor, b = ed.getBody(), dom = ed.dom, n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn; - if (isGecko) { - ed.onKeyDown.add(function(ed, e) { - if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) - t.backspaceDelete(e, e.keyCode == 8); - }); - } - } + // The caret sometimes gets stuck in Gecko if you delete empty paragraphs + // This workaround removes the element by hand and moves the caret to the previous element + if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) { + if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) { + // Find previous block element + n = sc; + while ((n = n.previousSibling) && !ed.dom.isBlock(n)) ; - function ren(rn, na) { - var ne = ed.dom.create(na); + if (n) { + if (sc != b.firstChild) { + // Find last text node + w = ed.dom.doc.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, FALSE); + while (tn = w.nextNode()) + n = tn; - each(rn.attributes, function(a) { - if (a.specified && a.nodeValue) - ne.setAttribute(a.nodeName.toLowerCase(), a.nodeValue); - }); + // Place caret at the end of last text node + r = ed.getDoc().createRange(); + r.setStart(n, n.nodeValue ? n.nodeValue.length : 0); + r.setEnd(n, n.nodeValue ? n.nodeValue.length : 0); + se.setRng(r); - each(rn.childNodes, function(n) { - ne.appendChild(n.cloneNode(true)); - }); + // Remove the target container + ed.dom.remove(sc); + } - rn.parentNode.replaceChild(ne, rn); + return Event.cancel(e); + } + } + } - return ne; - }; + // Gecko generates BR elements here and there, we don't like those so lets remove them + function handler(e) { + var pr; - // Padd empty inline elements within block elements - // For example:

becomes

 

- ed.onPreProcess.add(function(ed, o) { - each(ed.dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) { - if (isEmpty(p)) { - each(ed.dom.select('span,em,strong,b,i', o.node), function(n) { - if (!n.hasChildNodes()) { - n.appendChild(ed.getDoc().createTextNode('\u00a0')); - return false; // Break the loop one padding is enough - } - }); - } - }); - }); + e = e.target; - // IE specific fixes - if (isIE) { - // Replaces IE:s auto generated paragraphs with the specified element name - if (s.element != 'P') { - ed.onKeyPress.add(function(ed, e) { - t.lastElm = ed.selection.getNode().nodeName; - }); + // A new BR was created in a block element, remove it + if (e && e.parentNode && e.nodeName == 'BR' && (n = t.getParentBlock(e))) { + pr = e.previousSibling; - ed.onKeyUp.add(function(ed, e) { - var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody(); + Event.remove(b, 'DOMNodeInserted', handler); - if (b.childNodes.length === 1 && n.nodeName == 'P') { - n = ren(n, s.element); - sel.select(n); - sel.collapse(); - ed.nodeChanged(); - } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') { - bl = ed.dom.getParent(n, 'p'); + // Is there whitespace at the end of the node before then we might need the pesky BR + // to place the caret at a correct location see bug: #2013943 + if (pr && pr.nodeType == 3 && /\s+$/.test(pr.nodeValue)) + return; - if (bl) { - ren(bl, s.element); - ed.nodeChanged(); - } - } - }); + // Only remove BR elements that got inserted in the middle of the text + if (e.previousSibling || e.nextSibling) + ed.dom.remove(e); } - } - }, + }; - find : function(n, t, s) { - var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1; + // Listen for new nodes + Event._add(b, 'DOMNodeInserted', handler); - while (n = w.nextNode()) { - c++; + // Remove listener + window.setTimeout(function() { + Event._remove(b, 'DOMNodeInserted', handler); + }, 1); + } + }); +})(tinymce); - // Index by node - if (t == 0 && n == s) - return c; +(function(tinymce) { + // Shorten names + var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend; - // Node by index - if (t == 1 && c == s) - return n; - } + tinymce.create('tinymce.ControlManager', { + ControlManager : function(ed, s) { + var t = this, i; - return -1; + s = s || {}; + t.editor = ed; + t.controls = {}; + t.onAdd = new tinymce.util.Dispatcher(t); + t.onPostRender = new tinymce.util.Dispatcher(t); + t.prefix = s.prefix || ed.id + '_'; + t._cls = {}; + + t.onPostRender.add(function() { + each(t.controls, function(c) { + c.postRender(); + }); + }); }, - forceRoots : function(ed, e) { - var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF; - var nx, bl, bp, sp, le, nl = b.childNodes, i, n, eid; + get : function(id) { + return this.controls[this.prefix + id] || this.controls[id]; + }, - // Fix for bug #1863847 - //if (e && e.keyCode == 13) - // return true; + setActive : function(id, s) { + var c = null; - // Wrap non blocks into blocks - for (i = nl.length - 1; i >= 0; i--) { - nx = nl[i]; + if (c = this.get(id)) + c.setActive(s); - // Is text or non block element - if (nx.nodeType === 3 || (!t.dom.isBlock(nx) && nx.nodeType !== 8 && !/^(script|mce:script|style|mce:style)$/i.test(nx.nodeName))) { - if (!bl) { - // Create new block but ignore whitespace - if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) { - // Store selection - if (si == -2 && r) { - if (!isIE) { - // If selection is element then mark it - if (r.startContainer.nodeType == 1 && (n = r.startContainer.childNodes[r.startOffset]) && n.nodeType == 1) { - // Save the id of the selected element - eid = n.getAttribute("id"); - n.setAttribute("id", "__mce"); - } else { - // If element is inside body, might not be the case in contentEdiable mode - if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) { - so = r.startOffset; - eo = r.endOffset; - si = t.find(b, 0, r.startContainer); - ei = t.find(b, 0, r.endContainer); - } - } - } else { - tr = d.body.createTextRange(); - tr.moveToElementText(b); - tr.collapse(1); - bp = tr.move('character', c) * -1; + return c; + }, - tr = r.duplicate(); - tr.collapse(1); - sp = tr.move('character', c) * -1; + setDisabled : function(id, s) { + var c = null; - tr = r.duplicate(); - tr.collapse(0); - le = (tr.move('character', c) * -1) - sp; + if (c = this.get(id)) + c.setDisabled(s); - si = sp - bp; - ei = le; - } - } + return c; + }, - // Uses replaceChild instead of cloneNode since it removes selected attribute from option elements on IE - // See: http://support.microsoft.com/kb/829907 - bl = ed.dom.create(ed.settings.forced_root_block); - nx.parentNode.replaceChild(bl, nx); - bl.appendChild(nx); - } - } else { - if (bl.hasChildNodes()) - bl.insertBefore(nx, bl.firstChild); - else - bl.appendChild(nx); - } - } else - bl = null; // Time to create new block + add : function(c) { + var t = this; + + if (c) { + t.controls[c.id] = c; + t.onAdd.dispatch(c, t); } - // Restore selection - if (si != -2) { - if (!isIE) { - bl = b.getElementsByTagName(ed.settings.element)[0]; - r = d.createRange(); + return c; + }, - // Select last location or generated block - if (si != -1) - r.setStart(t.find(b, 1, si), so); - else - r.setStart(bl, 0); + createControl : function(n) { + var c, t = this, ed = t.editor; - // Select last location or generated block - if (ei != -1) - r.setEnd(t.find(b, 1, ei), eo); - else - r.setEnd(bl, 0); + each(ed.plugins, function(p) { + if (p.createControl) { + c = p.createControl(n, t); - if (s) { - s.removeAllRanges(); - s.addRange(r); - } - } else { - try { - r = s.createRange(); - r.moveToElementText(b); - r.collapse(1); - r.moveStart('character', si); - r.moveEnd('character', ei); - r.select(); - } catch (ex) { - // Ignore - } + if (c) + return false; } - } else if (!isIE && (n = ed.dom.get('__mce'))) { - // Restore the id of the selected element - if (eid) - n.setAttribute('id', eid); - else - n.removeAttribute('id'); + }); - // Move caret before selected element - r = d.createRange(); - r.setStartBefore(n); - r.setEndBefore(n); - se.setRng(r); + switch (n) { + case "|": + case "separator": + return t.createSeparator(); } - }, - getParentBlock : function(n) { - var d = this.dom; + if (!c && ed.buttons && (c = ed.buttons[n])) + return t.createButton(n, c); - return d.getParent(n, d.isBlock); + return t.add(c); }, - insertPara : function(e) { - var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body; - var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car; - - // If root blocks are forced then use Operas default behavior since it's really good -// Removed due to bug: #1853816 -// if (se.forced_root_block && isOpera) -// return true; + createDropMenu : function(id, s, cc) { + var t = this, ed = t.editor, c, bm, v, cls; - // Setup before range - rb = d.createRange(); + s = extend({ + 'class' : 'mceDropDown', + constrain : ed.settings.constrain_menus + }, s); - // If is before the first block element and in body, then move it into first block element - rb.setStart(s.anchorNode, s.anchorOffset); - rb.collapse(true); + s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin'; + if (v = ed.getParam('skin_variant')) + s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1); - // Setup after range - ra = d.createRange(); + id = t.prefix + id; + cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu; + c = t.controls[id] = new cls(id, s); + c.onAddItem.add(function(c, o) { + var s = o.settings; - // If is before the first block element and in body, then move it into first block element - ra.setStart(s.focusNode, s.focusOffset); - ra.collapse(true); + s.title = ed.getLang(s.title, s.title); - // Setup start/end points - dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0; - sn = dir ? s.anchorNode : s.focusNode; - so = dir ? s.anchorOffset : s.focusOffset; - en = dir ? s.focusNode : s.anchorNode; - eo = dir ? s.focusOffset : s.anchorOffset; + if (!s.onclick) { + s.onclick = function(v) { + if (s.cmd) + ed.execCommand(s.cmd, s.ui || false, s.value); + }; + } + }); - // If selection is in empty table cell - if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) { - if (sn.firstChild.nodeName == 'BR') - dom.remove(sn.firstChild); // Remove BR + ed.onRemove.add(function() { + c.destroy(); + }); - // Create two new block elements - if (sn.childNodes.length == 0) { - ed.dom.add(sn, se.element, null, '
'); - aft = ed.dom.add(sn, se.element, null, '
'); - } else { - n = sn.innerHTML; - sn.innerHTML = ''; - ed.dom.add(sn, se.element, null, n); - aft = ed.dom.add(sn, se.element, null, '
'); - } + // Fix for bug #1897785, #1898007 + if (tinymce.isIE) { + c.onShowMenu.add(function() { + // IE 8 needs focus in order to store away a range with the current collapsed caret location + ed.focus(); - // Move caret into the last one - r = d.createRange(); - r.selectNodeContents(aft); - r.collapse(1); - ed.selection.setRng(r); + bm = ed.selection.getBookmark(1); + }); - return false; + c.onHideMenu.add(function() { + if (bm) { + ed.selection.moveToBookmark(bm); + bm = 0; + } + }); } - // If the caret is in an invalid location in FF we need to move it into the first block - if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) { - sn = en = sn.firstChild; - so = eo = 0; - rb = d.createRange(); - rb.setStart(sn, 0); - ra = d.createRange(); - ra.setStart(en, 0); - } + return t.add(c); + }, - // Never use body as start or end node - sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes - sn = sn.nodeName == "BODY" ? sn.firstChild : sn; - en = en.nodeName == "HTML" ? d.body : en; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes - en = en.nodeName == "BODY" ? en.firstChild : en; + createListBox : function(id, s, cc) { + var t = this, ed = t.editor, cmd, c, cls; - // Get start and end blocks - sb = t.getParentBlock(sn); - eb = t.getParentBlock(en); - bn = sb ? sb.nodeName : se.element; // Get block name to create + if (t.get(id)) + return null; - // Return inside list use default browser behavior - if (t.dom.getParent(sb, 'ol,ul,pre')) - return true; + s.title = ed.translate(s.title); + s.scope = s.scope || ed; - // If caption or absolute layers then always generate new blocks within - if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { - bn = se.element; - sb = null; + if (!s.onselect) { + s.onselect = function(v) { + ed.execCommand(s.cmd, s.ui || false, v || s.value); + }; } - // If caption or absolute layers then always generate new blocks within - if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { - bn = se.element; - eb = null; - } + s = extend({ + title : s.title, + 'class' : 'mce_' + id, + scope : s.scope, + control_manager : t + }, s); - // Use P instead - if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) { - bn = se.element; - sb = eb = null; - } + id = t.prefix + id; - // Setup new before and after blocks - bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn); - aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn); + if (ed.settings.use_native_selects) + c = new tinymce.ui.NativeListBox(id, s); + else { + cls = cc || t._cls.listbox || tinymce.ui.ListBox; + c = new cls(id, s); + } - // Remove id from after clone - aft.removeAttribute('id'); + t.controls[id] = c; - // Is header and cursor is at the end, then force paragraph under - if (/^(H[1-6])$/.test(bn) && isAtEnd(r, sb)) - aft = ed.dom.create(se.element); + // Fix focus problem in Safari + if (tinymce.isWebKit) { + c.onPostRender.add(function(c, n) { + // Store bookmark on mousedown + Event.add(n, 'mousedown', function() { + ed.bookmark = ed.selection.getBookmark(1); + }); - // Find start chop node - n = sc = sn; - do { - if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) - break; + // Restore on focus, since it might be lost + Event.add(n, 'focus', function() { + ed.selection.moveToBookmark(ed.bookmark); + ed.bookmark = null; + }); + }); + } - sc = n; - } while ((n = n.previousSibling ? n.previousSibling : n.parentNode)); + if (c.hideMenu) + ed.onMouseDown.add(c.hideMenu, c); - // Find end chop node - n = ec = en; - do { - if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) - break; + return t.add(c); + }, - ec = n; - } while ((n = n.nextSibling ? n.nextSibling : n.parentNode)); + createButton : function(id, s, cc) { + var t = this, ed = t.editor, o, c, cls; - // Place first chop part into before block element - if (sc.nodeName == bn) - rb.setStart(sc, 0); - else - rb.setStartBefore(sc); + if (t.get(id)) + return null; - rb.setEnd(sn, so); - bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari + s.title = ed.translate(s.title); + s.label = ed.translate(s.label); + s.scope = s.scope || ed; - // Place secnd chop part within new block element - try { - ra.setEndAfter(ec); - } catch(ex) { - //console.debug(s.focusNode, s.focusOffset); + if (!s.onclick && !s.menu_button) { + s.onclick = function() { + ed.execCommand(s.cmd, s.ui || false, s.value); + }; } - ra.setStart(en, eo); - aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari + s = extend({ + title : s.title, + 'class' : 'mce_' + id, + unavailable_prefix : ed.getLang('unavailable', ''), + scope : s.scope, + control_manager : t + }, s); - // Create range around everything - r = d.createRange(); - if (!sc.previousSibling && sc.parentNode.nodeName == bn) { - r.setStartBefore(sc.parentNode); + id = t.prefix + id; + + if (s.menu_button) { + cls = cc || t._cls.menubutton || tinymce.ui.MenuButton; + c = new cls(id, s); + ed.onMouseDown.add(c.hideMenu, c); } else { - if (rb.startContainer.nodeName == bn && rb.startOffset == 0) - r.setStartBefore(rb.startContainer); - else - r.setStart(rb.startContainer, rb.startOffset); + cls = t._cls.button || tinymce.ui.Button; + c = new cls(id, s); } - if (!ec.nextSibling && ec.parentNode.nodeName == bn) - r.setEndAfter(ec.parentNode); - else - r.setEnd(ra.endContainer, ra.endOffset); + return t.add(c); + }, - // Delete and replace it with new block elements - r.deleteContents(); + createMenuButton : function(id, s, cc) { + s = s || {}; + s.menu_button = 1; - if (isOpera) - ed.getWin().scrollTo(0, vp.y); + return this.createButton(id, s, cc); + }, - // Never wrap blocks in blocks - if (bef.firstChild && bef.firstChild.nodeName == bn) - bef.innerHTML = bef.firstChild.innerHTML; + createSplitButton : function(id, s, cc) { + var t = this, ed = t.editor, cmd, c, cls; - if (aft.firstChild && aft.firstChild.nodeName == bn) - aft.innerHTML = aft.firstChild.innerHTML; + if (t.get(id)) + return null; - // Padd empty blocks - if (isEmpty(bef)) - bef.innerHTML = '
'; + s.title = ed.translate(s.title); + s.scope = s.scope || ed; - function appendStyles(e, en) { - var nl = [], nn, n, i; + if (!s.onclick) { + s.onclick = function(v) { + ed.execCommand(s.cmd, s.ui || false, v || s.value); + }; + } - e.innerHTML = ''; + if (!s.onselect) { + s.onselect = function(v) { + ed.execCommand(s.cmd, s.ui || false, v || s.value); + }; + } - // Make clones of style elements - if (se.keep_styles) { - n = en; - do { - // We only want style specific elements - if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(n.nodeName)) { - nn = n.cloneNode(false); - dom.setAttrib(nn, 'id', ''); // Remove ID since it needs to be unique - nl.push(nn); - } - } while (n = n.parentNode); - } + s = extend({ + title : s.title, + 'class' : 'mce_' + id, + scope : s.scope, + control_manager : t + }, s); - // Append style elements to aft - if (nl.length > 0) { - for (i = nl.length - 1, nn = e; i >= 0; i--) - nn = nn.appendChild(nl[i]); + id = t.prefix + id; + cls = cc || t._cls.splitbutton || tinymce.ui.SplitButton; + c = t.add(new cls(id, s)); + ed.onMouseDown.add(c.hideMenu, c); - // Padd most inner style element - nl[0].innerHTML = isOpera ? ' ' : '
'; // Extra space for Opera so that the caret can move there - return nl[0]; // Move caret to most inner element + return c; + }, + + createColorSplitButton : function(id, s, cc) { + var t = this, ed = t.editor, cmd, c, cls, bm; + + if (t.get(id)) + return null; + + s.title = ed.translate(s.title); + s.scope = s.scope || ed; + + if (!s.onclick) { + s.onclick = function(v) { + if (tinymce.isIE) + bm = ed.selection.getBookmark(1); + + ed.execCommand(s.cmd, s.ui || false, v || s.value); + }; + } + + if (!s.onselect) { + s.onselect = function(v) { + ed.execCommand(s.cmd, s.ui || false, v || s.value); + }; + } + + s = extend({ + title : s.title, + 'class' : 'mce_' + id, + 'menu_class' : ed.getParam('skin') + 'Skin', + scope : s.scope, + more_colors_title : ed.getLang('more_colors') + }, s); + + id = t.prefix + id; + cls = cc || t._cls.colorsplitbutton || tinymce.ui.ColorSplitButton; + c = new cls(id, s); + ed.onMouseDown.add(c.hideMenu, c); + + // Remove the menu element when the editor is removed + ed.onRemove.add(function() { + c.destroy(); + }); + + // Fix for bug #1897785, #1898007 + if (tinymce.isIE) { + c.onShowMenu.add(function() { + // IE 8 needs focus in order to store away a range with the current collapsed caret location + ed.focus(); + bm = ed.selection.getBookmark(1); + }); + + c.onHideMenu.add(function() { + if (bm) { + ed.selection.moveToBookmark(bm); + bm = 0; + } + }); + } + + return t.add(c); + }, + + createToolbar : function(id, s, cc) { + var c, t = this, cls; + + id = t.prefix + id; + cls = cc || t._cls.toolbar || tinymce.ui.Toolbar; + c = new cls(id, s); + + if (t.get(id)) + return null; + + return t.add(c); + }, + + createSeparator : function(cc) { + var cls = cc || this._cls.separator || tinymce.ui.Separator; + + return new cls(); + }, + + setControlType : function(n, c) { + return this._cls[n.toLowerCase()] = c; + }, + + destroy : function() { + each(this.controls, function(c) { + c.destroy(); + }); + + this.controls = null; + } + }); +})(tinymce); + +(function(tinymce) { + var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera; + + tinymce.create('tinymce.WindowManager', { + WindowManager : function(ed) { + var t = this; + + t.editor = ed; + t.onOpen = new Dispatcher(t); + t.onClose = new Dispatcher(t); + t.params = {}; + t.features = {}; + }, + + open : function(s, p) { + var t = this, f = '', x, y, mo = t.editor.settings.dialog_type == 'modal', w, sw, sh, vp = tinymce.DOM.getViewPort(), u; + + // Default some options + s = s || {}; + p = p || {}; + sw = isOpera ? vp.w : screen.width; // Opera uses windows inside the Opera window + sh = isOpera ? vp.h : screen.height; + s.name = s.name || 'mc_' + new Date().getTime(); + s.width = parseInt(s.width || 320); + s.height = parseInt(s.height || 240); + s.resizable = true; + s.left = s.left || parseInt(sw / 2.0) - (s.width / 2.0); + s.top = s.top || parseInt(sh / 2.0) - (s.height / 2.0); + p.inline = false; + p.mce_width = s.width; + p.mce_height = s.height; + p.mce_auto_focus = s.auto_focus; + + if (mo) { + if (isIE) { + s.center = true; + s.help = false; + s.dialogWidth = s.width + 'px'; + s.dialogHeight = s.height + 'px'; + s.scroll = s.scrollbars || false; + } + } + + // Build features string + each(s, function(v, k) { + if (tinymce.is(v, 'boolean')) + v = v ? 'yes' : 'no'; + + if (!/^(name|url)$/.test(k)) { + if (isIE && mo) + f += (f ? ';' : '') + k + ':' + v; + else + f += (f ? ',' : '') + k + '=' + v; + } + }); + + t.features = s; + t.params = p; + t.onOpen.dispatch(t, s, p); + + u = s.url || s.file; + u = tinymce._addVer(u); + + try { + if (isIE && mo) { + w = 1; + window.showModalDialog(u, window, f); } else - e.innerHTML = isOpera ? ' ' : '
'; // Extra space for Opera so that the caret can move there - }; + w = window.open(u, s.name, f); + } catch (ex) { + // Ignore + } - // Fill empty afterblook with current style - if (isEmpty(aft)) - car = appendStyles(aft, en); + if (!w) + alert(t.editor.getLang('popup_blocked')); + }, - // Opera needs this one backwards for older versions - if (isOpera && parseFloat(opera.version()) < 9.5) { - r.insertNode(bef); - r.insertNode(aft); - } else { - r.insertNode(aft); - r.insertNode(bef); + close : function(w) { + w.close(); + this.onClose.dispatch(this); + }, + + createInstance : function(cl, a, b, c, d, e) { + var f = tinymce.resolve(cl); + + return new f(a, b, c, d, e); + }, + + confirm : function(t, cb, s, w) { + w = w || window; + + cb.call(s || this, w.confirm(this._decode(this.editor.getLang(t, t)))); + }, + + alert : function(tx, cb, s, w) { + var t = this; + + w = w || window; + w.alert(t._decode(t.editor.getLang(tx, tx))); + + if (cb) + cb.call(s || t); + }, + + resizeBy : function(dw, dh, win) { + win.resizeBy(dw, dh); + }, + + // Internal functions + + _decode : function(s) { + return tinymce.DOM.decode(s).replace(/\\n/g, '\n'); + } + }); +}(tinymce)); +(function(tinymce) { + function CommandManager() { + var execCommands = {}, queryStateCommands = {}, queryValueCommands = {}; + + function add(collection, cmd, func, scope) { + if (typeof(cmd) == 'string') + cmd = [cmd]; + + tinymce.each(cmd, function(cmd) { + collection[cmd.toLowerCase()] = {func : func, scope : scope}; + }); + }; + + tinymce.extend(this, { + add : function(cmd, func, scope) { + add(execCommands, cmd, func, scope); + }, + + addQueryStateHandler : function(cmd, func, scope) { + add(queryStateCommands, cmd, func, scope); + }, + + addQueryValueHandler : function(cmd, func, scope) { + add(queryValueCommands, cmd, func, scope); + }, + + execCommand : function(scope, cmd, ui, value, args) { + if (cmd = execCommands[cmd.toLowerCase()]) { + if (cmd.func.call(scope || cmd.scope, ui, value, args) !== false) + return true; + } + }, + + queryCommandValue : function() { + if (cmd = queryValueCommands[cmd.toLowerCase()]) + return cmd.func.call(scope || cmd.scope, ui, value, args); + }, + + queryCommandState : function() { + if (cmd = queryStateCommands[cmd.toLowerCase()]) + return cmd.func.call(scope || cmd.scope, ui, value, args); + } + }); + }; + + tinymce.GlobalCommands = new CommandManager(); +})(tinymce); +(function(tinymce) { + tinymce.Formatter = function(ed) { + var formats = {}, + each = tinymce.each, + dom = ed.dom, + selection = ed.selection, + TreeWalker = tinymce.dom.TreeWalker, + rangeUtils = new tinymce.dom.RangeUtils(dom), + isValid = ed.schema.isValid, + isBlock = dom.isBlock, + forcedRootBlock = ed.settings.forced_root_block, + nodeIndex = dom.nodeIndex, + INVISIBLE_CHAR = '\uFEFF', + MCE_ATTR_RE = /^(src|href|style)$/, + FALSE = false, + TRUE = true, + undefined, + pendingFormats = {apply : [], remove : []}; + + function getParents(node, selector) { + return dom.getParents(node, selector, dom.getRoot()); + }; + + function isCaretNode(node) { + return node.nodeType === 1 && (node.face === 'mceinline' || node.style.fontFamily === 'mceinline'); + }; + + // Public functions + + function get(name) { + return name ? formats[name] : formats; + }; + + function register(name, format) { + if (name) { + if (typeof(name) !== 'string') { + each(name, function(format, name) { + register(name, format); + }); + } else { + // Force format into array and add it to internal collection + format = format.length ? format : [format]; + + each(format, function(format) { + // Set deep to false by default on selector formats this to avoid removing + // alignment on images inside paragraphs when alignment is changed on paragraphs + if (format.deep === undefined) + format.deep = !format.selector; + + // Default to true + if (format.split === undefined) + format.split = !format.selector || format.inline; + + // Default to true + if (format.remove === undefined && format.selector && !format.inline) + format.remove = 'none'; + + // Mark format as a mixed format inline + block level + if (format.selector && format.inline) { + format.mixed = true; + format.block_expand = true; + } + + // Split classes if needed + if (typeof(format.classes) === 'string') + format.classes = format.classes.split(/\s+/); + }); + + formats[name] = format; + } } + }; - // Normalize - aft.normalize(); - bef.normalize(); + function apply(name, vars, node) { + var formatList = get(name), format = formatList[0], bookmark, rng, i; - function first(n) { - return d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() || n; - }; + function moveStart(rng) { + var container = rng.startContainer, + offset = rng.startOffset, + walker, node; - // Move cursor and scroll into view - r = d.createRange(); - r.selectNodeContents(isGecko ? first(car || aft) : car || aft); - r.collapse(1); - s.removeAllRanges(); - s.addRange(r); + // Move startContainer/startOffset in to a suitable node + if (container.nodeType == 1 || container.nodeValue === "") { + walker = new TreeWalker(container.childNodes[offset]); + for (node = walker.current(); node; node = walker.next()) { + if (node.nodeType == 3 && !isBlock(node.parentNode) && !isWhiteSpaceNode(node)) { + rng.setStart(node, 0); + break; + } + } + } - // scrollIntoView seems to scroll the parent window in most browsers now including FF 3.0b4 so it's time to stop using it and do it our selfs - y = ed.dom.getPos(aft).y; - ch = aft.clientHeight; + return rng; + }; - // Is element within viewport - if (y < vp.y || y + ch > vp.y + vp.h) { - ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + 25); // Needs to be hardcoded to roughly one line of text if a huge text block is broken into two blocks - //console.debug('SCROLL!', 'vp.y: ' + vp.y, 'y' + y, 'vp.h' + vp.h, 'clientHeight' + aft.clientHeight, 'yyy: ' + (y < vp.y ? y : y - vp.h + aft.clientHeight)); - } + function setElementFormat(elm, fmt) { + fmt = fmt || format; - return false; - }, + if (elm) { + each(fmt.styles, function(value, name) { + dom.setStyle(elm, name, replaceVars(value, vars)); + }); - backspaceDelete : function(e, bs) { - var t = this, ed = t.editor, b = ed.getBody(), dom = ed.dom, n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn; + each(fmt.attributes, function(value, name) { + dom.setAttrib(elm, name, replaceVars(value, vars)); + }); + + each(fmt.classes, function(value) { + value = replaceVars(value, vars); - /* - var par, rng, nextBlock; + if (!dom.hasClass(elm, value)) + dom.addClass(elm, value); + }); + } + }; - // Delete key will not merge paragraphs on Gecko so we need to do this manually - // Hitting the delete key at the following caret position doesn't merge the elements

A|

B

- // This logic will merge them into this:

A|B

- if (e.keyCode == 46) { - if (r.collapsed) { - par = dom.getParent(sc, 'p,h1,h2,h3,h4,h5,h6,div'); + function applyRngStyle(rng) { + var newWrappers = [], wrapName, wrapElm; - if (par) { - rng = dom.createRng(); + // Setup wrapper element + wrapName = format.inline || format.block; + wrapElm = dom.create(wrapName); + setElementFormat(wrapElm); - rng.setStart(sc, r.startOffset); - rng.setEndAfter(par); + rangeUtils.walk(rng, function(nodes) { + var currentWrapElm; - // Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element - if (dom.getOuterHTML(rng.cloneContents()).replace(/<[^>]+>/g, '').length == 0) { - nextBlock = dom.getNext(par, 'p,h1,h2,h3,h4,h5,h6,div'); + function process(node) { + var nodeName = node.nodeName.toLowerCase(), parentName = node.parentNode.nodeName.toLowerCase(), found; - // Copy all children from next sibling block and remove it - if (nextBlock) { - each(nextBlock.childNodes, function(node) { - par.appendChild(node.cloneNode(true)); - }); + // Stop wrapping on br elements + if (isEq(nodeName, 'br')) { + currentWrapElm = 0; - dom.remove(nextBlock); - } + // Remove any br elements when we wrap things + if (format.block) + dom.remove(node); - // Block the default even since the Gecko team might eventually fix this - // We will remove this logic once they do we can't feature detect this one - e.preventDefault(); return; } - } - } - } - */ - // The caret sometimes gets stuck in Gecko if you delete empty paragraphs - // This workaround removes the element by hand and moves the caret to the previous element - if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) { - if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) { - // Find previous block element - n = sc; - while ((n = n.previousSibling) && !ed.dom.isBlock(n)) ; + // If node is wrapper type + if (format.wrapper && matchNode(node, name, vars)) { + currentWrapElm = 0; + return; + } - if (n) { - if (sc != b.firstChild) { - // Find last text node - w = ed.dom.doc.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); - while (tn = w.nextNode()) - n = tn; + // Can we rename the block + if (format.block && !format.wrapper && isTextBlock(nodeName)) { + node = dom.rename(node, wrapName); + setElementFormat(node); + newWrappers.push(node); + currentWrapElm = 0; + return; + } - // Place caret at the end of last text node - r = ed.getDoc().createRange(); - r.setStart(n, n.nodeValue ? n.nodeValue.length : 0); - r.setEnd(n, n.nodeValue ? n.nodeValue.length : 0); - se.setRng(r); + // Handle selector patterns + if (format.selector) { + // Look for matching formats + each(formatList, function(format) { + if (dom.is(node, format.selector) && !isCaretNode(node)) { + setElementFormat(node, format); + found = true; + } + }); - // Remove the target container - ed.dom.remove(sc); + // Contine processing if a selector match wasn't found and a inline element is defined + if (!format.inline || found) { + currentWrapElm = 0; + return; + } } - return Event.cancel(e); - } - } - } + // Is it valid to wrap this item + if (isValid(wrapName, nodeName) && isValid(parentName, wrapName)) { + // Start wrapping + if (!currentWrapElm) { + // Wrap the node + currentWrapElm = wrapElm.cloneNode(FALSE); + node.parentNode.insertBefore(currentWrapElm, node); + newWrappers.push(currentWrapElm); + } - // Gecko generates BR elements here and there, we don't like those so lets remove them - function handler(e) { - var pr; + currentWrapElm.appendChild(node); + } else { + // Start a new wrapper for possible children + currentWrapElm = 0; - e = e.target; + each(tinymce.grep(node.childNodes), process); - // A new BR was created in a block element, remove it - if (e && e.parentNode && e.nodeName == 'BR' && (n = t.getParentBlock(e))) { - pr = e.previousSibling; + // End the last wrapper + currentWrapElm = 0; + } + }; - Event.remove(b, 'DOMNodeInserted', handler); + // Process siblings from range + each(nodes, process); + }); - // Is there whitespace at the end of the node before then we might need the pesky BR - // to place the caret at a correct location see bug: #2013943 - if (pr && pr.nodeType == 3 && /\s+$/.test(pr.nodeValue)) - return; + // Cleanup + each(newWrappers, function(node) { + var childCount; - // Only remove BR elements that got inserted in the middle of the text - if (e.previousSibling || e.nextSibling) - ed.dom.remove(e); - } - }; + function getChildCount(node) { + var count = 0; - // Listen for new nodes - Event._add(b, 'DOMNodeInserted', handler); + each(node.childNodes, function(node) { + if (!isWhiteSpaceNode(node) && !isBookmarkNode(node)) + count++; + }); - // Remove listener - window.setTimeout(function() { - Event._remove(b, 'DOMNodeInserted', handler); - }, 1); - } - }); -})(tinymce); -(function(tinymce) { - // Shorten names - var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend; + return count; + }; - tinymce.create('tinymce.ControlManager', { - ControlManager : function(ed, s) { - var t = this, i; + function mergeStyles(node) { + var child, clone; - s = s || {}; - t.editor = ed; - t.controls = {}; - t.onAdd = new tinymce.util.Dispatcher(t); - t.onPostRender = new tinymce.util.Dispatcher(t); - t.prefix = s.prefix || ed.id + '_'; - t._cls = {}; + each(node.childNodes, function(node) { + if (node.nodeType == 1 && !isBookmarkNode(node) && !isCaretNode(node)) { + child = node; + return FALSE; // break loop + } + }); - t.onPostRender.add(function() { - each(t.controls, function(c) { - c.postRender(); - }); - }); - }, + // If child was found and of the same type as the current node + if (child && matchName(child, format)) { + clone = child.cloneNode(FALSE); + setElementFormat(clone); - get : function(id) { - return this.controls[this.prefix + id] || this.controls[id]; - }, + dom.replace(clone, node, TRUE); + dom.remove(child, 1); + } - setActive : function(id, s) { - var c = null; + return clone || node; + }; - if (c = this.get(id)) - c.setActive(s); + childCount = getChildCount(node); - return c; - }, + // Remove empty nodes + if (childCount === 0) { + dom.remove(node, 1); + return; + } - setDisabled : function(id, s) { - var c = null; + if (format.inline || format.wrapper) { + // Merges the current node with it's children of similar type to reduce the number of elements + if (!format.exact && childCount === 1) + node = mergeStyles(node); + + // Remove/merge children + each(formatList, function(format) { + // Merge all children of similar type will move styles from child to parent + // this: text + // will become: text + each(dom.select(format.inline, node), function(child) { + removeFormat(format, vars, child, format.exact ? child : null); + }); + }); - if (c = this.get(id)) - c.setDisabled(s); + // Look for parent with similar style format + dom.getParent(node.parentNode, function(parent) { + if (matchNode(parent, name, vars)) { + dom.remove(node, 1); + node = 0; + return TRUE; + } + }); - return c; - }, + // Merge next and previous siblings if they are similar texttext becomes texttext + if (node) { + node = mergeSiblings(getNonWhiteSpaceSibling(node), node); + node = mergeSiblings(node, getNonWhiteSpaceSibling(node, TRUE)); + } + } + }); + }; - add : function(c) { - var t = this; + if (format) { + if (node) { + rng = dom.createRng(); - if (c) { - t.controls[c.id] = c; - t.onAdd.dispatch(c, t); + rng.setStartBefore(node); + rng.setEndAfter(node); + + applyRngStyle(rng); + } else { + if (!selection.isCollapsed() || !format.inline) { + // Apply formatting to selection + bookmark = selection.getBookmark(); + applyRngStyle(expandRng(selection.getRng(TRUE), formatList)); + + selection.moveToBookmark(bookmark); + selection.setRng(moveStart(selection.getRng(TRUE))); + ed.nodeChanged(); + } else + performCaretAction('apply', name, vars); + } } + }; - return c; - }, + function remove(name, vars, node) { + var formatList = get(name), format = formatList[0], bookmark, i, rng; - createControl : function(n) { - var c, t = this, ed = t.editor; + // Merges the styles for each node + function process(node) { + var children, i, l; - each(ed.plugins, function(p) { - if (p.createControl) { - c = p.createControl(n, t); + // Grab the children first since the nodelist might be changed + children = tinymce.grep(node.childNodes); - if (c) - return false; + // Process current node + for (i = 0, l = formatList.length; i < l; i++) { + if (removeFormat(formatList[i], vars, node, node)) + break; } - }); - switch (n) { - case "|": - case "separator": - return t.createSeparator(); - } + // Process the children + if (format.deep) { + for (i = 0, l = children.length; i < l; i++) + process(children[i]); + } + }; - if (!c && ed.buttons && (c = ed.buttons[n])) - return t.createButton(n, c); + function findFormatRoot(container) { + var formatRoot; - return t.add(c); - }, + // Find format root + each(getParents(container.parentNode).reverse(), function(parent) { + var format; - createDropMenu : function(id, s, cc) { - var t = this, ed = t.editor, c, bm, v, cls; + // Find format root element + if (!formatRoot && parent.id != '_start' && parent.id != '_end') { + // Is the node matching the format we are looking for + format = matchNode(parent, name, vars); + if (format && format.split !== false) + formatRoot = parent; + } + }); - s = extend({ - 'class' : 'mceDropDown', - constrain : ed.settings.constrain_menus - }, s); + return formatRoot; + }; - s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin'; - if (v = ed.getParam('skin_variant')) - s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1); + function wrapAndSplit(format_root, container, target, split) { + var parent, clone, lastClone, firstClone, i, formatRootParent; - id = t.prefix + id; - cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu; - c = t.controls[id] = new cls(id, s); - c.onAddItem.add(function(c, o) { - var s = o.settings; + // Format root found then clone formats and split it + if (format_root) { + formatRootParent = format_root.parentNode; - s.title = ed.getLang(s.title, s.title); + for (parent = container.parentNode; parent && parent != formatRootParent; parent = parent.parentNode) { + clone = parent.cloneNode(FALSE); - if (!s.onclick) { - s.onclick = function(v) { - ed.execCommand(s.cmd, s.ui || false, s.value); - }; - } - }); + for (i = 0; i < formatList.length; i++) { + if (removeFormat(formatList[i], vars, clone, clone)) { + clone = 0; + break; + } + } - ed.onRemove.add(function() { - c.destroy(); - }); + // Build wrapper node + if (clone) { + if (lastClone) + clone.appendChild(lastClone); - // Fix for bug #1897785, #1898007 - if (tinymce.isIE) { - c.onShowMenu.add(function() { - // IE 8 needs focus in order to store away a range with the current collapsed caret location - ed.focus(); + if (!firstClone) + firstClone = clone; - bm = ed.selection.getBookmark(1); - }); + lastClone = clone; + } + } - c.onHideMenu.add(function() { - if (bm) { - ed.selection.moveToBookmark(bm); - bm = 0; + // Never split block elements if the format is mixed + if (split && (!format.mixed || !isBlock(format_root))) + container = dom.split(format_root, container); + + // Wrap container in cloned formats + if (lastClone) { + target.parentNode.insertBefore(lastClone, target); + firstClone.appendChild(target); } - }); - } + } - return t.add(c); - }, + return container; + }; - createListBox : function(id, s, cc) { - var t = this, ed = t.editor, cmd, c, cls; + function splitToFormatRoot(container) { + return wrapAndSplit(findFormatRoot(container), container, container, true); + }; - if (t.get(id)) - return null; + function unwrap(start) { + var node = dom.get(start ? '_start' : '_end'), + out = node[start ? 'firstChild' : 'lastChild']; - s.title = ed.translate(s.title); - s.scope = s.scope || ed; + dom.remove(node, 1); - if (!s.onselect) { - s.onselect = function(v) { - ed.execCommand(s.cmd, s.ui || false, v || s.value); - }; - } + return out; + }; - s = extend({ - title : s.title, - 'class' : 'mce_' + id, - scope : s.scope, - control_manager : t - }, s); + function removeRngStyle(rng) { + var startContainer, endContainer; + + rng = expandRng(rng, formatList, TRUE); - id = t.prefix + id; + if (format.split) { + startContainer = getContainer(rng, TRUE); + endContainer = getContainer(rng); - if (ed.settings.use_native_selects) - c = new tinymce.ui.NativeListBox(id, s); - else { - cls = cc || t._cls.listbox || tinymce.ui.ListBox; - c = new cls(id, s); - } + if (startContainer != endContainer) { + // Wrap start/end nodes in span element since these might be cloned/moved + startContainer = wrap(startContainer, 'span', {id : '_start', _mce_type : 'bookmark'}); + endContainer = wrap(endContainer, 'span', {id : '_end', _mce_type : 'bookmark'}); - t.controls[id] = c; + // Split start/end + splitToFormatRoot(startContainer); + splitToFormatRoot(endContainer); - // Fix focus problem in Safari - if (tinymce.isWebKit) { - c.onPostRender.add(function(c, n) { - // Store bookmark on mousedown - Event.add(n, 'mousedown', function() { - ed.bookmark = ed.selection.getBookmark(1); - }); + // Unwrap start/end to get real elements again + startContainer = unwrap(TRUE); + endContainer = unwrap(); + } else + startContainer = endContainer = splitToFormatRoot(startContainer); - // Restore on focus, since it might be lost - Event.add(n, 'focus', function() { - ed.selection.moveToBookmark(ed.bookmark); - ed.bookmark = null; + // Update range positions since they might have changed after the split operations + rng.startContainer = startContainer.parentNode; + rng.startOffset = nodeIndex(startContainer); + rng.endContainer = endContainer.parentNode; + rng.endOffset = nodeIndex(endContainer) + 1; + } + + // Remove items between start/end + rangeUtils.walk(rng, function(nodes) { + each(nodes, function(node) { + process(node); }); }); + }; + + // Handle node + if (node) { + rng = dom.createRng(); + rng.setStartBefore(node); + rng.setEndAfter(node); + removeRngStyle(rng); + return; } - if (c.hideMenu) - ed.onMouseDown.add(c.hideMenu, c); + if (!selection.isCollapsed() || !format.inline) { + bookmark = selection.getBookmark(); + removeRngStyle(selection.getRng(TRUE)); + selection.moveToBookmark(bookmark); + ed.nodeChanged(); + } else + performCaretAction('remove', name, vars); + }; - return t.add(c); - }, + function toggle(name, vars, node) { + if (match(name, vars, node)) + remove(name, vars, node); + else + apply(name, vars, node); + }; - createButton : function(id, s, cc) { - var t = this, ed = t.editor, o, c, cls; + function matchNode(node, name, vars) { + var formatList = get(name), format, i, classes; - if (t.get(id)) - return null; + function matchItems(node, format, item_name) { + var key, value, items = format[item_name], i; - s.title = ed.translate(s.title); - s.label = ed.translate(s.label); - s.scope = s.scope || ed; + // Check all items + if (items) { + // Non indexed object + if (items.length === undefined) { + for (key in items) { + if (items.hasOwnProperty(key)) { + if (item_name === 'attributes') + value = dom.getAttrib(node, key); + else + value = getStyle(node, key); - if (!s.onclick && !s.menu_button) { - s.onclick = function() { - ed.execCommand(s.cmd, s.ui || false, s.value); - }; - } + if (!isEq(value, replaceVars(items[key], vars))) + return; + } + } + } else { + // Only one match needed for indexed arrays + for (i = 0; i < items.length; i++) { + if (item_name === 'attributes' ? dom.getAttrib(node, items[i]) : getStyle(node, items[i])) + return format; + } + } + } - s = extend({ - title : s.title, - 'class' : 'mce_' + id, - unavailable_prefix : ed.getLang('unavailable', ''), - scope : s.scope, - control_manager : t - }, s); + return format; + }; - id = t.prefix + id; + if (formatList && node) { + // Check each format in list + for (i = 0; i < formatList.length; i++) { + format = formatList[i]; + + // Name name, attributes, styles and classes + if (matchName(node, format) && matchItems(node, format, 'attributes') && matchItems(node, format, 'styles')) { + // Match classes + if (classes = format.classes) { + for (i = 0; i < classes.length; i++) { + if (!dom.hasClass(node, classes[i])) + return; + } + } - if (s.menu_button) { - cls = cc || t._cls.menubutton || tinymce.ui.MenuButton; - c = new cls(id, s); - ed.onMouseDown.add(c.hideMenu, c); - } else { - cls = t._cls.button || tinymce.ui.Button; - c = new cls(id, s); + return format; + } + } } + }; - return t.add(c); - }, + function match(name, vars, node) { + var startNode, i; - createMenuButton : function(id, s, cc) { - s = s || {}; - s.menu_button = 1; + function matchParents(node) { + // Find first node with similar format settings + node = dom.getParent(node, function(node) { + return !!matchNode(node, name, vars); + }); - return this.createButton(id, s, cc); - }, + // Do an exact check on the similar format element + return matchNode(node, name, vars); + }; - createSplitButton : function(id, s, cc) { - var t = this, ed = t.editor, cmd, c, cls; + // Check specified node + if (node) + return matchParents(node); - if (t.get(id)) - return null; + // Check pending formats + if (selection.isCollapsed()) { + for (i = pendingFormats.apply.length - 1; i >= 0; i--) { + if (pendingFormats.apply[i].name == name) + return true; + } - s.title = ed.translate(s.title); - s.scope = s.scope || ed; + for (i = pendingFormats.remove.length - 1; i >= 0; i--) { + if (pendingFormats.remove[i].name == name) + return false; + } - if (!s.onclick) { - s.onclick = function(v) { - ed.execCommand(s.cmd, s.ui || false, v || s.value); - }; + return matchParents(selection.getNode()); } - if (!s.onselect) { - s.onselect = function(v) { - ed.execCommand(s.cmd, s.ui || false, v || s.value); - }; + // Check selected node + node = selection.getNode(); + if (matchParents(node)) + return TRUE; + + // Check start node if it's different + startNode = selection.getStart(); + if (startNode != node) { + if (matchParents(startNode)) + return TRUE; } - s = extend({ - title : s.title, - 'class' : 'mce_' + id, - scope : s.scope, - control_manager : t - }, s); + return FALSE; + }; - id = t.prefix + id; - cls = cc || t._cls.splitbutton || tinymce.ui.SplitButton; - c = t.add(new cls(id, s)); - ed.onMouseDown.add(c.hideMenu, c); + function canApply(name) { + var formatList = get(name), startNode, parents, i, x, selector; - return c; - }, + if (formatList) { + startNode = selection.getStart(); + parents = getParents(startNode); - createColorSplitButton : function(id, s, cc) { - var t = this, ed = t.editor, cmd, c, cls, bm; + for (x = formatList.length - 1; x >= 0; x--) { + selector = formatList[x].selector; - if (t.get(id)) - return null; + // Format is not selector based, then always return TRUE + if (!selector) + return TRUE; - s.title = ed.translate(s.title); - s.scope = s.scope || ed; + for (i = parents.length - 1; i >= 0; i--) { + if (dom.is(parents[i], selector)) + return TRUE; + } + } + } - if (!s.onclick) { - s.onclick = function(v) { - if (tinymce.isIE) - bm = ed.selection.getBookmark(1); + return FALSE; + }; - ed.execCommand(s.cmd, s.ui || false, v || s.value); - }; - } + // Expose to public + tinymce.extend(this, { + get : get, + register : register, + apply : apply, + remove : remove, + toggle : toggle, + match : match, + matchNode : matchNode, + canApply : canApply + }); - if (!s.onselect) { - s.onselect = function(v) { - ed.execCommand(s.cmd, s.ui || false, v || s.value); - }; - } + // Private functions - s = extend({ - title : s.title, - 'class' : 'mce_' + id, - 'menu_class' : ed.getParam('skin') + 'Skin', - scope : s.scope, - more_colors_title : ed.getLang('more_colors') - }, s); + function matchName(node, format) { + // Check for inline match + if (isEq(node, format.inline)) + return TRUE; - id = t.prefix + id; - cls = cc || t._cls.colorsplitbutton || tinymce.ui.ColorSplitButton; - c = new cls(id, s); - ed.onMouseDown.add(c.hideMenu, c); + // Check for block match + if (isEq(node, format.block)) + return TRUE; - // Remove the menu element when the editor is removed - ed.onRemove.add(function() { - c.destroy(); - }); + // Check for selector match + if (format.selector) + return dom.is(node, format.selector); + }; - // Fix for bug #1897785, #1898007 - if (tinymce.isIE) { - c.onShowMenu.add(function() { - // IE 8 needs focus in order to store away a range with the current collapsed caret location - ed.focus(); - bm = ed.selection.getBookmark(1); - }); + function isEq(str1, str2) { + str1 = str1 || ''; + str2 = str2 || ''; - c.onHideMenu.add(function() { - if (bm) { - ed.selection.moveToBookmark(bm); - bm = 0; - } - }); - } + str1 = str1.nodeName || str1; + str2 = str2.nodeName || str2; - return t.add(c); - }, + return str1.toLowerCase() == str2.toLowerCase(); + }; - createToolbar : function(id, s, cc) { - var c, t = this, cls; + function getStyle(node, name) { + var styleVal = dom.getStyle(node, name); - id = t.prefix + id; - cls = cc || t._cls.toolbar || tinymce.ui.Toolbar; - c = new cls(id, s); + // Force the format to hex + if (name == 'color' || name == 'backgroundColor') + styleVal = dom.toHex(styleVal); - if (t.get(id)) - return null; + // Opera will return bold as 700 + if (name == 'fontWeight' && styleVal == 700) + styleVal = 'bold'; - return t.add(c); - }, + return '' + styleVal; + }; - createSeparator : function(cc) { - var cls = cc || this._cls.separator || tinymce.ui.Separator; + function replaceVars(value, vars) { + if (typeof(value) != "string") + value = value(vars); + else if (vars) { + value = value.replace(/%(\w+)/g, function(str, name) { + return vars[name] || str; + }); + } - return new cls(); - }, + return value; + }; - setControlType : function(n, c) { - return this._cls[n.toLowerCase()] = c; - }, - - destroy : function() { - each(this.controls, function(c) { - c.destroy(); - }); + function isWhiteSpaceNode(node) { + return node && node.nodeType === 3 && /^\s*$/.test(node.nodeValue); + }; - this.controls = null; - } - }); -})(tinymce); -(function(tinymce) { - var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera; + function wrap(node, name, attrs) { + var wrapper = dom.create(name, attrs); - tinymce.create('tinymce.WindowManager', { - WindowManager : function(ed) { - var t = this; + node.parentNode.insertBefore(wrapper, node); + wrapper.appendChild(node); - t.editor = ed; - t.onOpen = new Dispatcher(t); - t.onClose = new Dispatcher(t); - t.params = {}; - t.features = {}; - }, + return wrapper; + }; - open : function(s, p) { - var t = this, f = '', x, y, mo = t.editor.settings.dialog_type == 'modal', w, sw, sh, vp = tinymce.DOM.getViewPort(), u; + function expandRng(rng, format, remove) { + var startContainer = rng.startContainer, + startOffset = rng.startOffset, + endContainer = rng.endContainer, + endOffset = rng.endOffset, sibling, lastIdx; - // Default some options - s = s || {}; - p = p || {}; - sw = isOpera ? vp.w : screen.width; // Opera uses windows inside the Opera window - sh = isOpera ? vp.h : screen.height; - s.name = s.name || 'mc_' + new Date().getTime(); - s.width = parseInt(s.width || 320); - s.height = parseInt(s.height || 240); - s.resizable = true; - s.left = s.left || parseInt(sw / 2.0) - (s.width / 2.0); - s.top = s.top || parseInt(sh / 2.0) - (s.height / 2.0); - p.inline = false; - p.mce_width = s.width; - p.mce_height = s.height; - p.mce_auto_focus = s.auto_focus; + // This function walks up the tree if there is no siblings before/after the node + function findParentContainer(container, child_name, sibling_name, root) { + var parent, child; - if (mo) { - if (isIE) { - s.center = true; - s.help = false; - s.dialogWidth = s.width + 'px'; - s.dialogHeight = s.height + 'px'; - s.scroll = s.scrollbars || false; - } - } + root = root || dom.getRoot(); - // Build features string - each(s, function(v, k) { - if (tinymce.is(v, 'boolean')) - v = v ? 'yes' : 'no'; + for (;;) { + // Check if we can move up are we at root level or body level + parent = container.parentNode; - if (!/^(name|url)$/.test(k)) { - if (isIE && mo) - f += (f ? ';' : '') + k + ':' + v; - else - f += (f ? ',' : '') + k + '=' + v; + // Stop expanding on block elements or root depending on format + if (parent == root || (!format[0].block_expand && isBlock(parent))) + return container; + + for (sibling = parent[child_name]; sibling && sibling != container; sibling = sibling[sibling_name]) { + if (sibling.nodeType == 1 && !isBookmarkNode(sibling)) + return container; + + if (sibling.nodeType == 3 && !isWhiteSpaceNode(sibling)) + return container; + } + + container = container.parentNode; } - }); - t.features = s; - t.params = p; - t.onOpen.dispatch(t, s, p); + return container; + }; + + // If index based start position then resolve it + if (startContainer.nodeType == 1 && startContainer.hasChildNodes()) { + lastIdx = startContainer.childNodes.length - 1; + startContainer = startContainer.childNodes[startOffset > lastIdx ? lastIdx : startOffset]; - u = s.url || s.file; - u = tinymce._addVer(u); + if (startContainer.nodeType == 3) + startOffset = 0; + } - try { - if (isIE && mo) { - w = 1; - window.showModalDialog(u, window, f); - } else - w = window.open(u, s.name, f); - } catch (ex) { - // Ignore + // If index based end position then resolve it + if (endContainer.nodeType == 1 && endContainer.hasChildNodes()) { + lastIdx = endContainer.childNodes.length - 1; + endContainer = endContainer.childNodes[endOffset > lastIdx ? lastIdx : endOffset - 1]; + + if (endContainer.nodeType == 3) + endOffset = endContainer.nodeValue.length; } - if (!w) - alert(t.editor.getLang('popup_blocked')); - }, + // Exclude bookmark nodes if possible + if (isBookmarkNode(startContainer.parentNode)) + startContainer = startContainer.parentNode; - close : function(w) { - w.close(); - this.onClose.dispatch(this); - }, + if (isBookmarkNode(startContainer)) + startContainer = startContainer.nextSibling || startContainer; - createInstance : function(cl, a, b, c, d, e) { - var f = tinymce.resolve(cl); + if (isBookmarkNode(endContainer.parentNode)) + endContainer = endContainer.parentNode; - return new f(a, b, c, d, e); - }, + if (isBookmarkNode(endContainer)) + endContainer = endContainer.previousSibling || endContainer; - confirm : function(t, cb, s, w) { - w = w || window; + // Move start/end point up the tree if the leaves are sharp and if we are in different containers + // Example * becomes !: !

*texttext*

! + // This will reduce the number of wrapper elements that needs to be created + // Move start point up the tree + if (format[0].inline || format[0].block_expand) { + startContainer = findParentContainer(startContainer, 'firstChild', 'nextSibling'); + endContainer = findParentContainer(endContainer, 'lastChild', 'previousSibling'); + } - cb.call(s || this, w.confirm(this._decode(this.editor.getLang(t, t)))); - }, + // Expand start/end container to matching selector + if (format[0].selector && format[0].expand !== FALSE && !format[0].inline) { + function findSelectorEndPoint(container, sibling_name) { + var parents, i, y; - alert : function(tx, cb, s, w) { - var t = this; + if (container.nodeType == 3 && container.nodeValue.length == 0 && container[sibling_name]) + container = container[sibling_name]; - w = w || window; - w.alert(t._decode(t.editor.getLang(tx, tx))); + parents = getParents(container); + for (i = 0; i < parents.length; i++) { + for (y = 0; y < format.length; y++) { + if (dom.is(parents[i], format[y].selector)) + return parents[i]; + } + } - if (cb) - cb.call(s || t); - }, + return container; + }; - // Internal functions + // Find new startContainer/endContainer if there is better one + startContainer = findSelectorEndPoint(startContainer, 'previousSibling'); + endContainer = findSelectorEndPoint(endContainer, 'nextSibling'); + } - _decode : function(s) { - return tinymce.DOM.decode(s).replace(/\\n/g, '\n'); - } - }); -}(tinymce));(function(tinymce) { - tinymce.CommandManager = function() { - var execCommands = {}, queryStateCommands = {}, queryValueCommands = {}; + // Expand start/end container to matching block element or text node + if (format[0].block || format[0].selector) { + function findBlockEndPoint(container, sibling_name, sibling_name2) { + var node; - function add(collection, cmd, func, scope) { - if (typeof(cmd) == 'string') - cmd = [cmd]; + // Expand to block of similar type + if (!format[0].wrapper) + node = dom.getParent(container, format[0].block); - tinymce.each(cmd, function(cmd) { - collection[cmd.toLowerCase()] = {func : func, scope : scope}; - }); - }; + // Expand to first wrappable block element or any block element + if (!node) + node = dom.getParent(container.nodeType == 3 ? container.parentNode : container, isBlock); - tinymce.extend(this, { - add : function(cmd, func, scope) { - add(execCommands, cmd, func, scope); - }, + // Exclude inner lists from wrapping + if (node && format[0].wrapper) + node = getParents(node, 'ul,ol').reverse()[0] || node; - addQueryStateHandler : function(cmd, func, scope) { - add(queryStateCommands, cmd, func, scope); - }, + // Didn't find a block element look for first/last wrappable element + if (!node) { + node = container; - addQueryValueHandler : function(cmd, func, scope) { - add(queryValueCommands, cmd, func, scope); - }, + while (node[sibling_name] && !isBlock(node[sibling_name])) { + node = node[sibling_name]; - execCommand : function(scope, cmd, ui, value, args) { - if (cmd = execCommands[cmd.toLowerCase()]) { - if (cmd.func.call(scope || cmd.scope, ui, value, args) !== false) - return true; + // Break on BR but include it will be removed later on + // we can't remove it now since we need to check if it can be wrapped + if (isEq(node, 'br')) + break; + } + } + + return node || container; + }; + + // Find new startContainer/endContainer if there is better one + startContainer = findBlockEndPoint(startContainer, 'previousSibling'); + endContainer = findBlockEndPoint(endContainer, 'nextSibling'); + + // Non block element then try to expand up the leaf + if (format[0].block) { + if (!isBlock(startContainer)) + startContainer = findParentContainer(startContainer, 'firstChild', 'nextSibling'); + + if (!isBlock(endContainer)) + endContainer = findParentContainer(endContainer, 'lastChild', 'previousSibling'); } - }, + } - queryCommandValue : function() { - if (cmd = queryValueCommands[cmd.toLowerCase()]) - return cmd.func.call(scope || cmd.scope, ui, value, args); - }, + // Setup index for startContainer + if (startContainer.nodeType == 1) { + startOffset = nodeIndex(startContainer); + startContainer = startContainer.parentNode; + } - queryCommandState : function() { - if (cmd = queryStateCommands[cmd.toLowerCase()]) - return cmd.func.call(scope || cmd.scope, ui, value, args); + // Setup index for endContainer + if (endContainer.nodeType == 1) { + endOffset = nodeIndex(endContainer) + 1; + endContainer = endContainer.parentNode; } - }); - }; - tinymce.GlobalCommands = new tinymce.CommandManager(); -})(tinymce);(function(tinymce) { - function processRange(dom, start, end, callback) { - var ancestor, n, startPoint, endPoint, sib; + // Return new range like object + return { + startContainer : startContainer, + startOffset : startOffset, + endContainer : endContainer, + endOffset : endOffset + }; + } - function findEndPoint(n, c) { - do { - if (n.parentNode == c) - return n; + function removeFormat(format, vars, node, compare_node) { + var i, attrs, stylesModified; - n = n.parentNode; - } while(n); - }; + // Check if node matches format + if (!matchName(node, format)) + return FALSE; - function process(n) { - callback(n); - tinymce.walk(n, callback, 'childNodes'); - }; + // Should we compare with format attribs and styles + if (format.remove != 'all') { + // Remove styles + each(format.styles, function(value, name) { + value = replaceVars(value, vars); - // Find common ancestor and end points - ancestor = dom.findCommonAncestor(start, end); - startPoint = findEndPoint(start, ancestor) || start; - endPoint = findEndPoint(end, ancestor) || end; + // Indexed array + if (typeof(name) === 'number') { + name = value; + compare_node = 0; + } - // Process left leaf - for (n = start; n && n != startPoint; n = n.parentNode) { - for (sib = n.nextSibling; sib; sib = sib.nextSibling) - process(sib); - } + if (!compare_node || isEq(getStyle(compare_node, name), value)) + dom.setStyle(node, name, ''); - // Process middle from start to end point - if (startPoint != endPoint) { - for (n = startPoint.nextSibling; n && n != endPoint; n = n.nextSibling) - process(n); - } else - process(startPoint); - - // Process right leaf - for (n = end; n && n != endPoint; n = n.parentNode) { - for (sib = n.previousSibling; sib; sib = sib.previousSibling) - process(sib); - } - }; + stylesModified = 1; + }); - tinymce.GlobalCommands.add('RemoveFormat', function() { - var ed = this, dom = ed.dom, s = ed.selection, r = s.getRng(1), nodes = [], bm, start, end, sc, so, ec, eo, n; + // Remove style attribute if it's empty + if (stylesModified && dom.getAttrib(node, 'style') == '') { + node.removeAttribute('style'); + node.removeAttribute('_mce_style'); + } - function findFormatRoot(n) { - var sp; + // Remove attributes + each(format.attributes, function(value, name) { + var valueOut; - dom.getParent(n, function(n) { - if (dom.is(n, ed.getParam('removeformat_selector'))) - sp = n; + value = replaceVars(value, vars); - return dom.isBlock(n); - }, ed.getBody()); + // Indexed array + if (typeof(name) === 'number') { + name = value; + compare_node = 0; + } - return sp; - }; + if (!compare_node || isEq(dom.getAttrib(compare_node, name), value)) { + // Keep internal classes + if (name == 'class') { + value = dom.getAttrib(node, name); + if (value) { + // Build new class value where everything is removed except the internal prefixed classes + valueOut = ''; + each(value.split(/\s+/), function(cls) { + if (/mce\w+/.test(cls)) + valueOut += (valueOut ? ' ' : '') + cls; + }); - function collect(n) { - if (dom.is(n, ed.getParam('removeformat_selector'))) - nodes.push(n); - }; + // We got some internal classes left + if (valueOut) { + dom.setAttrib(node, name, valueOut); + return; + } + } + } - function walk(n) { - collect(n); - tinymce.walk(n, collect, 'childNodes'); - }; + // IE6 has a bug where the attribute doesn't get removed correctly + if (name == "class") + node.removeAttribute('className'); - bm = s.getBookmark(); - sc = r.startContainer; - ec = r.endContainer; - so = r.startOffset; - eo = r.endOffset; - sc = sc.nodeType == 1 ? sc.childNodes[Math.min(so, sc.childNodes.length - 1)] : sc; - ec = ec.nodeType == 1 ? ec.childNodes[Math.min(so == eo ? eo : eo - 1, ec.childNodes.length - 1)] : ec; + // Remove mce prefixed attributes + if (MCE_ATTR_RE.test(name)) + node.removeAttribute('_mce_' + name); - // Same container - if (sc == ec) { // TEXT_NODE - start = findFormatRoot(sc); + node.removeAttribute(name); + } + }); - // Handle single text node - if (sc.nodeType == 3) { - if (start && start.nodeType == 1) { // ELEMENT - n = sc.splitText(so); - n.splitText(eo - so); - dom.split(start, n); + // Remove classes + each(format.classes, function(value) { + value = replaceVars(value, vars); + + if (!compare_node || dom.hasClass(compare_node, value)) + dom.removeClass(node, value); + }); - s.moveToBookmark(bm); + // Check for non internal attributes + attrs = dom.getAttribs(node); + for (i = 0; i < attrs.length; i++) { + if (attrs[i].nodeName.indexOf('_') !== 0) + return FALSE; } + } - return; + // Remove the inline child if it's empty for example or + if (format.remove != 'none') { + removeNode(node, format); + return TRUE; } + }; - // Handle single element - walk(dom.split(start, sc) || sc); - } else { - // Find start/end format root - start = findFormatRoot(sc); - end = findFormatRoot(ec); + function removeNode(node, format) { + var parentNode = node.parentNode, rootBlockElm; + + if (format.block) { + if (!forcedRootBlock) { + function find(node, next, inc) { + node = getNonWhiteSpaceSibling(node, next, inc); - // Split start text node - if (start) { - if (sc.nodeType == 3) { // TEXT - // Since IE doesn't support white space nodes in the DOM we need to - // add this invisible character so that the splitText function can split the contents - if (so == sc.nodeValue.length) - sc.nodeValue += '\uFEFF'; // Yet another pesky IE fix + return !node || (node.nodeName == 'BR' || isBlock(node)); + }; + + // Append BR elements if needed before we remove the block + if (isBlock(node) && !isBlock(parentNode)) { + if (!find(node, FALSE) && !find(node.firstChild, TRUE, 1)) + node.insertBefore(dom.create('br'), node.firstChild); - sc = sc.splitText(so); + if (!find(node, TRUE) && !find(node.lastChild, FALSE, 1)) + node.appendChild(dom.create('br')); + } + } else { + // Wrap the block in a forcedRootBlock if we are at the root of document + if (parentNode == dom.getRoot()) { + if (!format.list_block || !isEq(node, format.list_block)) { + each(tinymce.grep(node.childNodes), function(node) { + if (isValid(forcedRootBlock, node.nodeName.toLowerCase())) { + if (!rootBlockElm) + rootBlockElm = wrap(node, forcedRootBlock); + else + rootBlockElm.appendChild(node); + } else + rootBlockElm = 0; + }); + } + } } } - // Split end text node - if (end) { - if (ec.nodeType == 3) // TEXT - ec.splitText(eo); - } + // Never remove nodes that isn't the specified inline element if a selector is specified too + if (format.selector && format.inline && !isEq(format.inline, node)) + return; - // If the start and end format root is the same then we need to wrap - // the end node in a span since the split calls might change the reference - // Example:

x[yz---12]3

- if (start && start == end) - dom.replace(dom.create('span', {id : '__end'}, ec.cloneNode(true)), ec); + dom.remove(node, 1); + }; - // Split all start containers down to the format root - if (start) - start = dom.split(start, sc); - else - start = sc; + function getNonWhiteSpaceSibling(node, next, inc) { + if (node) { + next = next ? 'nextSibling' : 'previousSibling'; - // If there is a span wrapper use that one instead - if (n = dom.get('__end')) { - ec = n; - end = findFormatRoot(ec); + for (node = inc ? node : node[next]; node; node = node[next]) { + if (node.nodeType == 1 || !isWhiteSpaceNode(node)) + return node; + } } + }; - // Split all end containers down to the format root - if (end) - end = dom.split(end, ec); - else - end = ec; + function isBookmarkNode(node) { + return node && node.nodeType == 1 && node.getAttribute('_mce_type') == 'bookmark'; + }; - // Collect nodes in between - processRange(dom, start, end, collect); + function mergeSiblings(prev, next) { + var marker, sibling, tmpSibling; - // Remove invisible character for IE workaround if we find it - if (sc.nodeValue == '\uFEFF') - sc.nodeValue = ''; + function compareElements(node1, node2) { + // Not the same name + if (node1.nodeName != node2.nodeName) + return FALSE; - // Process start/end container elements - walk(ec); - walk(sc); - } + function getAttribs(node) { + var attribs = {}; - // Remove all collected nodes - tinymce.each(nodes, function(n) { - dom.remove(n, 1); - }); + each(dom.getAttribs(node), function(attr) { + var name = attr.nodeName.toLowerCase(); - // Remove leftover wrapper - dom.remove('__end', 1); + // Don't compare internal attributes or style + if (name.indexOf('_') !== 0 && name !== 'style') + attribs[name] = dom.getAttrib(node, name); + }); - s.moveToBookmark(bm); - }); -})(tinymce); -(function(tinymce) { - tinymce.GlobalCommands.add('mceBlockQuote', function() { - var ed = this, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl; + return attribs; + }; - function getBQ(e) { - return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';}); - }; + function compareObjects(obj1, obj2) { + var value, name; - // Get start/end block - sb = dom.getParent(s.getStart(), dom.isBlock); - eb = dom.getParent(s.getEnd(), dom.isBlock); + for (name in obj1) { + // Obj1 has item obj2 doesn't have + if (obj1.hasOwnProperty(name)) { + value = obj2[name]; - // Remove blockquote(s) - if (bq = getBQ(sb)) { - if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR')) - bm = s.getBookmark(); + // Obj2 doesn't have obj1 item + if (value === undefined) + return FALSE; - // Move all elements after the end block into new bq - if (getBQ(eb)) { - bq2 = bq.cloneNode(false); + // Obj2 item has a different value + if (obj1[name] != value) + return FALSE; - while (n = eb.nextSibling) - bq2.appendChild(n.parentNode.removeChild(n)); - } + // Delete similar value + delete obj2[name]; + } + } - // Add new bq after - if (bq2) - dom.insertAfter(bq2, bq); + // Check if obj 2 has something obj 1 doesn't have + for (name in obj2) { + // Obj2 has item obj1 doesn't have + if (obj2.hasOwnProperty(name)) + return FALSE; + } - // Move all selected blocks after the current bq - nl = s.getSelectedBlocks(sb, eb); - for (i = nl.length - 1; i >= 0; i--) { - dom.insertAfter(nl[i], bq); - } + return TRUE; + }; - // Empty bq, then remove it - if (/^\s*$/.test(bq.innerHTML)) - dom.remove(bq, 1); // Keep children so boomark restoration works correctly + // Attribs are not the same + if (!compareObjects(getAttribs(node1), getAttribs(node2))) + return FALSE; - // Empty bq, then remote it - if (bq2 && /^\s*$/.test(bq2.innerHTML)) - dom.remove(bq2, 1); // Keep children so boomark restoration works correctly + // Styles are not the same + if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) + return FALSE; - if (!bm) { - // Move caret inside empty block element - if (!tinymce.isIE) { - r = ed.getDoc().createRange(); - r.setStart(sb, 0); - r.setEnd(sb, 0); - s.setRng(r); - } else { - s.select(sb); - s.collapse(0); + return TRUE; + }; - // IE misses the empty block some times element so we must move back the caret - if (dom.getParent(s.getStart(), dom.isBlock) != sb) { - r = s.getRng(); - r.move('character', -1); - r.select(); + // Check if next/prev exists and that they are elements + if (prev && next) { + function findElementSibling(node, sibling_name) { + for (sibling = node; sibling; sibling = sibling[sibling_name]) { + if (sibling.nodeType == 3 && !isWhiteSpaceNode(sibling)) + return node; + + if (sibling.nodeType == 1 && !isBookmarkNode(sibling)) + return sibling; } - } - } else - ed.selection.moveToBookmark(bm); - return; - } + return node; + }; - // Since IE can start with a totally empty document we need to add the first bq and paragraph - if (tinymce.isIE && !sb && !eb) { - ed.getDoc().execCommand('Indent'); - n = getBQ(s.getNode()); - n.style.margin = n.dir = ''; // IE adds margin and dir to bq - return; - } + // If previous sibling is empty then jump over it + prev = findElementSibling(prev, 'previousSibling'); + next = findElementSibling(next, 'nextSibling'); + + // Compare next and previous nodes + if (compareElements(prev, next)) { + // Append nodes between + for (sibling = prev.nextSibling; sibling && sibling != next;) { + tmpSibling = sibling; + sibling = sibling.nextSibling; + prev.appendChild(tmpSibling); + } - if (!sb || !eb) - return; + // Remove next node + dom.remove(next); - // If empty paragraph node then do not use bookmark - if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR')) - bm = s.getBookmark(); + // Move children into prev node + each(tinymce.grep(next.childNodes), function(node) { + prev.appendChild(node); + }); - // Move selected block elements into a bq - tinymce.each(s.getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) { - // Found existing BQ add to this one - if (e.nodeName == 'BLOCKQUOTE' && !bq) { - bq = e; - return; + return prev; + } } - // No BQ found, create one - if (!bq) { - bq = dom.create('blockquote'); - e.parentNode.insertBefore(bq, e); + return next; + }; + + function isTextBlock(name) { + return /^(h[1-6]|p|div|pre|address)$/.test(name); + }; + + function getContainer(rng, start) { + var container, offset, lastIdx; + + container = rng[start ? 'startContainer' : 'endContainer']; + offset = rng[start ? 'startOffset' : 'endOffset']; + + if (container.nodeType == 1) { + lastIdx = container.childNodes.length - 1; + + if (!start && offset) + offset--; + + container = container.childNodes[offset > lastIdx ? lastIdx : offset]; } - // Add children from existing BQ - if (e.nodeName == 'BLOCKQUOTE' && bq) { - n = e.firstChild; + return container; + }; - while (n) { - bq.appendChild(n.cloneNode(true)); - n = n.nextSibling; - } + function performCaretAction(type, name, vars) { + var i, currentPendingFormats = pendingFormats[type], + otherPendingFormats = pendingFormats[type == 'apply' ? 'remove' : 'apply']; - dom.remove(e); - return; + function hasPending() { + return pendingFormats.apply.length || pendingFormats.remove.length; + }; + + function resetPending() { + pendingFormats.apply = []; + pendingFormats.remove = []; + }; + + function perform(caret_node) { + // Apply pending formats + each(pendingFormats.apply.reverse(), function(item) { + apply(item.name, item.vars, caret_node); + }); + + // Remove pending formats + each(pendingFormats.remove.reverse(), function(item) { + remove(item.name, item.vars, caret_node); + }); + + dom.remove(caret_node, 1); + resetPending(); + }; + + // Check if it already exists then ignore it + for (i = currentPendingFormats.length - 1; i >= 0; i--) { + if (currentPendingFormats[i].name == name) + return; } - // Add non BQ element to BQ - bq.appendChild(dom.remove(e)); - }); + currentPendingFormats.push({name : name, vars : vars}); - if (!bm) { - // Move caret inside empty block element - if (!tinymce.isIE) { - r = ed.getDoc().createRange(); - r.setStart(sb, 0); - r.setEnd(sb, 0); - s.setRng(r); - } else { - s.select(sb); - s.collapse(1); + // Check if it's in the other type, then remove it + for (i = otherPendingFormats.length - 1; i >= 0; i--) { + if (otherPendingFormats[i].name == name) + otherPendingFormats.splice(i, 1); } - } else - s.moveToBookmark(bm); - }); -})(tinymce); -(function(tinymce) { - tinymce.each(['Cut', 'Copy', 'Paste'], function(cmd) { - tinymce.GlobalCommands.add(cmd, function() { - var ed = this, doc = ed.getDoc(); - try { - doc.execCommand(cmd, false, null); + // Pending apply or remove formats + if (hasPending()) { + ed.getDoc().execCommand('FontName', false, 'mceinline'); - // On WebKit the command will just be ignored if it's not enabled - if (!doc.queryCommandEnabled(cmd)) - throw 'Error'; - } catch (ex) { - if (tinymce.isGecko) { - ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) { - if (s) - open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', '_blank'); + // IE will convert the current word + each(dom.select('font,span'), function(node) { + var bookmark; + + if (isCaretNode(node)) { + bookmark = selection.getBookmark(); + perform(node); + selection.moveToBookmark(bookmark); + ed.nodeChanged(); + } + }); + + // Only register listeners once if we need to + if (!pendingFormats.isListening && hasPending()) { + pendingFormats.isListening = true; + + each('onKeyDown,onKeyUp,onKeyPress,onMouseUp'.split(','), function(event) { + ed[event].addToTop(function(ed, e) { + if (hasPending()) { + each(dom.select('font,span'), function(node) { + var bookmark, textNode, rng; + + // Look for marker + if (isCaretNode(node)) { + textNode = node.firstChild; + + perform(node); + + rng = dom.createRng(); + rng.setStart(textNode, textNode.nodeValue.length); + rng.setEnd(textNode, textNode.nodeValue.length); + selection.setRng(rng); + ed.nodeChanged(); + } + }); + + // Always unbind and clear pending styles on keyup + if (e.type == 'keyup' || e.type == 'mouseup') + resetPending(); + } + }); }); - } else - ed.windowManager.alert(ed.getLang('clipboard_no_support')); + } } - }); - }); + }; + }; })(tinymce); -(function(tinymce) { - tinymce.GlobalCommands.add('InsertHorizontalRule', function() { - if (tinymce.isOpera) - return this.getDoc().execCommand('InsertHorizontalRule', false, ''); - this.selection.setContent('
'); - }); -})(tinymce); -(function() { - var cmds = tinymce.GlobalCommands; +tinymce.onAddEditor.add(function(tinymce, ed) { + var filters, fontSizes, dom, settings = ed.settings; - cmds.add(['mceEndUndoLevel', 'mceAddUndoLevel'], function() { - this.undoManager.add(); - }); + if (settings.inline_styles) { + fontSizes = tinymce.explode(settings.font_size_style_values); - cmds.add('Undo', function() { - var ed = this; + function replaceWithSpan(node, styles) { + dom.replace(dom.create('span', { + style : styles + }), node, 1); + }; - if (ed.settings.custom_undo_redo) { - ed.undoManager.undo(); - ed.nodeChanged(); - return true; - } + filters = { + font : function(dom, node) { + replaceWithSpan(node, { + backgroundColor : node.style.backgroundColor, + color : node.color, + fontFamily : node.face, + fontSize : fontSizes[parseInt(node.size) - 1] + }); + }, - return false; // Run browser command - }); + u : function(dom, node) { + replaceWithSpan(node, { + textDecoration : 'underline' + }); + }, - cmds.add('Redo', function() { - var ed = this; + strike : function(dom, node) { + replaceWithSpan(node, { + textDecoration : 'line-through' + }); + } + }; - if (ed.settings.custom_undo_redo) { - ed.undoManager.redo(); - ed.nodeChanged(); - return true; - } + function convert(editor, params) { + dom = editor.dom; + + if (settings.convert_fonts_to_spans) { + tinymce.each(dom.select('font,u,strike', params.node), function(node) { + filters[node.nodeName.toLowerCase()](ed.dom, node); + }); + } + }; + + ed.onPreProcess.add(convert); + + ed.onInit.add(function() { + ed.selection.onSetContent.add(convert); + }); + } +}); - return false; // Run browser command - }); -})(); diff --git a/program/js/tiny_mce/utils/editable_selects.js b/program/js/tiny_mce/utils/editable_selects.js index fff496392..fd943c0f8 100644 --- a/program/js/tiny_mce/utils/editable_selects.js +++ b/program/js/tiny_mce/utils/editable_selects.js @@ -1,10 +1,11 @@ /** - * $Id: editable_selects.js 867 2008-06-09 20:33:40Z spocke $ + * editable_selects.js * - * Makes select boxes editable. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ var TinyMCE_EditableSelects = { diff --git a/program/js/tiny_mce/utils/form_utils.js b/program/js/tiny_mce/utils/form_utils.js index 9bc2bad4b..2617a26ed 100644 --- a/program/js/tiny_mce/utils/form_utils.js +++ b/program/js/tiny_mce/utils/form_utils.js @@ -1,10 +1,11 @@ /** - * $Id: form_utils.js 1184 2009-08-11 11:47:27Z spocke $ + * form_utils.js * - * Various form utilitiy functions. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ var themeBaseURL = tinyMCEPopup.editor.baseURI.toAbsolute('themes/' + tinyMCEPopup.getParam("theme")); diff --git a/program/js/tiny_mce/utils/mctabs.js b/program/js/tiny_mce/utils/mctabs.js index 284501ee9..825d4c143 100644 --- a/program/js/tiny_mce/utils/mctabs.js +++ b/program/js/tiny_mce/utils/mctabs.js @@ -1,10 +1,11 @@ /** - * $Id: mctabs.js 758 2008-03-30 13:53:29Z spocke $ + * mctabs.js * - * Moxiecode DHTML Tabs script. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ function MCTabs() { diff --git a/program/js/tiny_mce/utils/validate.js b/program/js/tiny_mce/utils/validate.js index cde4c9798..a6fcf9701 100644 --- a/program/js/tiny_mce/utils/validate.js +++ b/program/js/tiny_mce/utils/validate.js @@ -1,10 +1,11 @@ /** - * $Id: validate.js 758 2008-03-30 13:53:29Z spocke $ + * validate.js * - * Various form validation methods. + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. * - * @author Moxiecode - * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing */ /** -- cgit v1.2.3