Changeset 6632
- Timestamp:
- 01/17/2008 03:44:05 PM (17 years ago)
- Location:
- trunk/wp-includes
- Files:
-
- 80 added
- 42 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-includes/formatting.php
r6613 r6632 68 68 $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee); 69 69 $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines 70 if ( strpos($pee, '<object') !== false ) { 71 $pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed 72 $pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee); 73 } 70 74 $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates 71 75 $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end -
trunk/wp-includes/general-template.php
r6609 r6632 953 953 <script type="text/javascript"> 954 954 // <![CDATA[ 955 if ( typeof tinyMCE != "undefined" && tinyMCE.configs.length > 0)955 if ( typeof tinyMCE != "undefined" ) 956 956 document.getElementById('editor-toolbar').style.display = 'block'; 957 957 // ]]> … … 968 968 <script type="text/javascript"> 969 969 // <![CDATA[ 970 if ( typeof tinyMCE != "undefined" && tinyMCE.configs.length > 0)970 if ( typeof tinyMCE != "undefined" ) 971 971 document.getElementById("quicktags").style.display="none"; 972 972 // ]]> -
trunk/wp-includes/js/tinymce/langs/en.js
r4747 r6632 1 // UK lang variables 2 3 tinyMCE.addToLang('',{ 4 bold_desc : 'Bold (Ctrl+B)', 5 italic_desc : 'Italic (Ctrl+I)', 6 underline_desc : 'Underline (Ctrl+U)', 7 striketrough_desc : 'Strikethrough', 8 justifyleft_desc : 'Align left', 9 justifycenter_desc : 'Align center', 10 justifyright_desc : 'Align right', 11 justifyfull_desc : 'Align full', 12 bullist_desc : 'Unordered list', 13 numlist_desc : 'Ordered list', 14 outdent_desc : 'Outdent', 15 indent_desc : 'Indent', 16 undo_desc : 'Undo (Ctrl+Z)', 17 redo_desc : 'Redo (Ctrl+Y)', 18 link_desc : 'Insert/edit link', 19 unlink_desc : 'Unlink', 20 image_desc : 'Insert/edit image', 21 cleanup_desc : 'Cleanup messy code', 22 focus_alert : 'A editor instance must be focused before using this command.', 23 edit_confirm : 'Do you want to use the WYSIWYG mode for this textarea?', 24 insert_link_title : 'Insert/edit link', 25 insert : 'Insert', 26 update : 'Update', 27 cancel : 'Cancel', 28 insert_link_url : 'Link URL', 29 insert_link_target : 'Target', 30 insert_link_target_same : 'Open link in the same window', 31 insert_link_target_blank : 'Open link in a new window', 32 insert_image_title : 'Insert/edit image', 33 insert_image_src : 'Image URL', 34 insert_image_alt : 'Image description', 35 help_desc : 'Help', 36 bold_img : "bold.gif", 37 italic_img : "italic.gif", 38 underline_img : "underline.gif", 39 clipboard_msg : 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?', 40 popup_blocked : 'Sorry, but we have noticed that your popup-blocker has disabled a window that provides application functionality. You will need to disable popup blocking on this site in order to fully utilize this tool.' 41 }); 1 tinyMCE.addI18n({en:{ 2 common:{ 3 edit_confirm:"Do you want to use the WYSIWYG mode for this textarea?", 4 apply:"Apply", 5 insert:"Insert", 6 update:"Update", 7 cancel:"Cancel", 8 close:"Close", 9 browse:"Browse", 10 class_name:"Class", 11 not_set:"-- Not set --", 12 clipboard_msg:"Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?", 13 clipboard_no_support:"Currently not supported by your browser, use keyboard shortcuts instead.", 14 popup_blocked:"Sorry, but we have noticed that your popup-blocker has disabled a window that provides application functionality. You will need to disable popup blocking on this site in order to fully utilize this tool.", 15 invalid_data:"Error: Invalid values entered, these are marked in red.", 16 more_colors:"More colors" 17 }, 18 contextmenu:{ 19 align:"Alignment", 20 left:"Left", 21 center:"Center", 22 right:"Right", 23 full:"Full" 24 }, 25 insertdatetime:{ 26 date_fmt:"%Y-%m-%d", 27 time_fmt:"%H:%M:%S", 28 insertdate_desc:"Insert date", 29 inserttime_desc:"Insert time", 30 months_long:"January,February,March,April,May,June,July,August,September,October,November,December", 31 months_short:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", 32 day_long:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday", 33 day_short:"Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun" 34 }, 35 print:{ 36 print_desc:"Print" 37 }, 38 preview:{ 39 preview_desc:"Preview" 40 }, 41 directionality:{ 42 ltr_desc:"Direction left to right", 43 rtl_desc:"Direction right to left" 44 }, 45 layer:{ 46 insertlayer_desc:"Insert new layer", 47 forward_desc:"Move forward", 48 backward_desc:"Move backward", 49 absolute_desc:"Toggle absolute positioning", 50 content:"New layer..." 51 }, 52 save:{ 53 save_desc:"Save", 54 cancel_desc:"Cancel all changes" 55 }, 56 nonbreaking:{ 57 nonbreaking_desc:"Insert non-breaking space character" 58 }, 59 iespell:{ 60 iespell_desc:"Run spell checking", 61 download:"ieSpell not detected. Do you want to install it now?" 62 }, 63 advhr:{ 64 advhr_desc:"Horizontale rule" 65 }, 66 emotions:{ 67 emotions_desc:"Emotions" 68 }, 69 searchreplace:{ 70 search_desc:"Find", 71 replace_desc:"Find/Replace" 72 }, 73 advimage:{ 74 image_desc:"Insert/edit image" 75 }, 76 advlink:{ 77 link_desc:"Insert/edit link" 78 }, 79 xhtmlxtras:{ 80 cite_desc:"Citation", 81 abbr_desc:"Abbreviation", 82 acronym_desc:"Acronym", 83 del_desc:"Deletion", 84 ins_desc:"Insertion", 85 attribs_desc:"Insert/Edit Attributes" 86 }, 87 style:{ 88 desc:"Edit CSS Style" 89 }, 90 paste:{ 91 paste_text_desc:"Paste as Plain Text", 92 paste_word_desc:"Paste from Word", 93 selectall_desc:"Select All" 94 }, 95 paste_dlg:{ 96 text_title:"Use CTRL+V on your keyboard to paste the text into the window.", 97 text_linebreaks:"Keep linebreaks", 98 word_title:"Use CTRL+V on your keyboard to paste the text into the window." 99 }, 100 table:{ 101 desc:"Inserts a new table", 102 row_before_desc:"Insert row before", 103 row_after_desc:"Insert row after", 104 delete_row_desc:"Delete row", 105 col_before_desc:"Insert column before", 106 col_after_desc:"Insert column after", 107 delete_col_desc:"Remove column", 108 split_cells_desc:"Split merged table cells", 109 merge_cells_desc:"Merge table cells", 110 row_desc:"Table row properties", 111 cell_desc:"Table cell properties", 112 props_desc:"Table properties", 113 paste_row_before_desc:"Paste table row before", 114 paste_row_after_desc:"Paste table row after", 115 cut_row_desc:"Cut table row", 116 copy_row_desc:"Copy table row", 117 del:"Delete table", 118 row:"Row", 119 col:"Column", 120 cell:"Cell" 121 }, 122 autosave:{ 123 unload_msg:"The changes you made will be lost if you navigate away from this page." 124 }, 125 fullscreen:{ 126 desc:"Toggle fullscreen mode" 127 }, 128 media:{ 129 desc:"Insert / edit embedded media", 130 edit:"Edit embedded media" 131 }, 132 fullpage:{ 133 desc:"Document properties" 134 }, 135 template:{ 136 desc:"Insert predefined template content" 137 }, 138 visualchars:{ 139 desc:"Visual control characters on/off." 140 }, 141 spellchecker:{ 142 desc:"Toggle spellchecker", 143 menu:"Spellchecker settings", 144 ignore_word:"Ignore word", 145 ignore_words:"Ignore all", 146 langs:"Languages", 147 wait:"Please wait...", 148 sug:"Suggestions", 149 no_sug:"No suggestions", 150 no_mpell:"No misspellings found." 151 }, 152 pagebreak:{ 153 desc:"Insert page break." 154 }}}); -
trunk/wp-includes/js/tinymce/plugins/autosave/editor_plugin.js
r5256 r6632 1 1 /** 2 * $Id : editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke$2 * $Id$ 3 3 * 4 4 * @author Moxiecode 5 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 6 6 */ 7 7 8 /* Import plugin specific language pack */ 9 tinyMCE.importPluginLanguagePack('autosave'); 8 (function() { 9 tinymce.create('tinymce.plugins.AutoSavePlugin', { 10 init : function(ed, url) { 11 var t = this; 10 12 11 var TinyMCE_AutoSavePlugin = { 12 getInfo : function() { 13 return { 14 longname : 'Auto save', 15 author : 'Moxiecode Systems AB', 16 authorurl : 'http://tinymce.moxiecode.com', 17 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave', 18 version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion 19 }; 20 }, 13 t.editor = ed; 21 14 22 // Private plugin internal methods 15 window.onbeforeunload = tinymce.plugins.AutoSavePlugin._beforeUnloadHandler; 16 }, 23 17 24 _beforeUnloadHandler : function() { 25 var n, inst, anyDirty = false, msg = tinyMCE.getLang("lang_autosave_unload_msg"); 18 getInfo : function() { 19 return { 20 longname : 'Auto save', 21 author : 'Moxiecode Systems AB', 22 authorurl : 'http://tinymce.moxiecode.com', 23 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave', 24 version : tinymce.majorVersion + "." + tinymce.minorVersion 25 }; 26 }, 26 27 27 if (tinyMCE.getParam("fullscreen_is_enabled")) 28 return; 28 // Private plugin internal methods 29 29 30 for (n in tinyMCE.instances) { 31 inst = tinyMCE.instances[n]; 30 'static' : { 31 _beforeUnloadHandler : function() { 32 var msg; 32 33 33 if (!tinyMCE.isInstance(inst)) 34 continue; 34 tinymce.each(tinyMCE.editors, function(ed) { 35 if (ed.getParam("fullscreen_is_enabled")) 36 return; 35 37 36 if (inst.isDirty()) 38 if (ed.isDirty()) { 39 msg = ed.getLang("autosave.unload_msg"); 40 return false; 41 } 42 }); 43 37 44 return msg; 45 } 38 46 } 47 }); 39 48 40 return; 41 } 42 }; 43 44 window.onbeforeunload = TinyMCE_AutoSavePlugin._beforeUnloadHandler; 45 46 tinyMCE.addPlugin("autosave", TinyMCE_AutoSavePlugin); 49 // Register plugin 50 tinymce.PluginManager.add('autosave', tinymce.plugins.AutoSavePlugin); 51 })(); -
trunk/wp-includes/js/tinymce/plugins/directionality/editor_plugin.js
r5256 r6632 1 1 /** 2 * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $2 * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * @author Moxiecode 5 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 6 6 */ 7 7 8 /* Import plugin specific language pack */ 9 tinyMCE.importPluginLanguagePack('directionality'); 8 (function() { 9 tinymce.create('tinymce.plugins.Directionality', { 10 init : function(ed, url) { 11 var t = this; 10 12 11 var TinyMCE_DirectionalityPlugin = { 12 getInfo : function() { 13 return { 14 longname : 'Directionality', 15 author : 'Moxiecode Systems AB', 16 authorurl : 'http://tinymce.moxiecode.com', 17 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality', 18 version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion 19 }; 20 }, 13 t.editor = ed; 21 14 22 getControlHTML : function(cn) { 23 switch (cn) { 24 case "ltr": 25 return tinyMCE.getButtonHTML(cn, 'lang_directionality_ltr_desc', '{$pluginurl}/images/ltr.gif', 'mceDirectionLTR'); 15 ed.addCommand('mceDirectionLTR', function() { 16 var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); 26 17 27 case "rtl": 28 return tinyMCE.getButtonHTML(cn, 'lang_directionality_rtl_desc', '{$pluginurl}/images/rtl.gif', 'mceDirectionRTL'); 18 if (e) { 19 if (ed.dom.getAttrib(e, "dir") != "ltr") 20 ed.dom.setAttrib(e, "dir", "ltr"); 21 else 22 ed.dom.setAttrib(e, "dir", ""); 23 } 24 25 ed.nodeChanged(); 26 }); 27 28 ed.addCommand('mceDirectionRTL', function() { 29 var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); 30 31 if (e) { 32 if (ed.dom.getAttrib(e, "dir") != "rtl") 33 ed.dom.setAttrib(e, "dir", "rtl"); 34 else 35 ed.dom.setAttrib(e, "dir", ""); 36 } 37 38 ed.nodeChanged(); 39 }); 40 41 ed.addButton('ltr', {title : 'directionality.ltr_desc', cmd : 'mceDirectionLTR'}); 42 ed.addButton('rtl', {title : 'directionality.rtl_desc', cmd : 'mceDirectionRTL'}); 43 44 ed.onNodeChange.add(t._nodeChange, t); 45 }, 46 47 getInfo : function() { 48 return { 49 longname : 'Directionality', 50 author : 'Moxiecode Systems AB', 51 authorurl : 'http://tinymce.moxiecode.com', 52 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality', 53 version : tinymce.majorVersion + "." + tinymce.minorVersion 54 }; 55 }, 56 57 // Private methods 58 59 _nodeChange : function(ed, cm, n) { 60 var dom = ed.dom, dir; 61 62 n = dom.getParent(n, dom.isBlock); 63 if (!n) { 64 cm.setDisabled('ltr', 1); 65 cm.setDisabled('rtl', 1); 66 return; 67 } 68 69 dir = dom.getAttrib(n, 'dir'); 70 cm.setActive('ltr', dir == "ltr"); 71 cm.setDisabled('ltr', 0); 72 cm.setActive('rtl', dir == "rtl"); 73 cm.setDisabled('rtl', 0); 29 74 } 75 }); 30 76 31 return ""; 32 }, 33 34 execCommand : function(editor_id, element, command, user_interface, value) { 35 // Handle commands 36 switch (command) { 37 case "mceDirectionLTR": 38 var inst = tinyMCE.getInstanceById(editor_id); 39 var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address"); 40 41 if (elm) 42 elm.setAttribute("dir", "ltr"); 43 44 tinyMCE.triggerNodeChange(false); 45 return true; 46 47 case "mceDirectionRTL": 48 var inst = tinyMCE.getInstanceById(editor_id); 49 var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address"); 50 51 if (elm) 52 elm.setAttribute("dir", "rtl"); 53 54 tinyMCE.triggerNodeChange(false); 55 return true; 56 } 57 58 // Pass to next handler in chain 59 return false; 60 }, 61 62 handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { 63 function getAttrib(elm, name) { 64 return elm.getAttribute(name) ? elm.getAttribute(name) : ""; 65 } 66 67 if (node == null) 68 return; 69 70 var elm = tinyMCE.getParentElement(node, "p,div,td,h1,h2,h3,h4,h5,h6,pre,address"); 71 if (!elm) { 72 tinyMCE.switchClass(editor_id + '_ltr', 'mceButtonDisabled'); 73 tinyMCE.switchClass(editor_id + '_rtl', 'mceButtonDisabled'); 74 return true; 75 } 76 77 tinyMCE.switchClass(editor_id + '_ltr', 'mceButtonNormal'); 78 tinyMCE.switchClass(editor_id + '_rtl', 'mceButtonNormal'); 79 80 var dir = getAttrib(elm, "dir"); 81 if (dir == "ltr" || dir == "") 82 tinyMCE.switchClass(editor_id + '_ltr', 'mceButtonSelected'); 83 else 84 tinyMCE.switchClass(editor_id + '_rtl', 'mceButtonSelected'); 85 86 return true; 87 } 88 }; 89 90 tinyMCE.addPlugin("directionality", TinyMCE_DirectionalityPlugin); 77 // Register plugin 78 tinymce.PluginManager.add('directionality', tinymce.plugins.Directionality); 79 })(); -
trunk/wp-includes/js/tinymce/plugins/inlinepopups/css/inlinepopup.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js
r6568 r6632 1 1 /** 2 * $Id: editor_plugin_src.js 268 2007-04-28 15:52:59Z spocke $ 3 * 4 * Moxiecode DHTML Windows script. 2 * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ 5 3 * 6 4 * @author Moxiecode 7 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 8 6 */ 9 7 10 // Patch openWindow, closeWindow TinyMCE functions 11 12 var TinyMCE_InlinePopupsPlugin = { 13 getInfo : function() { 14 return { 15 longname : 'Inline Popups', 16 author : 'Moxiecode Systems AB', 17 authorurl : 'http://tinymce.moxiecode.com', 18 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups', 19 version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion 20 }; 21 } 22 }; 23 24 tinyMCE.addPlugin("inlinepopups", TinyMCE_InlinePopupsPlugin); 25 26 // Patch openWindow, closeWindow TinyMCE functions 27 28 TinyMCE_Engine.prototype.orgOpenWindow = TinyMCE_Engine.prototype.openWindow; 29 TinyMCE_Engine.prototype.orgCloseWindow = TinyMCE_Engine.prototype.closeWindow; 30 31 TinyMCE_Engine.prototype.openWindow = function(template, args) { 32 // Does the caller support inline 33 if (args['inline'] != "yes" || tinyMCE.isOpera || tinyMCE.getParam("plugins").indexOf('inlinepopups') == -1) { 34 mcWindows.selectedWindow = null; 35 args['mce_inside_iframe'] = false; 36 this.orgOpenWindow(template, args); 37 return; 38 } 39 40 var url, resizable, scrollbars; 41 42 args['mce_inside_iframe'] = true; 43 tinyMCE.windowArgs = args; 44 45 if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1) 46 url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file']; 47 else 48 url = template['file']; 49 50 if (!(width = parseInt(template['width']))) 51 width = 320; 52 53 if (!(height = parseInt(template['height']))) 54 height = 200; 55 56 if (!(minWidth = parseInt(template['minWidth']))) 57 minWidth = 100; 58 59 if (!(minHeight = parseInt(template['minHeight']))) 60 minHeight = 100; 61 62 resizable = (args && args['resizable']) ? args['resizable'] : "no"; 63 scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no"; 64 65 height += 18; 66 67 // Replace all args as variables in URL 68 for (var name in args) { 69 if (typeof(args[name]) == 'function') 70 continue; 71 72 url = tinyMCE.replaceVar(url, name, escape(args[name])); 73 } 74 75 var elm = document.getElementById(this.selectedInstance.editorId + '_parent'); 76 77 if (tinyMCE.hasPlugin('fullscreen') && this.selectedInstance.getData('fullscreen').enabled) 78 pos = { absLeft: 0, absTop: 0 }; 79 else 80 pos = tinyMCE.getAbsPosition(elm); 81 82 // Center div in editor area 83 pos.absLeft += Math.round((elm.firstChild.clientWidth / 2) - (width / 2)); 84 pos.absTop += Math.round((elm.firstChild.clientHeight / 2) - (height / 2)); 8 (function() { 9 var DOM = tinymce.DOM, Element = tinymce.dom.Element, Event = tinymce.dom.Event, each = tinymce.each, is = tinymce.is; 10 11 tinymce.create('tinymce.plugins.InlinePopups', { 12 init : function(ed, url) { 13 // Replace window manager 14 ed.onBeforeRenderUI.add(function() { 15 ed.windowManager = new tinymce.InlineWindowManager(ed); 16 DOM.loadCSS(url + '/skins/' + (ed.settings.inlinepopups_skin || 'clearlooks2') + "/window.css"); 17 }); 18 }, 19 20 getInfo : function() { 21 return { 22 longname : 'InlinePopups', 23 author : 'Moxiecode Systems AB', 24 authorurl : 'http://tinymce.moxiecode.com', 25 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups', 26 version : tinymce.majorVersion + "." + tinymce.minorVersion 27 }; 28 } 29 }); 30 31 tinymce.create('tinymce.InlineWindowManager:tinymce.WindowManager', { 32 InlineWindowManager : function(ed) { 33 var t = this; 34 35 t.parent(ed); 36 t.zIndex = 1000; 37 }, 38 39 open : function(f, p) { 40 var t = this, id, opt = '', ed = t.editor, dw = 0, dh = 0, vp, po, mdf, clf, we, w; 41 42 f = f || {}; 43 p = p || {}; 44 45 // Run native windows 46 if (!f.inline) 47 return t.parent(f, p); 48 49 t.bookmark = ed.selection.getBookmark('simple'); 50 id = DOM.uniqueId(); 51 vp = DOM.getViewPort(); 52 f.width = parseInt(f.width || 320); 53 f.height = parseInt(f.height || 240) + (tinymce.isIE ? 8 : 0); 54 f.min_width = parseInt(f.min_width || 150); 55 f.min_height = parseInt(f.min_height || 100); 56 f.max_width = parseInt(f.max_width || 2000); 57 f.max_height = parseInt(f.max_height || 2000); 58 f.left = f.left || Math.round(Math.max(vp.x, vp.x + (vp.w / 2.0) - (f.width / 2.0))); 59 f.top = f.top || Math.round(Math.max(vp.y, vp.y + (vp.h / 2.0) - (f.height / 2.0))); 60 f.movable = f.resizable = true; 61 p.mce_width = f.width; 62 p.mce_height = f.height; 63 p.mce_inline = true; 64 p.mce_window_id = id; 65 66 // Transpose 67 // po = DOM.getPos(ed.getContainer()); 68 // f.left -= po.x; 69 // f.top -= po.y; 70 71 t.features = f; 72 t.params = p; 73 t.onOpen.dispatch(t, f, p); 74 75 if (f.type) { 76 opt += ' modal ' + f.type; 77 f.resizable = false; 78 } 79 80 if (f.statusbar) 81 opt += ' statusbar'; 82 83 if (f.resizable) 84 opt += ' resizable'; 85 86 if (f.minimizable) 87 opt += ' minimizable'; 88 89 if (f.maximizable) 90 opt += ' maximizable'; 91 92 if (f.movable) 93 opt += ' movable'; 94 95 // Create DOM objects 96 t._addAll(document.body, 97 ['div', {id : id, 'class' : ed.settings.inlinepopups_skin || 'clearlooks2', style : 'width:100px;height:100px'}, 98 ['div', {id : id + '_wrapper', 'class' : 'wrapper' + opt}, 99 ['div', {id : id + '_top', 'class' : 'top'}, 100 ['div', {'class' : 'left'}], 101 ['div', {'class' : 'center'}], 102 ['div', {'class' : 'right'}], 103 ['span', {id : id + '_title'}, f.title || ''] 104 ], 105 106 ['div', {id : id + '_middle', 'class' : 'middle'}, 107 ['div', {id : id + '_left', 'class' : 'left'}], 108 ['span', {id : id + '_content'}], 109 ['div', {id : id + '_right', 'class' : 'right'}] 110 ], 111 112 ['div', {id : id + '_bottom', 'class' : 'bottom'}, 113 ['div', {'class' : 'left'}], 114 ['div', {'class' : 'center'}], 115 ['div', {'class' : 'right'}], 116 ['span', {id : id + '_status'}, 'Content'] 117 ], 118 119 ['a', {'class' : 'move', href : 'javascript:;'}], 120 ['a', {'class' : 'min', href : 'javascript:;', onmousedown : 'return false;'}], 121 ['a', {'class' : 'max', href : 'javascript:;', onmousedown : 'return false;'}], 122 ['a', {'class' : 'med', href : 'javascript:;', onmousedown : 'return false;'}], 123 ['a', {'class' : 'close', href : 'javascript:;', onmousedown : 'return false;'}], 124 ['a', {id : id + '_resize_n', 'class' : 'resize resize-n', href : 'javascript:;'}], 125 ['a', {id : id + '_resize_s', 'class' : 'resize resize-s', href : 'javascript:;'}], 126 ['a', {id : id + '_resize_w', 'class' : 'resize resize-w', href : 'javascript:;'}], 127 ['a', {id : id + '_resize_e', 'class' : 'resize resize-e', href : 'javascript:;'}], 128 ['a', {id : id + '_resize_nw', 'class' : 'resize resize-nw', href : 'javascript:;'}], 129 ['a', {id : id + '_resize_ne', 'class' : 'resize resize-ne', href : 'javascript:;'}], 130 ['a', {id : id + '_resize_sw', 'class' : 'resize resize-sw', href : 'javascript:;'}], 131 ['a', {id : id + '_resize_se', 'class' : 'resize resize-se', href : 'javascript:;'}] 132 ] 133 ] 134 ); 135 136 DOM.setStyles(id, {top : -10000, left : -10000}); 137 138 // Fix gecko rendering bug, where the editors iframe messed with window contents 139 if (tinymce.isGecko) 140 DOM.setStyle(id, 'overflow', 'auto'); 141 142 // Measure borders 143 if (!f.type) { 144 dw += DOM.get(id + '_left').clientWidth; 145 dw += DOM.get(id + '_right').clientWidth; 146 dh += DOM.get(id + '_top').clientHeight; 147 dh += DOM.get(id + '_bottom').clientHeight; 148 } 149 150 // Resize window 151 DOM.setStyles(id, {top : f.top, left : f.left, width : f.width + dw, height : f.height + dh}); 152 153 if (!f.type) { 154 DOM.add(id + '_content', 'iframe', {id : id + '_ifr', src : 'javascript:""', frameBorder : 0, style : 'border:0;width:10px;height:10px'}); 155 DOM.setStyles(id + '_ifr', {width : f.width, height : f.height}); 156 DOM.setAttrib(id + '_ifr', 'src', f.url || f.file); 157 } else { 158 DOM.add(id + '_wrapper', 'a', {id : id + '_ok', 'class' : 'button ok', href : 'javascript:;', onmousedown : 'return false;'}, 'Ok'); 159 160 if (f.type == 'confirm') 161 DOM.add(id + '_wrapper', 'a', {'class' : 'button cancel', href : 'javascript:;', onmousedown : 'return false;'}, 'Cancel'); 162 163 DOM.add(id + '_middle', 'div', {'class' : 'icon'}); 164 DOM.setHTML(id + '_content', f.content.replace('\n', '<br />')); 165 } 166 167 // Register events 168 mdf = Event.add(id, 'mousedown', function(e) { 169 var n = e.target, w, vp; 170 171 w = t.windows[id]; 172 t.focus(id); 173 174 if (n.nodeName == 'A' || n.nodeName == 'a') { 175 if (n.className == 'max') { 176 w.oldPos = w.element.getXY(); 177 w.oldSize = w.element.getSize(); 178 179 vp = DOM.getViewPort(); 180 181 // Reduce viewport size to avoid scrollbars 182 vp.w -= 2; 183 vp.h -= 2; 184 185 w.element.moveTo(vp.x, vp.y); 186 w.element.resizeTo(vp.w, vp.h); 187 DOM.setStyles(id + '_ifr', {width : vp.w - w.deltaWidth, height : vp.h - w.deltaHeight}); 188 DOM.addClass(id + '_wrapper', 'maximized'); 189 } else if (n.className == 'med') { 190 // Reset to old size 191 w.element.moveTo(w.oldPos.x, w.oldPos.y); 192 w.element.resizeTo(w.oldSize.w, w.oldSize.h); 193 w.iframeElement.resizeTo(w.oldSize.w - w.deltaWidth, w.oldSize.h - w.deltaHeight); 194 195 DOM.removeClass(id + '_wrapper', 'maximized'); 196 } else if (n.className == 'move') 197 return t._startDrag(id, e, n.className); 198 else if (DOM.hasClass(n, 'resize')) 199 return t._startDrag(id, e, n.className.substring(7)); 200 } 201 }); 202 203 clf = Event.add(id, 'click', function(e) { 204 var n = e.target; 205 206 t.focus(id); 207 208 if (n.nodeName == 'A' || n.nodeName == 'a') { 209 switch (n.className) { 210 case 'close': 211 t.close(null, id); 212 return Event.cancel(e); 213 214 case 'button ok': 215 case 'button cancel': 216 f.button_func(n.className == 'button ok'); 217 return Event.cancel(e); 218 } 219 } 220 }); 221 222 // Add window 223 t.windows = t.windows || {}; 224 w = t.windows[id] = { 225 id : id, 226 mousedown_func : mdf, 227 click_func : clf, 228 element : new Element(id, {blocker : 1, container : ed.getContainer()}), 229 iframeElement : new Element(id + '_ifr'), 230 features : f, 231 deltaWidth : dw, 232 deltaHeight : dh 233 }; 234 235 w.iframeElement.on('focus', function() { 236 t.focus(id); 237 }); 238 239 t.focus(id); 240 t._fixIELayout(id, 1); 241 242 // if (DOM.get(id + '_ok')) 243 // DOM.get(id + '_ok').focus(); 244 245 return w; 246 }, 247 248 focus : function(id) { 249 var t = this, w = t.windows[id]; 250 251 w.zIndex = this.zIndex++; 252 w.element.setStyle('zIndex', w.zIndex); 253 w.element.update(); 254 255 id = id + '_wrapper'; 256 DOM.removeClass(t.lastId, 'focus'); 257 DOM.addClass(id, 'focus'); 258 t.lastId = id; 259 }, 260 261 _addAll : function(te, ne) { 262 var i, n, t = this, dom = tinymce.DOM; 263 264 if (is(ne, 'string')) 265 te.appendChild(dom.doc.createTextNode(ne)); 266 else if (ne.length) { 267 te = te.appendChild(dom.create(ne[0], ne[1])); 268 269 for (i=2; i<ne.length; i++) 270 t._addAll(te, ne[i]); 271 } 272 }, 273 274 _startDrag : function(id, se, ac) { 275 var t = this, mu, mm, d = document, eb, w = t.windows[id], we = w.element, sp = we.getXY(), p, sz, ph, cp, vp, sx, sy, sex, sey, dx, dy, dw, dh; 276 277 // Get positons and sizes 278 // cp = DOM.getPos(t.editor.getContainer()); 279 cp = {x : 0, y : 0}; 280 vp = DOM.getViewPort(); 281 282 // Reduce viewport size to avoid scrollbars 283 vp.w -= 2; 284 vp.h -= 2; 285 286 sex = se.screenX; 287 sey = se.screenY; 288 dx = dy = dw = dh = 0; 289 290 // Handle mouse up 291 mu = Event.add(d, 'mouseup', function(e) { 292 Event.remove(d, 'mouseup', mu); 293 Event.remove(d, 'mousemove', mm); 294 295 if (eb) 296 eb.remove(); 297 298 we.moveBy(dx, dy); 299 we.resizeBy(dw, dh); 300 sz = we.getSize(); 301 DOM.setStyles(id + '_ifr', {width : sz.w - w.deltaWidth, height : sz.h - w.deltaHeight}); 302 t._fixIELayout(id, 1); 303 304 return Event.cancel(e); 305 }); 306 307 if (ac != 'move') 308 startMove(); 309 310 function startMove() { 311 if (eb) 312 return; 313 314 t._fixIELayout(id, 0); 315 316 // Setup event blocker 317 DOM.add(d.body, 'div', { 318 id : 'mceEventBlocker', 319 'class' : 'mceEventBlocker ' + (t.editor.settings.inlinepopups_skin || 'clearlooks2'), 320 style : {left : vp.x, top : vp.y, width : vp.w - 20, height : vp.h - 20, zIndex : 20001} 321 }); 322 eb = new Element('mceEventBlocker'); 323 eb.update(); 324 325 // Setup placeholder 326 p = we.getXY(); 327 sz = we.getSize(); 328 sx = cp.x + p.x - vp.x; 329 sy = cp.y + p.y - vp.y; 330 DOM.add(eb.get(), 'div', {id : 'mcePlaceHolder', 'class' : 'placeholder', style : {left : sx, top : sy, width : sz.w, height : sz.h}}); 331 ph = new Element('mcePlaceHolder'); 332 }; 333 334 // Handle mouse move/drag 335 mm = Event.add(d, 'mousemove', function(e) { 336 var x, y, v; 337 338 startMove(); 339 340 x = e.screenX - sex; 341 y = e.screenY - sey; 342 343 switch (ac) { 344 case 'resize-w': 345 dx = x; 346 dw = 0 - x; 347 break; 348 349 case 'resize-e': 350 dw = x; 351 break; 352 353 case 'resize-n': 354 case 'resize-nw': 355 case 'resize-ne': 356 if (ac == "resize-nw") { 357 dx = x; 358 dw = 0 - x; 359 } else if (ac == "resize-ne") 360 dw = x; 361 362 dy = y; 363 dh = 0 - y; 364 break; 365 366 case 'resize-s': 367 case 'resize-sw': 368 case 'resize-se': 369 if (ac == "resize-sw") { 370 dx = x; 371 dw = 0 - x; 372 } else if (ac == "resize-se") 373 dw = x; 374 375 dh = y; 376 break; 377 378 case 'move': 379 dx = x; 380 dy = y; 381 break; 382 } 383 384 // Boundary check 385 if (dw < (v = w.features.min_width - sz.w)) { 386 if (dx !== 0) 387 dx += dw - v; 388 389 dw = v; 390 } 85 391 86 // WordPress cache buster 87 url += tinyMCE.settings['imp_version'] ? (url.indexOf('?')==-1?'?':'&') + 'ver=' + tinyMCE.settings['imp_version'] : ''; 88 89 mcWindows.open(url, mcWindows.idCounter++, "modal=yes,width=" + width+ ",height=" + height + ",resizable=" + resizable + ",scrollbars=" + scrollbars + ",statusbar=" + resizable + ",left=" + pos.absLeft + ",top=" + pos.absTop + ",minWidth=" + minWidth + ",minHeight=" + minHeight ); 90 }; 91 92 TinyMCE_Engine.prototype.closeWindow = function(win) { 93 var gotit = false, n, w; 94 95 for (n in mcWindows.windows) { 96 w = mcWindows.windows[n]; 97 98 if (typeof(w) == 'function') 99 continue; 100 101 if (win.name == w.id + '_iframe') { 102 w.close(); 103 gotit = true; 392 if (dh < (v = w.features.min_height - sz.h)) { 393 if (dy !== 0) 394 dy += dh - v; 395 396 dh = v; 397 } 398 399 dw = Math.min(dw, w.features.max_width - sz.w); 400 dh = Math.min(dh, w.features.max_height - sz.h); 401 dx = Math.max(dx, vp.x - (sx + vp.x)); 402 dy = Math.max(dy, vp.y - (sy + vp.y)); 403 dx = Math.min(dx, (vp.w + vp.x) - (sx + sz.w + vp.x)); 404 dy = Math.min(dy, (vp.h + vp.y) - (sy + sz.h + vp.y)); 405 406 // Move if needed 407 if (dx + dy !== 0) { 408 if (sx + dx < 0) 409 dx = 0; 410 411 if (sy + dy < 0) 412 dy = 0; 413 414 ph.moveTo(sx + dx, sy + dy); 415 } 416 417 // Resize if needed 418 if (dw + dh !== 0) 419 ph.resizeTo(sz.w + dw, sz.h + dh); 420 421 return Event.cancel(e); 422 }); 423 424 return Event.cancel(se); 425 }, 426 427 resizeBy : function(dw, dh, id) { 428 var w = this.windows[id]; 429 430 if (w) { 431 w.element.resizeBy(dw, dh); 432 w.iframeElement.resizeBy(dw, dh); 433 } 434 }, 435 436 close : function(win, id) { 437 var t = this, w, d = document, ix = 0, fw; 438 439 // Probably not inline 440 if (!id && win) { 441 t.parent(win); 442 return; 443 } 444 445 if (w = t.windows[id]) { 446 t.onClose.dispatch(t); 447 Event.remove(d, 'mousedown', w.mousedownFunc); 448 Event.remove(d, 'click', w.clickFunc); 449 450 DOM.setAttrib(id + '_ifr', 'src', 'javascript:""'); // Prevent leak 451 w.element.remove(); 452 delete t.windows[id]; 453 454 // Find front most window and focus that 455 each (t.windows, function(w) { 456 if (w.zIndex > ix) { 457 fw = w; 458 ix = w.zIndex; 459 } 460 }); 461 462 if (fw) 463 t.focus(fw.id); 464 } 465 }, 466 467 setTitle : function(ti, id) { 468 DOM.get(id + '_title').innerHTML = DOM.encode(ti); 469 }, 470 471 alert : function(txt, cb, s) { 472 var t = this, w; 473 474 w = t.open({ 475 title : t, 476 type : 'alert', 477 button_func : function(s) { 478 if (cb) 479 cb.call(s || t, s); 480 481 t.close(null, w.id); 482 }, 483 content : DOM.encode(t.editor.getLang(txt, txt)), 484 inline : 1, 485 width : 400, 486 height : 130 487 }); 488 }, 489 490 confirm : function(txt, cb, s) { 491 var t = this, w; 492 493 w = t.open({ 494 title : t, 495 type : 'confirm', 496 button_func : function(s) { 497 if (cb) 498 cb.call(s || t, s); 499 500 t.close(null, w.id); 501 }, 502 content : DOM.encode(t.editor.getLang(txt, txt)), 503 inline : 1, 504 width : 400, 505 height : 130 506 }); 507 }, 508 509 // Internal functions 510 511 _fixIELayout : function(id, s) { 512 var w, img; 513 514 if (!tinymce.isIE6) 515 return; 516 517 // Fixes the bug where hover flickers and does odd things in IE6 518 each(['n','s','w','e','nw','ne','sw','se'], function(v) { 519 var e = DOM.get(id + '_resize_' + v); 520 521 DOM.setStyles(e, { 522 width : s ? e.clientWidth : '', 523 height : s ? e.clientHeight : '', 524 cursor : DOM.getStyle(e, 'cursor', 1) 525 }); 526 527 DOM.setStyle(id + "_bottom", 'bottom', '-1px'); 528 529 e = 0; 530 }); 531 532 // Fixes graphics glitch 533 if (w = this.windows[id]) { 534 // Fixes rendering bug after resize 535 w.element.hide(); 536 w.element.show(); 537 538 // Forced a repaint of the window 539 //DOM.get(id).style.filter = ''; 540 541 // IE has a bug where images used in CSS won't get loaded 542 // sometimes when the cache in the browser is disabled 543 // This fix tries to solve it by loading the images using the image object 544 each(DOM.select('div,a', id), function(e, i) { 545 if (e.currentStyle.backgroundImage != 'none') { 546 img = new Image(); 547 img.src = e.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/, '$1'); 548 } 549 }); 550 551 DOM.get(id).style.filter = ''; 552 } 104 553 } 105 } 106 107 if (!gotit) 108 this.orgCloseWindow(win); 109 110 tinyMCE.selectedInstance.getWin().focus(); 111 }; 112 113 TinyMCE_Engine.prototype.setWindowTitle = function(win_ref, title) { 114 for (var n in mcWindows.windows) { 115 var win = mcWindows.windows[n]; 116 if (typeof(win) == 'function') 117 continue; 118 119 if (win_ref.name == win.id + "_iframe") 120 window.frames[win.id + "_iframe"].document.getElementById(win.id + '_title').innerHTML = title; 121 } 122 }; 123 124 // * * * * * TinyMCE_Windows classes below 125 126 // Windows handler 127 function TinyMCE_Windows() { 128 this.settings = new Array(); 129 this.windows = new Array(); 130 this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); 131 this.isGecko = navigator.userAgent.indexOf('Gecko') != -1; 132 this.isSafari = navigator.userAgent.indexOf('Safari') != -1; 133 this.isMac = navigator.userAgent.indexOf('Mac') != -1; 134 this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1); 135 this.action = "none"; 136 this.selectedWindow = null; 137 this.lastSelectedWindow = null; 138 this.zindex = 1001; 139 this.mouseDownScreenX = 0; 140 this.mouseDownScreenY = 0; 141 this.mouseDownLayerX = 0; 142 this.mouseDownLayerY = 0; 143 this.mouseDownWidth = 0; 144 this.mouseDownHeight = 0; 145 this.idCounter = 0; 146 }; 147 148 TinyMCE_Windows.prototype.init = function(settings) { 149 this.settings = settings; 150 151 if (this.isMSIE) 152 this.addEvent(document, "mousemove", mcWindows.eventDispatcher); 153 else 154 this.addEvent(window, "mousemove", mcWindows.eventDispatcher); 155 156 this.addEvent(document, "mouseup", mcWindows.eventDispatcher); 157 158 this.addEvent(window, "resize", mcWindows.eventDispatcher); 159 this.addEvent(document, "scroll", mcWindows.eventDispatcher); 160 161 this.doc = document; 162 }; 163 164 TinyMCE_Windows.prototype.getBounds = function() { 165 if (!this.bounds) { 166 var vp = tinyMCE.getViewPort(window); 167 var top, left, bottom, right, docEl = this.doc.documentElement; 168 169 top = vp.top; 170 left = vp.left; 171 bottom = vp.height + top - 2; 172 right = vp.width + left - 22; // TODO this number is platform dependant 173 // x1, y1, x2, y2 174 this.bounds = [left, top, right, bottom]; 175 } 176 return this.bounds; 177 }; 178 179 TinyMCE_Windows.prototype.clampBoxPosition = function(x, y, w, h, minW, minH) { 180 var bounds = this.getBounds(); 181 182 x = Math.max(bounds[0], Math.min(bounds[2], x + w) - w); 183 y = Math.max(bounds[1], Math.min(bounds[3], y + h) - h); 184 185 return this.clampBoxSize(x, y, w, h, minW, minH); 186 }; 187 188 TinyMCE_Windows.prototype.clampBoxSize = function(x, y, w, h, minW, minH) { 189 var bounds = this.getBounds(); 190 191 return [ 192 x, y, 193 Math.max(minW, Math.min(bounds[2], x + w) - x), 194 Math.max(minH, Math.min(bounds[3], y + h) - y) 195 ]; 196 }; 197 198 TinyMCE_Windows.prototype.getParam = function(name, default_value) { 199 var value = null; 200 201 value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name]; 202 203 // Fix bool values 204 if (value == "true" || value == "false") 205 return (value == "true"); 206 207 return value; 208 }; 209 210 TinyMCE_Windows.prototype.eventDispatcher = function(e) { 211 e = typeof(e) == "undefined" ? window.event : e; 212 213 if (mcWindows.selectedWindow == null) 214 return; 215 216 // Switch focus 217 if (mcWindows.isGecko && e.type == "mousedown") { 218 var elm = e.currentTarget; 219 220 for (var n in mcWindows.windows) { 221 var win = mcWindows.windows[n]; 222 223 if (win.headElement == elm || win.resizeElement == elm) { 224 win.focus(); 225 break; 226 } 227 } 228 } 229 230 switch (e.type) { 231 case "mousemove": 232 mcWindows.selectedWindow.onMouseMove(e); 233 break; 234 235 case "mouseup": 236 mcWindows.selectedWindow.onMouseUp(e); 237 break; 238 239 case "mousedown": 240 mcWindows.selectedWindow.onMouseDown(e); 241 break; 242 243 case "focus": 244 mcWindows.selectedWindow.onFocus(e); 245 break; 246 case "scroll": 247 case "resize": 248 if (mcWindows.clampUpdateTimeout) 249 clearTimeout(mcWindows.clampUpdateTimeout); 250 mcWindows.clampEventType = e.type; 251 mcWindows.clampUpdateTimeout = 252 setTimeout(function () {mcWindows.updateClamping()}, 100); 253 break; 254 } 255 }; 256 257 TinyMCE_Windows.prototype.updateClamping = function () { 258 var clamp, oversize, etype = mcWindows.clampEventType; 259 260 this.bounds = null; // Recalc window bounds on resize/scroll 261 this.clampUpdateTimeout = null; 262 263 for (var n in this.windows) { 264 win = this.windows[n]; 265 if (typeof(win) == 'function' || ! win.winElement) continue; 266 267 clamp = mcWindows.clampBoxPosition( 268 win.left, win.top, 269 win.winElement.scrollWidth, 270 win.winElement.scrollHeight, 271 win.features.minWidth, 272 win.features.minHeight 273 ); 274 oversize = ( 275 clamp[2] != win.winElement.scrollWidth || 276 clamp[3] != win.winElement.scrollHeight 277 ) ? true : false; 278 279 if (!oversize || win.features.resizable == "yes" || etype != "scroll") 280 win.moveTo(clamp[0], clamp[1]); 281 if (oversize && win.features.resizable == "yes") 282 win.resizeTo(clamp[2], clamp[3]); 283 } 284 }; 285 286 TinyMCE_Windows.prototype.addEvent = function(obj, name, handler) { 287 if (this.isMSIE) 288 obj.attachEvent("on" + name, handler); 289 else 290 obj.addEventListener(name, handler, false); 291 }; 292 293 TinyMCE_Windows.prototype.cancelEvent = function(e) { 294 if (this.isMSIE) { 295 e.returnValue = false; 296 e.cancelBubble = true; 297 } else 298 e.preventDefault(); 299 }; 300 301 TinyMCE_Windows.prototype.parseFeatures = function(opts) { 302 // Cleanup the options 303 opts = opts.toLowerCase(); 304 opts = opts.replace(/;/g, ","); 305 opts = opts.replace(/[^0-9a-z=,]/g, ""); 306 307 var optionChunks = opts.split(','); 308 var options = new Array(); 309 310 options['left'] = "10"; 311 options['top'] = "10"; 312 options['width'] = "300"; 313 options['height'] = "300"; 314 options['minwidth'] = "100"; 315 options['minheight'] = "100"; 316 options['resizable'] = "yes"; 317 options['minimizable'] = "yes"; 318 options['maximizable'] = "yes"; 319 options['close'] = "yes"; 320 options['movable'] = "yes"; 321 options['statusbar'] = "yes"; 322 options['scrollbars'] = "auto"; 323 options['modal'] = "no"; 324 325 if (opts == "") 326 return options; 327 328 for (var i=0; i<optionChunks.length; i++) { 329 var parts = optionChunks[i].split('='); 330 331 if (parts.length == 2) 332 options[parts[0]] = parts[1]; 333 } 334 335 options['left'] = parseInt(options['left']); 336 options['top'] = parseInt(options['top']); 337 options['width'] = parseInt(options['width']); 338 options['height'] = parseInt(options['height']); 339 options['minWidth'] = parseInt(options['minwidth']); 340 options['minHeight'] = parseInt(options['minheight']); 341 342 return options; 343 }; 344 345 TinyMCE_Windows.prototype.open = function(url, name, features) { 346 this.lastSelectedWindow = this.selectedWindow; 347 348 var win = new TinyMCE_Window(); 349 var winDiv, html = "", id; 350 var imgPath = this.getParam("images_path"); 351 352 features = this.parseFeatures(features); 353 354 // Clamp specified dimensions 355 var clamp = mcWindows.clampBoxPosition( 356 features['left'], features['top'], 357 features['width'], features['height'], 358 features['minWidth'], features['minHeight'] 359 ); 360 361 features['left'] = clamp[0]; 362 features['top'] = clamp[1]; 363 364 if (features['resizable'] == "yes") { 365 features['width'] = clamp[2]; 366 features['height'] = clamp[3]; 367 } 368 369 // Create div 370 id = "mcWindow_" + name; 371 win.deltaHeight = 18; 372 373 if (features['statusbar'] == "yes") { 374 win.deltaHeight += 13; 375 376 if (this.isMSIE) 377 win.deltaHeight += 1; 378 } 379 380 width = parseInt(features['width']); 381 height = parseInt(features['height'])-win.deltaHeight; 382 383 if (this.isMSIE) 384 width -= 2; 385 386 // Setup first part of window 387 win.id = id; 388 win.url = url; 389 win.name = name; 390 win.features = features; 391 this.windows[name] = win; 392 393 iframeWidth = width; 394 iframeHeight = height; 395 396 // Create inner content 397 html += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'; 398 html += '<html>'; 399 html += '<head>'; 400 html += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'; 401 html += '<title>Wrapper iframe</title>'; 402 403 // WordPress: put the window buttons on the left as in Macs 404 if (this.isMac) html += '<style type="text/css">.mceWindowTitle{float:none;margin:0;width:100%;text-align:center;}.mceWindowClose{float:none;position:absolute;left:0px;top:0px;}</style>'; 405 406 html += '<link href="' + this.getParam("css_file") + '" rel="stylesheet" type="text/css" />'; 407 html += '</head>'; 408 html += '<body onload="parent.mcWindows.onLoad(\'' + name + '\');">'; 409 410 html += '<div id="' + id + '_container" class="mceWindow">'; 411 html += '<div id="' + id + '_head" class="mceWindowHead" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">'; 412 html += ' <div id="' + id + '_title" class="mceWindowTitle"'; 413 html += ' onselectstart="return false;" unselectable="on" style="-moz-user-select: none !important;"></div>'; 414 html += ' <div class="mceWindowHeadTools">'; 415 html += ' <a href="javascript:parent.mcWindows.windows[\'' + name + '\'].close();" target="_self" onmousedown="return false;" class="mceWindowClose"><img border="0" src="' + imgPath + '/window_close.gif" /></a>'; 416 if (features['resizable'] == "yes" && features['maximizable'] == "yes") 417 html += ' <a href="javascript:parent.mcWindows.windows[\'' + name + '\'].maximize();" target="_self" onmousedown="return false;" class="mceWindowMaximize"><img border="0" src="' + imgPath + '/window_maximize.gif" /></a>'; 418 // html += ' <a href="javascript:mcWindows.windows[\'' + name + '\'].minimize();" target="_self" onmousedown="return false;" class="mceWindowMinimize"></a>'; 419 html += ' </div>'; 420 html += '</div><div id="' + id + '_body" class="mceWindowBody" style="width: ' + width + 'px; height: ' + height + 'px;">'; 421 html += '<iframe id="' + id + '_iframe" name="' + id + '_iframe" frameborder="0" width="' + iframeWidth + '" height="' + iframeHeight + '" src="' + url + '" class="mceWindowBodyIframe" scrolling="' + features['scrollbars'] + '"></iframe></div>'; 422 423 if (features['statusbar'] == "yes") { 424 html += '<div id="' + id + '_statusbar" class="mceWindowStatusbar" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">'; 425 426 if (features['resizable'] == "yes") { 427 if (this.isGecko) 428 html += '<div id="' + id + '_resize" class="mceWindowResize"><div style="background-image: url(\'' + imgPath + '/window_resize.gif\'); width: 12px; height: 12px;"></div></div>'; 429 else 430 html += '<div id="' + id + '_resize" class="mceWindowResize"><img onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();" border="0" src="' + imgPath + '/window_resize.gif" /></div>'; 431 } 432 433 html += '</div>'; 434 } 435 436 html += '</div>'; 437 438 html += '</body>'; 439 html += '</html>'; 440 441 // Create iframe 442 this.createFloatingIFrame(id, features['left'], features['top'], features['width'], features['height'], html); 443 }; 444 445 // Blocks the document events by placing a image over the whole document 446 TinyMCE_Windows.prototype.setDocumentLock = function(state) { 447 var elm = document.getElementById('mcWindowEventBlocker'); 448 449 if (state) { 450 if (elm == null) { 451 elm = document.createElement("div"); 452 453 elm.id = "mcWindowEventBlocker"; 454 elm.style.position = "absolute"; 455 elm.style.left = "0"; 456 elm.style.top = "0"; 457 458 document.body.appendChild(elm); 459 } 460 461 elm.style.display = "none"; 462 463 var imgPath = this.getParam("images_path"); 464 var width = document.body.clientWidth; 465 var height = document.body.clientHeight; 466 467 elm.style.width = width; 468 elm.style.height = height; 469 elm.innerHTML = '<img src="' + imgPath + '/spacer.gif" width="' + width + '" height="' + height + '" />'; 470 471 elm.style.zIndex = mcWindows.zindex-1; 472 elm.style.display = "block"; 473 } else if (elm != null) { 474 if (mcWindows.windows.length == 0) 475 elm.parentNode.removeChild(elm); 476 else 477 elm.style.zIndex = mcWindows.zindex-1; 478 } 479 }; 480 481 // Gets called when wrapper iframe is initialized 482 TinyMCE_Windows.prototype.onLoad = function(name) { 483 var win = mcWindows.windows[name]; 484 var id = "mcWindow_" + name; 485 var wrapperIframe = window.frames[id + "_iframe"].frames[0]; 486 var wrapperDoc = window.frames[id + "_iframe"].document; 487 var doc = window.frames[id + "_iframe"].document; 488 var winDiv = document.getElementById("mcWindow_" + name + "_div"); 489 var realIframe = window.frames[id + "_iframe"].frames[0]; 490 491 // Set window data 492 win.id = "mcWindow_" + name; 493 win.winElement = winDiv; 494 win.bodyElement = doc.getElementById(id + '_body'); 495 win.iframeElement = doc.getElementById(id + '_iframe'); 496 win.headElement = doc.getElementById(id + '_head'); 497 win.titleElement = doc.getElementById(id + '_title'); 498 win.resizeElement = doc.getElementById(id + '_resize'); 499 win.containerElement = doc.getElementById(id + '_container'); 500 win.left = win.features['left']; 501 win.top = win.features['top']; 502 win.frame = window.frames[id + '_iframe'].frames[0]; 503 win.wrapperFrame = window.frames[id + '_iframe']; 504 win.wrapperIFrameElement = document.getElementById(id + "_iframe"); 505 506 // Add event handlers 507 mcWindows.addEvent(win.headElement, "mousedown", mcWindows.eventDispatcher); 508 509 if (win.resizeElement != null) 510 mcWindows.addEvent(win.resizeElement, "mousedown", mcWindows.eventDispatcher); 511 512 if (mcWindows.isMSIE) { 513 mcWindows.addEvent(realIframe.document, "mousemove", mcWindows.eventDispatcher); 514 mcWindows.addEvent(realIframe.document, "mouseup", mcWindows.eventDispatcher); 515 } else { 516 mcWindows.addEvent(realIframe, "mousemove", mcWindows.eventDispatcher); 517 mcWindows.addEvent(realIframe, "mouseup", mcWindows.eventDispatcher); 518 mcWindows.addEvent(realIframe, "focus", mcWindows.eventDispatcher); 519 } 520 521 for (var i=0; i<window.frames.length; i++) { 522 if (!window.frames[i]._hasMouseHandlers) { 523 if (mcWindows.isMSIE) { 524 mcWindows.addEvent(window.frames[i].document, "mousemove", mcWindows.eventDispatcher); 525 mcWindows.addEvent(window.frames[i].document, "mouseup", mcWindows.eventDispatcher); 526 } else { 527 mcWindows.addEvent(window.frames[i], "mousemove", mcWindows.eventDispatcher); 528 mcWindows.addEvent(window.frames[i], "mouseup", mcWindows.eventDispatcher); 529 } 530 531 window.frames[i]._hasMouseHandlers = true; 532 } 533 } 534 535 if (mcWindows.isMSIE) { 536 mcWindows.addEvent(win.frame.document, "mousemove", mcWindows.eventDispatcher); 537 mcWindows.addEvent(win.frame.document, "mouseup", mcWindows.eventDispatcher); 538 } else { 539 mcWindows.addEvent(win.frame, "mousemove", mcWindows.eventDispatcher); 540 mcWindows.addEvent(win.frame, "mouseup", mcWindows.eventDispatcher); 541 mcWindows.addEvent(win.frame, "focus", mcWindows.eventDispatcher); 542 } 543 544 // Dispatch open window event 545 var func = this.getParam("on_open_window", ""); 546 if (func != "") 547 eval(func + "(win);"); 548 549 win.focus(); 550 551 if (win.features['modal'] == "yes") 552 mcWindows.setDocumentLock(true); 553 }; 554 555 TinyMCE_Windows.prototype.createFloatingIFrame = function(id_prefix, left, top, width, height, html) { 556 var iframe = document.createElement("iframe"); 557 var div = document.createElement("div"), doc; 558 559 width = parseInt(width); 560 height = parseInt(height)+1; 561 562 // Create wrapper div 563 div.setAttribute("id", id_prefix + "_div"); 564 div.setAttribute("width", width); 565 div.setAttribute("height", (height)); 566 div.style.position = "absolute"; 567 568 div.style.left = left + "px"; 569 div.style.top = top + "px"; 570 div.style.width = width + "px"; 571 div.style.height = (height) + "px"; 572 div.style.backgroundColor = "white"; 573 div.style.display = "none"; 574 575 if (this.isGecko) { 576 iframeWidth = width + 2; 577 iframeHeight = height + 2; 578 } else { 579 iframeWidth = width; 580 iframeHeight = height + 1; 581 } 582 583 // Create iframe 584 iframe.setAttribute("id", id_prefix + "_iframe"); 585 iframe.setAttribute("name", id_prefix + "_iframe"); 586 iframe.setAttribute("border", "0"); 587 iframe.setAttribute("frameBorder", "0"); 588 iframe.setAttribute("marginWidth", "0"); 589 iframe.setAttribute("marginHeight", "0"); 590 iframe.setAttribute("leftMargin", "0"); 591 iframe.setAttribute("topMargin", "0"); 592 iframe.setAttribute("width", iframeWidth); 593 iframe.setAttribute("height", iframeHeight); 594 // iframe.setAttribute("src", "../jscripts/tiny_mce/blank.htm"); 595 // iframe.setAttribute("allowtransparency", "false"); 596 iframe.setAttribute("scrolling", "no"); 597 iframe.style.width = iframeWidth + "px"; 598 iframe.style.height = iframeHeight + "px"; 599 iframe.style.backgroundColor = "white"; 600 div.appendChild(iframe); 601 602 document.body.appendChild(div); 603 604 // Fixed MSIE 5.0 issue 605 div.innerHTML = div.innerHTML; 606 607 if (this.isSafari) { 608 // Give Safari some time to setup 609 window.setTimeout(function() { 610 var doc = window.frames[id_prefix + '_iframe'].document; 611 doc.open(); 612 doc.write(html); 613 doc.close(); 614 }, 10); 615 } else { 616 doc = window.frames[id_prefix + '_iframe'].window.document; 617 doc.open(); 618 doc.write(html); 619 doc.close(); 620 } 621 622 div.style.display = "block"; 623 624 return div; 625 }; 626 627 // Window instance 628 function TinyMCE_Window() { 629 }; 630 631 TinyMCE_Window.prototype.focus = function() { 632 if (this != mcWindows.selectedWindow) { 633 this.winElement.style.zIndex = ++mcWindows.zindex; 634 mcWindows.lastSelectedWindow = mcWindows.selectedWindow; 635 mcWindows.selectedWindow = this; 636 } 637 }; 638 639 TinyMCE_Window.prototype.minimize = function() { 640 }; 641 642 TinyMCE_Window.prototype.maximize = function() { 643 if (this.restoreSize) { 644 this.moveTo(this.restoreSize[0], this.restoreSize[1]); 645 this.resizeTo(this.restoreSize[2], this.restoreSize[3]); 646 this.updateClamping(); 647 this.restoreSize = null; 648 } else { 649 var bounds = mcWindows.getBounds(); 650 this.restoreSize = [ 651 this.left, this.top, 652 this.winElement.scrollWidth, 653 this.winElement.scrollHeight 654 ]; 655 this.moveTo(bounds[0], bounds[1]); 656 this.resizeTo( 657 bounds[2] - bounds[0], 658 bounds[3] - bounds[1] 659 ); 660 } 661 }; 662 663 TinyMCE_Window.prototype.startResize = function() { 664 mcWindows.action = "resize"; 665 }; 666 667 TinyMCE_Window.prototype.startMove = function(e) { 668 mcWindows.action = "move"; 669 }; 670 671 TinyMCE_Window.prototype.close = function() { 672 if (this.frame && this.frame['tinyMCEPopup']) 673 this.frame['tinyMCEPopup'].restoreSelection(); 674 675 if (mcWindows.lastSelectedWindow != null) 676 mcWindows.lastSelectedWindow.focus(); 677 678 var mcWindowsNew = new Array(); 679 for (var n in mcWindows.windows) { 680 var win = mcWindows.windows[n]; 681 if (typeof(win) == 'function') 682 continue; 683 684 if (win.name != this.name) 685 mcWindowsNew[n] = win; 686 } 687 688 mcWindows.windows = mcWindowsNew; 689 690 // alert(mcWindows.doc.getElementById(this.id + "_iframe")); 691 692 var e = mcWindows.doc.getElementById(this.id + "_iframe"); 693 e.parentNode.removeChild(e); 694 695 var e = mcWindows.doc.getElementById(this.id + "_div"); 696 e.parentNode.removeChild(e); 697 698 mcWindows.setDocumentLock(false); 699 }; 700 701 TinyMCE_Window.prototype.onMouseMove = function(e) { 702 var clamp; 703 // Calculate real X, Y 704 var dx = e.screenX - mcWindows.mouseDownScreenX; 705 var dy = e.screenY - mcWindows.mouseDownScreenY; 706 707 switch (mcWindows.action) { 708 case "resize": 709 clamp = mcWindows.clampBoxSize( 710 this.left, this.top, 711 mcWindows.mouseDownWidth + (e.screenX - mcWindows.mouseDownScreenX), 712 mcWindows.mouseDownHeight + (e.screenY - mcWindows.mouseDownScreenY), 713 this.features.minWidth, this.features.minHeight 714 ); 715 716 this.resizeTo(clamp[2], clamp[3]); 717 718 mcWindows.cancelEvent(e); 719 break; 720 721 case "move": 722 this.left = mcWindows.mouseDownLayerX + (e.screenX - mcWindows.mouseDownScreenX); 723 this.top = mcWindows.mouseDownLayerY + (e.screenY - mcWindows.mouseDownScreenY); 724 this.updateClamping(); 725 726 mcWindows.cancelEvent(e); 727 break; 728 } 729 }; 730 731 TinyMCE_Window.prototype.moveTo = function (x, y) { 732 this.left = x; 733 this.top = y; 734 735 this.winElement.style.left = this.left + "px"; 736 this.winElement.style.top = this.top + "px"; 737 }; 738 739 TinyMCE_Window.prototype.resizeTo = function (width, height) { 740 this.wrapperIFrameElement.style.width = (width+2) + 'px'; 741 this.wrapperIFrameElement.style.height = (height+2) + 'px'; 742 this.wrapperIFrameElement.width = width+2; 743 this.wrapperIFrameElement.height = height+2; 744 this.winElement.style.width = width + 'px'; 745 this.winElement.style.height = height + 'px'; 746 747 height = height - this.deltaHeight; 748 749 this.containerElement.style.width = width + 'px'; 750 this.iframeElement.style.width = width + 'px'; 751 this.iframeElement.style.height = height + 'px'; 752 this.bodyElement.style.width = width + 'px'; 753 this.bodyElement.style.height = height + 'px'; 754 this.headElement.style.width = width + 'px'; 755 //this.statusElement.style.width = width + 'px'; 756 }; 757 758 TinyMCE_Window.prototype.updateClamping = function () { 759 var clamp, oversize; 760 761 clamp = mcWindows.clampBoxPosition( 762 this.left, this.top, 763 this.winElement.scrollWidth, 764 this.winElement.scrollHeight, 765 this.features.minWidth, this.features.minHeight 766 ); 767 oversize = ( 768 clamp[2] != this.winElement.scrollWidth || 769 clamp[3] != this.winElement.scrollHeight 770 ) ? true : false; 771 772 this.moveTo(clamp[0], clamp[1]); 773 if (this.features.resizable == "yes" && oversize) 774 this.resizeTo(clamp[2], clamp[3]); 775 }; 776 777 function debug(msg) { 778 document.getElementById('debug').value += msg + "\n"; 779 } 780 781 TinyMCE_Window.prototype.onMouseUp = function(e) { 782 mcWindows.action = "none"; 783 }; 784 785 TinyMCE_Window.prototype.onFocus = function(e) { 786 // Gecko only handler 787 var winRef = e.currentTarget; 788 789 for (var n in mcWindows.windows) { 790 var win = mcWindows.windows[n]; 791 if (typeof(win) == 'function') 792 continue; 793 794 if (winRef.name == win.id + "_iframe") { 795 win.focus(); 796 return; 797 } 798 } 799 }; 800 801 TinyMCE_Window.prototype.onMouseDown = function(e) { 802 var elm = mcWindows.isMSIE ? this.wrapperFrame.event.srcElement : e.target; 803 804 mcWindows.mouseDownScreenX = e.screenX; 805 mcWindows.mouseDownScreenY = e.screenY; 806 mcWindows.mouseDownLayerX = this.left; 807 mcWindows.mouseDownLayerY = this.top; 808 mcWindows.mouseDownWidth = parseInt(this.winElement.style.width); 809 mcWindows.mouseDownHeight = parseInt(this.winElement.style.height); 810 811 if (this.resizeElement != null && elm == this.resizeElement.firstChild) 812 this.startResize(e); 813 else 814 this.startMove(e); 815 816 mcWindows.cancelEvent(e); 817 }; 818 819 // Global instance 820 var mcWindows = new TinyMCE_Windows(); 821 822 // Initialize windows 823 mcWindows.init({ 824 images_path : tinyMCE.baseURL + "/plugins/inlinepopups/images", 825 css_file : tinyMCE.baseURL + "/plugins/inlinepopups/css/inlinepopup.css" 826 }); 554 }); 555 556 // Register plugin 557 tinymce.PluginManager.add('inlinepopups', tinymce.plugins.InlinePopups); 558 })(); 559 -
trunk/wp-includes/js/tinymce/plugins/paste/blank.htm
-
Property
svn:eol-style
set to
native
r6568 r6632 1 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 2 <head> 3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 4 <title>blank_page</title> 5 <script language="javascript"> 6 function init() { 7 document.body.contentEditable = true; 8 document.designMode = 'on'; 9 parent.initIframe(document); 10 window.focus(); 11 } 12 </script> 13 <link href="css/blank.css" rel="stylesheet" type="text/css" /> 14 <base target="_self" /> 3 <title>blank_page</title> 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 5 <link href="css/blank.css" rel="stylesheet" type="text/css" /> 6 <base target="_self" /> 7 <script type="text/javascript"> 8 function init() { 9 if (parent.tinymce.isIE) 10 document.body.contentEditable = true; 11 else 12 document.designMode = 'on'; 13 14 parent.initIframe(document); 15 window.focus(); 16 } 17 </script> 15 18 </head> 16 19 <body onload="init();"> -
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/paste/css/blank.css
-
Property
svn:eol-style
set to
native
r3664 r6632 1 html, body {height:98%} 1 2 body { 2 3 4 5 6 7 8 9 10 11 12 3 background-color: #FFFFFF; 4 font-family: Verdana, Arial, Helvetica, sans-serif; 5 font-size: 10px; 6 scrollbar-3dlight-color: #F0F0EE; 7 scrollbar-arrow-color: #676662; 8 scrollbar-base-color: #F0F0EE; 9 scrollbar-darkshadow-color: #DDDDDD; 10 scrollbar-face-color: #E0E0DD; 11 scrollbar-highlight-color: #F0F0EE; 12 scrollbar-shadow-color: #F0F0EE; 13 scrollbar-track-color: #F5F5F5; 13 14 } -
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/paste/css/pasteword.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/paste/editor_plugin.js
r5256 r6632 1 1 /** 2 * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $2 * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * @author Moxiecode 5 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 6 6 */ 7 7 8 /* Import plugin specific language pack */ 9 tinyMCE.importPluginLanguagePack('paste'); 10 11 var TinyMCE_PastePlugin = { 12 getInfo : function() { 13 return { 14 longname : 'Paste text/word', 15 author : 'Moxiecode Systems AB', 16 authorurl : 'http://tinymce.moxiecode.com', 17 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste', 18 version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion 19 }; 20 }, 21 22 initInstance : function(inst) { 23 if (tinyMCE.isMSIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false)) 24 tinyMCE.addEvent(inst.getBody(), "paste", TinyMCE_PastePlugin._handlePasteEvent); 25 }, 26 27 handleEvent : function(e) { 28 // Force paste dialog if non IE browser 29 if (!tinyMCE.isRealIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false) && e.ctrlKey && e.keyCode == 86 && e.type == "keydown") { 30 window.setTimeout('tinyMCE.selectedInstance.execCommand("mcePasteText",true)', 1); 31 return tinyMCE.cancelEvent(e); 8 (function() { 9 var Event = tinymce.dom.Event; 10 11 tinymce.create('tinymce.plugins.PastePlugin', { 12 init : function(ed, url) { 13 var t = this; 14 15 t.editor = ed; 16 17 // Register commands 18 ed.addCommand('mcePasteText', function(ui, v) { 19 if (ui) { 20 ed.windowManager.open({ 21 file : url + '/pastetext.htm', 22 width : 450, 23 height : 400, 24 inline : 1 25 }, { 26 plugin_url : url 27 }); 28 } else 29 t._insertText(v.html, v.linebreaks); 30 }); 31 32 ed.addCommand('mcePasteWord', function(ui, v) { 33 if (ui) { 34 ed.windowManager.open({ 35 file : url + '/pasteword.htm', 36 width : 450, 37 height : 400, 38 inline : 1 39 }, { 40 plugin_url : url 41 }); 42 } else 43 t._insertWordContent(v); 44 }); 45 46 ed.addCommand('mceSelectAll', function() { 47 ed.execCommand('selectall'); 48 }); 49 50 // Register buttons 51 ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText', ui : true}); 52 ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord', ui : true}); 53 ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'mceSelectAll'}); 54 55 if (ed.getParam("paste_auto_cleanup_on_paste", false)) { 56 ed.onPaste.add(function(ed, e) { 57 return t._handlePasteEvent(e) 58 }); 59 } 60 61 if (!tinymce.isIE && ed.getParam("paste_auto_cleanup_on_paste", false)) { 62 // Force paste dialog if non IE browser 63 ed.onKeyDown.add(function(ed, e) { 64 if (e.ctrlKey && e.keyCode == 86) { 65 window.setTimeout(function() { 66 ed.execCommand("mcePasteText", true); 67 }, 1); 68 69 Event.cancel(e); 70 } 71 }); 72 } 73 }, 74 75 getInfo : function() { 76 return { 77 longname : 'Paste text/word', 78 author : 'Moxiecode Systems AB', 79 authorurl : 'http://tinymce.moxiecode.com', 80 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste', 81 version : tinymce.majorVersion + "." + tinymce.minorVersion 82 }; 83 }, 84 85 // Private methods 86 87 _handlePasteEvent : function(e) { 88 var html = this._clipboardHTML(), ed = this.editor, sel = ed.selection, r; 89 90 // Removes italic, strong etc, the if was needed due to bug #1437114 91 if (ed && (r = sel.getRng()) && r.text.length > 0) 92 ed.execCommand('delete'); 93 94 if (html && html.length > 0) 95 ed.execCommand('mcePasteWord', false, html); 96 97 return Event.cancel(e); 98 }, 99 100 _insertText : function(content, bLinebreaks) { 101 if (content && content.length > 0) { 102 if (bLinebreaks) { 103 // Special paragraph treatment 104 if (this.editor.getParam("paste_create_paragraphs", true)) { 105 var rl = this.editor.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); 106 for (var i=0; i<rl.length; i+=2) 107 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); 108 109 content = content.replace(/\r\n\r\n/g, '</p><p>'); 110 content = content.replace(/\r\r/g, '</p><p>'); 111 content = content.replace(/\n\n/g, '</p><p>'); 112 113 // Has paragraphs 114 if ((pos = content.indexOf('</p><p>')) != -1) { 115 this.editor.execCommand("Delete"); 116 117 var node = this.editor.selection.getNode(); 118 119 // Get list of elements to break 120 var breakElms = []; 121 122 do { 123 if (node.nodeType == 1) { 124 // Don't break tables and break at body 125 if (node.nodeName == "TD" || node.nodeName == "BODY") 126 break; 127 128 breakElms[breakElms.length] = node; 129 } 130 } while(node = node.parentNode); 131 132 var before = "", after = "</p>"; 133 before += content.substring(0, pos); 134 135 for (var i=0; i<breakElms.length; i++) { 136 before += "</" + breakElms[i].nodeName + ">"; 137 after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; 138 } 139 140 before += "<p>"; 141 content = before + content.substring(pos+7) + after; 142 } 143 } 144 145 if (this.editor.getParam("paste_create_linebreaks", true)) { 146 content = content.replace(/\r\n/g, '<br />'); 147 content = content.replace(/\r/g, '<br />'); 148 content = content.replace(/\n/g, '<br />'); 149 } 150 } 151 152 this.editor.execCommand("mceInsertRawHTML", false, content); 153 } 154 }, 155 156 _insertWordContent : function(content) { 157 var t = this, ed = t.editor; 158 159 if (content && content.length > 0) { 160 // Cleanup Word content 161 var bull = String.fromCharCode(8226); 162 var middot = String.fromCharCode(183); 163 var cb; 164 165 if ((cb = this.editor.getParam("paste_insert_word_content_callback", "")) != "") 166 content = eval(cb + "('before', content)"); 167 168 var rl = this.editor.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); 169 for (var i=0; i<rl.length; i+=2) 170 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); 171 172 if (this.editor.getParam("paste_convert_headers_to_strong", false)) { 173 content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>'); 174 } 175 176 content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--"); 177 content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>"); 178 content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list 179 content = content.replace(/<o:p><\/o:p>/gi, ""); 180 content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks 181 content = content.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), ""); // Word comments 182 183 if (this.editor.getParam("paste_remove_spans", true)) 184 content = content.replace(/<\/?span[^>]*>/gi, ""); 185 186 if (this.editor.getParam("paste_remove_styles", true)) 187 content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3"); 188 189 content = content.replace(/<\/?font[^>]*>/gi, ""); 190 191 // Strips class attributes. 192 switch (this.editor.getParam("paste_strip_class_attributes", "all")) { 193 case "all": 194 content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); 195 break; 196 197 case "mso": 198 content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3"); 199 break; 200 } 201 202 content = content.replace(new RegExp('href="?' + this._reEscape("" + document.location) + '', 'gi'), 'href="' + this.editor.documentBaseURI.getURI()); 203 content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3"); 204 content = content.replace(/<\\?\?xml[^>]*>/gi, ""); 205 content = content.replace(/<\/?\w+:[^>]*>/gi, ""); 206 content = content.replace(/-- page break --\s*<p> <\/p>/gi, ""); // Remove pagebreaks 207 content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks 208 209 // content = content.replace(/\/? */gi, ""); 210 // content = content.replace(/<p> <\/p>/gi, ''); 211 212 if (!this.editor.getParam('force_p_newlines')) { 213 content = content.replace('', '' ,'gi'); 214 content = content.replace('</p>', '<br /><br />' ,'gi'); 215 } 216 217 if (!tinymce.isIE && !this.editor.getParam('force_p_newlines')) { 218 content = content.replace(/<\/?p[^>]*>/gi, ""); 219 } 220 221 content = content.replace(/<\/?div[^>]*>/gi, ""); 222 223 // Convert all middlot lists to UL lists 224 if (this.editor.getParam("paste_convert_middot_lists", true)) { 225 var div = ed.dom.create("div", null, content); 226 227 // Convert all middot paragraphs to li elements 228 var className = this.editor.getParam("paste_unindented_list_class", "unIndentedList"); 229 230 while (this._convertMiddots(div, "--list--")) ; // bull 231 while (this._convertMiddots(div, middot, className)) ; // Middot 232 while (this._convertMiddots(div, bull)) ; // bull 233 234 content = div.innerHTML; 235 } 236 237 // Replace all headers with strong and fix some other issues 238 if (this.editor.getParam("paste_convert_headers_to_strong", false)) { 239 content = content.replace(/<h[1-6]> <\/h[1-6]>/gi, '<p> </p>'); 240 content = content.replace(/<h[1-6]>/gi, '<p><b>'); 241 content = content.replace(/<\/h[1-6]>/gi, '</b></p>'); 242 content = content.replace(/<b> <\/b>/gi, '<b> </b>'); 243 content = content.replace(/^( )*/gi, ''); 244 } 245 246 content = content.replace(/--list--/gi, ""); // Remove --list-- 247 248 if ((cb = this.editor.getParam("paste_insert_word_content_callback", "")) != "") 249 content = eval(cb + "('after', content)"); 250 251 // Insert cleaned content 252 this.editor.execCommand("mceInsertContent", false, content); 253 254 if (this.editor.getParam('paste_force_cleanup_wordpaste', true)) { 255 var ed = this.editor; 256 257 window.setTimeout(function() { 258 ed.execCommand("mceCleanup"); 259 }, 1); // Do normal cleanup detached from this thread 260 } 261 } 262 }, 263 264 _reEscape : function(s) { 265 var l = "?.\\*[](){}+^$:"; 266 var o = ""; 267 268 for (var i=0; i<s.length; i++) { 269 var c = s.charAt(i); 270 271 if (l.indexOf(c) != -1) 272 o += '\\' + c; 273 else 274 o += c; 275 } 276 277 return o; 278 }, 279 280 _convertMiddots : function(div, search, class_name) { 281 var mdot = String.fromCharCode(183); 282 var bull = String.fromCharCode(8226); 283 284 var nodes = div.getElementsByTagName("p"); 285 var prevul; 286 for (var i=0; i<nodes.length; i++) { 287 var p = nodes[i]; 288 289 // Is middot 290 if (p.innerHTML.indexOf(search) == 0) { 291 var ul = document.createElement("ul"); 292 293 if (class_name) 294 ul.className = class_name; 295 296 // Add the first one 297 var li = document.createElement("li"); 298 li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); 299 ul.appendChild(li); 300 301 // Add the rest 302 var np = p.nextSibling; 303 while (np) { 304 // If the node is whitespace, then 305 // ignore it and continue on. 306 if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) { 307 np = np.nextSibling; 308 continue; 309 } 310 311 if (search == mdot) { 312 if (np.nodeType == 1 && new RegExp('^o(\\s+| )').test(np.innerHTML)) { 313 // Second level of nesting 314 if (!prevul) { 315 prevul = ul; 316 ul = document.createElement("ul"); 317 prevul.appendChild(ul); 318 } 319 np.innerHTML = np.innerHTML.replace(/^o/, ''); 320 } else { 321 // Pop the stack if we're going back up to the first level 322 if (prevul) { 323 ul = prevul; 324 prevul = null; 325 } 326 // Not element or middot paragraph 327 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) 328 break; 329 } 330 } else { 331 // Not element or middot paragraph 332 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) 333 break; 334 } 335 336 var cp = np.nextSibling; 337 var li = document.createElement("li"); 338 li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); 339 np.parentNode.removeChild(np); 340 ul.appendChild(li); 341 np = cp; 342 } 343 344 p.parentNode.replaceChild(ul, p); 345 346 return true; 347 } 348 } 349 350 return false; 351 }, 352 353 _clipboardHTML : function() { 354 var div = document.getElementById('_TinyMCE_clipboardHTML'); 355 356 if (!div) { 357 var div = document.createElement('DIV'); 358 div.id = '_TinyMCE_clipboardHTML'; 359 360 with (div.style) { 361 visibility = 'hidden'; 362 overflow = 'hidden'; 363 position = 'absolute'; 364 width = 1; 365 height = 1; 366 } 367 368 document.body.appendChild(div); 369 } 370 371 div.innerHTML = ''; 372 var rng = document.body.createTextRange(); 373 rng.moveToElementText(div); 374 rng.execCommand('Paste'); 375 var html = div.innerHTML; 376 div.innerHTML = ''; 377 return html; 32 378 } 33 34 return true; 35 }, 36 37 getControlHTML : function(cn) { 38 switch (cn) { 39 case "pastetext": 40 return tinyMCE.getButtonHTML(cn, 'lang_paste_text_desc', '{$pluginurl}/images/pastetext.gif', 'mcePasteText', true); 41 42 case "pasteword": 43 return tinyMCE.getButtonHTML(cn, 'lang_paste_word_desc', '{$pluginurl}/images/pasteword.gif', 'mcePasteWord', true); 44 45 case "selectall": 46 return tinyMCE.getButtonHTML(cn, 'lang_selectall_desc', '{$pluginurl}/images/selectall.gif', 'mceSelectAll', true); 47 } 48 49 return ''; 50 }, 51 52 execCommand : function(editor_id, element, command, user_interface, value) { 53 switch (command) { 54 case "mcePasteText": 55 if (user_interface) { 56 if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && !tinyMCE.getParam('paste_use_dialog', false)) 57 TinyMCE_PastePlugin._insertText(clipboardData.getData("Text"), true); 58 else { 59 var template = new Array(); 60 template['file'] = '../../plugins/paste/pastetext.htm'; // Relative to theme 61 template['width'] = 450; 62 template['height'] = 400; 63 var plain_text = ""; 64 tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", inline : "yes", mceDo : 'insert'}); 65 } 66 } else 67 TinyMCE_PastePlugin._insertText(value['html'], value['linebreaks']); 68 69 return true; 70 71 case "mcePasteWord": 72 if (user_interface) { 73 if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && !tinyMCE.getParam('paste_use_dialog', false)) { 74 TinyMCE_PastePlugin._insertWordContent(TinyMCE_PastePlugin._clipboardHTML()); 75 } else { 76 var template = new Array(); 77 template['file'] = '../../plugins/paste/pasteword.htm'; // Relative to theme 78 template['width'] = 450; 79 template['height'] = 400; 80 var plain_text = ""; 81 tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", inline : "yes", mceDo : 'insert'}); 82 } 83 } else 84 TinyMCE_PastePlugin._insertWordContent(value); 85 86 return true; 87 88 case "mceSelectAll": 89 tinyMCE.execInstanceCommand(editor_id, 'selectall'); 90 return true; 91 92 } 93 94 // Pass to next handler in chain 95 return false; 96 }, 97 98 // Private plugin internal methods 99 100 _handlePasteEvent : function(e) { 101 switch (e.type) { 102 case "paste": 103 var html = TinyMCE_PastePlugin._clipboardHTML(); 104 var r, inst = tinyMCE.selectedInstance; 105 106 // Removes italic, strong etc, the if was needed due to bug #1437114 107 if (inst && (r = inst.getRng()) && r.text.length > 0) 108 tinyMCE.execCommand('delete'); 109 110 if (html && html.length > 0) 111 tinyMCE.execCommand('mcePasteWord', false, html); 112 113 tinyMCE.cancelEvent(e); 114 return false; 115 } 116 117 return true; 118 }, 119 120 _insertText : function(content, bLinebreaks) { 121 if (content && content.length > 0) { 122 if (bLinebreaks) { 123 // Special paragraph treatment 124 if (tinyMCE.getParam("paste_create_paragraphs", true)) { 125 var rl = tinyMCE.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); 126 for (var i=0; i<rl.length; i+=2) 127 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); 128 129 content = tinyMCE.regexpReplace(content, "\r\n\r\n", "</p><p>", "gi"); 130 content = tinyMCE.regexpReplace(content, "\r\r", "</p><p>", "gi"); 131 content = tinyMCE.regexpReplace(content, "\n\n", "</p><p>", "gi"); 132 133 // Has paragraphs 134 if ((pos = content.indexOf('</p><p>')) != -1) { 135 tinyMCE.execCommand("Delete"); 136 137 var node = tinyMCE.selectedInstance.getFocusElement(); 138 139 // Get list of elements to break 140 var breakElms = new Array(); 141 142 do { 143 if (node.nodeType == 1) { 144 // Don't break tables and break at body 145 if (node.nodeName == "TD" || node.nodeName == "BODY") 146 break; 147 148 breakElms[breakElms.length] = node; 149 } 150 } while(node = node.parentNode); 151 152 var before = "", after = "</p>"; 153 before += content.substring(0, pos); 154 155 for (var i=0; i<breakElms.length; i++) { 156 before += "</" + breakElms[i].nodeName + ">"; 157 after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; 158 } 159 160 before += "<p>"; 161 content = before + content.substring(pos+7) + after; 162 } 163 } 164 165 if (tinyMCE.getParam("paste_create_linebreaks", true)) { 166 content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi"); 167 content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi"); 168 content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi"); 169 } 170 } 171 172 tinyMCE.execCommand("mceInsertRawHTML", false, content); 173 } 174 }, 175 176 _insertWordContent : function(content) { 177 if (content && content.length > 0) { 178 // Cleanup Word content 179 var bull = String.fromCharCode(8226); 180 var middot = String.fromCharCode(183); 181 var cb; 182 183 if ((cb = tinyMCE.getParam("paste_insert_word_content_callback", "")) != "") 184 content = eval(cb + "('before', content)"); 185 186 var rl = tinyMCE.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); 187 for (var i=0; i<rl.length; i+=2) 188 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); 189 190 if (tinyMCE.getParam("paste_convert_headers_to_strong", false)) { 191 content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>'); 192 } 193 194 content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--"); 195 content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>"); 196 content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list 197 content = content.replace(/<o:p><\/o:p>/gi, ""); 198 content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks 199 content = content.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), ""); // Word comments 200 201 if (tinyMCE.getParam("paste_remove_spans", true)) 202 content = content.replace(/<\/?span[^>]*>/gi, ""); 203 204 if (tinyMCE.getParam("paste_remove_styles", true)) 205 content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3"); 206 207 content = content.replace(/<\/?font[^>]*>/gi, ""); 208 209 // Strips class attributes. 210 switch (tinyMCE.getParam("paste_strip_class_attributes", "all")) { 211 case "all": 212 content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); 213 break; 214 215 case "mso": 216 content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3"); 217 break; 218 } 219 220 content = content.replace(new RegExp('href="?' + TinyMCE_PastePlugin._reEscape("" + document.location) + '', 'gi'), 'href="' + tinyMCE.settings['document_base_url']); 221 content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3"); 222 content = content.replace(/<\\?\?xml[^>]*>/gi, ""); 223 content = content.replace(/<\/?\w+:[^>]*>/gi, ""); 224 content = content.replace(/-- page break --\s*<p> <\/p>/gi, ""); // Remove pagebreaks 225 content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks 226 227 // content = content.replace(/\/? */gi, ""); 228 // content = content.replace(/<p> <\/p>/gi, ''); 229 230 if (!tinyMCE.settings['force_p_newlines']) { 231 content = content.replace('', '' ,'gi'); 232 content = content.replace('</p>', '<br /><br />' ,'gi'); 233 } 234 235 if (!tinyMCE.isMSIE && !tinyMCE.settings['force_p_newlines']) { 236 content = content.replace(/<\/?p[^>]*>/gi, ""); 237 } 238 239 content = content.replace(/<\/?div[^>]*>/gi, ""); 240 241 // Convert all middlot lists to UL lists 242 if (tinyMCE.getParam("paste_convert_middot_lists", true)) { 243 var div = document.createElement("div"); 244 div.innerHTML = content; 245 246 // Convert all middot paragraphs to li elements 247 var className = tinyMCE.getParam("paste_unindented_list_class", "unIndentedList"); 248 249 while (TinyMCE_PastePlugin._convertMiddots(div, "--list--")) ; // bull 250 while (TinyMCE_PastePlugin._convertMiddots(div, middot, className)) ; // Middot 251 while (TinyMCE_PastePlugin._convertMiddots(div, bull)) ; // bull 252 253 content = div.innerHTML; 254 } 255 256 // Replace all headers with strong and fix some other issues 257 if (tinyMCE.getParam("paste_convert_headers_to_strong", false)) { 258 content = content.replace(/<h[1-6]> <\/h[1-6]>/gi, '<p> </p>'); 259 content = content.replace(/<h[1-6]>/gi, '<p><b>'); 260 content = content.replace(/<\/h[1-6]>/gi, '</b></p>'); 261 content = content.replace(/<b> <\/b>/gi, '<b> </b>'); 262 content = content.replace(/^( )*/gi, ''); 263 } 264 265 content = content.replace(/--list--/gi, ""); // Remove --list-- 266 267 if ((cb = tinyMCE.getParam("paste_insert_word_content_callback", "")) != "") 268 content = eval(cb + "('after', content)"); 269 270 // Insert cleaned content 271 tinyMCE.execCommand("mceInsertContent", false, content); 272 273 if (tinyMCE.getParam('paste_force_cleanup_wordpaste', true)) 274 window.setTimeout('tinyMCE.execCommand("mceCleanup");', 1); // Do normal cleanup detached from this thread 275 } 276 }, 277 278 _reEscape : function(s) { 279 var l = "?.\\*[](){}+^$:"; 280 var o = ""; 281 282 for (var i=0; i<s.length; i++) { 283 var c = s.charAt(i); 284 285 if (l.indexOf(c) != -1) 286 o += '\\' + c; 287 else 288 o += c; 289 } 290 291 return o; 292 }, 293 294 _convertMiddots : function(div, search, class_name) { 295 var mdot = String.fromCharCode(183); 296 var bull = String.fromCharCode(8226); 297 298 var nodes = div.getElementsByTagName("p"); 299 var prevul; 300 for (var i=0; i<nodes.length; i++) { 301 var p = nodes[i]; 302 303 // Is middot 304 if (p.innerHTML.indexOf(search) == 0) { 305 var ul = document.createElement("ul"); 306 307 if (class_name) 308 ul.className = class_name; 309 310 // Add the first one 311 var li = document.createElement("li"); 312 li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); 313 ul.appendChild(li); 314 315 // Add the rest 316 var np = p.nextSibling; 317 while (np) { 318 // If the node is whitespace, then 319 // ignore it and continue on. 320 if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) { 321 np = np.nextSibling; 322 continue; 323 } 324 325 if (search == mdot) { 326 if (np.nodeType == 1 && new RegExp('^o(\\s+| )').test(np.innerHTML)) { 327 // Second level of nesting 328 if (!prevul) { 329 prevul = ul; 330 ul = document.createElement("ul"); 331 prevul.appendChild(ul); 332 } 333 np.innerHTML = np.innerHTML.replace(/^o/, ''); 334 } else { 335 // Pop the stack if we're going back up to the first level 336 if (prevul) { 337 ul = prevul; 338 prevul = null; 339 } 340 // Not element or middot paragraph 341 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) 342 break; 343 } 344 } else { 345 // Not element or middot paragraph 346 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0) 347 break; 348 } 349 350 var cp = np.nextSibling; 351 var li = document.createElement("li"); 352 li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--| ', "gi"), ''); 353 np.parentNode.removeChild(np); 354 ul.appendChild(li); 355 np = cp; 356 } 357 358 p.parentNode.replaceChild(ul, p); 359 360 return true; 361 } 362 } 363 364 return false; 365 }, 366 367 _clipboardHTML : function() { 368 var div = document.getElementById('_TinyMCE_clipboardHTML'); 369 370 if (!div) { 371 var div = document.createElement('DIV'); 372 div.id = '_TinyMCE_clipboardHTML'; 373 374 with (div.style) { 375 visibility = 'hidden'; 376 overflow = 'hidden'; 377 position = 'absolute'; 378 width = 1; 379 height = 1; 380 } 381 382 document.body.appendChild(div); 383 } 384 385 div.innerHTML = ''; 386 var rng = document.body.createTextRange(); 387 rng.moveToElementText(div); 388 rng.execCommand('Paste'); 389 var html = div.innerHTML; 390 div.innerHTML = ''; 391 return html; 392 } 393 }; 394 395 tinyMCE.addPlugin("paste", TinyMCE_PastePlugin); 379 }); 380 381 // Register plugin 382 tinymce.PluginManager.add('paste', tinymce.plugins.PastePlugin); 383 })(); -
trunk/wp-includes/js/tinymce/plugins/paste/pastetext.htm
-
Property
svn:eol-style
set to
native
r3664 r6632 1 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 2 <head> 3 <title>{ $lang_paste_text_desc}</title>3 <title>{#paste.paste_text_desc}</title> 4 4 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 5 <script language="javascript"type="text/javascript" src="../../tiny_mce_popup.js"></script>6 <script language="javascript" type="text/javascript" src="jscripts/pastetext.js"></script>5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="js/pastetext.js"></script> 7 7 <base target="_self" /> 8 8 </head> 9 <body on load="tinyMCEPopup.executeOnLoad('onLoadInit();');" onresize="resizeInputs();" style="display: none">9 <body onresize="resizeInputs();" style="display:none; overflow:hidden;"> 10 10 <form name="source" onsubmit="saveContent();"> 11 <div style="float: left" class="title">{ $lang_paste_text_desc}</div>11 <div style="float: left" class="title">{#paste.paste_text_desc}</div> 12 12 13 13 <div style="float: right"> 14 <input type="checkbox" name="linebreaks" id="linebreaks" class="wordWrapCode" checked="checked" /><label for="linebreaks">{ $lang_paste_text_linebreaks}</label>14 <input type="checkbox" name="linebreaks" id="linebreaks" class="wordWrapCode" checked="checked" /><label for="linebreaks">{#paste_dlg.text_linebreaks}</label> 15 15 </div> 16 16 17 17 <br style="clear: both" /> 18 18 19 <div>{ $lang_paste_text_title}</div>19 <div>{#paste_dlg.text_title}</div> 20 20 21 21 <textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px;" dir="ltr" wrap="soft"></textarea> … … 23 23 <div class="mceActionPanel"> 24 24 <div style="float: left"> 25 <input type="button" name="insert" value="{ $lang_insert}" onclick="saveContent();" id="insert" />25 <input type="button" name="insert" value="{#insert}" onclick="saveContent();" id="insert" /> 26 26 </div> 27 27 28 28 <div style="float: right"> 29 <input type="button" name="cancel" value="{ $lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />29 <input type="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" /> 30 30 </div> 31 31 </div> -
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/paste/pasteword.htm
-
Property
svn:eol-style
set to
native
r3664 r6632 2 2 <head> 3 3 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 4 <title>{ $lang_paste_word_desc}</title>5 <script language="javascript"type="text/javascript" src="../../tiny_mce_popup.js"></script>6 <script language="javascript" type="text/javascript" src="jscripts/pasteword.js"></script>4 <title>{#paste.paste_word_desc}</title> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="js/pasteword.js"></script> 7 7 <link href="css/pasteword.css" rel="stylesheet" type="text/css" /> 8 8 <base target="_self" /> 9 9 </head> 10 <body on load="tinyMCEPopup.executeOnLoad('onLoadInit();');" onresize="resizeInputs();" style="display: none">10 <body onresize="resizeInputs();" style="display:none; overflow:hidden;"> 11 11 <form name="source" onsubmit="saveContent();" action="#"> 12 <div class="title">{ $lang_paste_word_desc}</div>12 <div class="title">{#paste.paste_word_desc}</div> 13 13 14 <div>{ $lang_paste_word_title}</div>14 <div>{#paste_dlg.word_title}</div> 15 15 16 16 <div id="iframecontainer"></div> … … 18 18 <div class="mceActionPanel"> 19 19 <div style="float: left"> 20 <input type="button" id="insert" name="insert" value="{ $lang_insert}" onclick="saveContent();" />20 <input type="button" id="insert" name="insert" value="{#insert}" onclick="saveContent();" /> 21 21 </div> 22 22 23 23 <div style="float: right"> 24 <input type="button" id="cancel" name="cancel" value="{ $lang_cancel}" onclick="tinyMCEPopup.close();" />24 <input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" /> 25 25 </div> 26 26 </div> -
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/spellchecker/config.php
r6360 r6632 1 1 <?php 2 $spellCheckerConfig = array(); 2 // General settings 3 $config['general.engine'] = 'GoogleSpell'; 4 //$config['general.engine'] = 'PSpell'; 5 //$config['general.engine'] = 'PSpellShell'; 3 6 4 // Spellchecker class use 5 // require_once("classes/TinyPspellShell.class.php"); // Command line pspell 6 require_once("classes/TinyGoogleSpell.class.php"); // Google web service 7 // require_once("classes/TinyPspell.class.php"); // Internal PHP version 7 // PSpell settings 8 $config['PSpell.mode'] = PSPELL_FAST; 9 $config['PSpell.spelling'] = ""; 10 $config['PSpell.jargon'] = ""; 11 $config['PSpell.encoding'] = ""; 8 12 9 // General settings 10 $spellCheckerConfig['enabled'] = true; 13 // PSpellShell settings 14 $config['PSpellShell.mode'] = PSPELL_FAST; 15 $config['PSpellShell.aspell'] = '/usr/bin/aspell'; 16 $config['PSpellShell.tmp'] = '/tmp'; 11 17 12 // Default settings 13 $spellCheckerConfig['default.language'] = 'en'; 14 $spellCheckerConfig['default.mode'] = PSPELL_FAST; 15 16 // Normaly not required to configure 17 $spellCheckerConfig['default.spelling'] = ""; 18 $spellCheckerConfig['default.jargon'] = ""; 19 $spellCheckerConfig['default.encoding'] = ""; 20 21 // Pspell shell specific settings 22 $spellCheckerConfig['tinypspellshell.aspell'] = '/usr/bin/aspell'; 23 $spellCheckerConfig['tinypspellshell.tmp'] = '/tmp'; 18 // Windows PSpellShell settings 19 //$config['PSpellShell.aspell'] = '"c:\Program Files\Aspell\bin\aspell.exe"'; 20 //$config['PSpellShell.tmp'] = 'c:/temp'; 24 21 ?> -
trunk/wp-includes/js/tinymce/plugins/spellchecker/css/content.css
-
Property
svn:eol-style
set to
native
r6360 r6632 1 .mceItemHiddenSpellWord { 2 background: url('../images/wline.gif') repeat-x bottom left; 3 cursor: default; 4 } 1 .mceItemHiddenSpellWord {background:url(../img/wline.gif) repeat-x bottom left; cursor:default;} -
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js
r6360 r6632 1 1 /** 2 * $Id: editor_plugin_src.js 289 2007-05-28 09:12:16Z spocke $2 * $Id: editor_plugin_src.js 425 2007-11-21 15:17:39Z spocke $ 3 3 * 4 4 * @author Moxiecode 5 * @copyright Copyright © 2004-200 6, Moxiecode Systems AB, All rights reserved.5 * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. 6 6 */ 7 7 8 tinyMCE.importPluginLanguagePack('spellchecker', 'en,fr,sv,nn,nb'); 9 10 // Plucin static class 11 var TinyMCE_SpellCheckerPlugin = { 12 _contextMenu : new TinyMCE_Menu(), 13 _menu : new TinyMCE_Menu(), 14 _counter : 0, 15 _ajaxPage : '/tinyspell.php', 16 17 getInfo : function() { 18 return { 19 longname : 'Spellchecker PHP', 20 author : 'Moxiecode Systems AB', 21 authorurl : 'http://tinymce.moxiecode.com', 22 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker', 23 version : "1.0.5" 24 }; 25 }, 26 27 handleEvent : function(e) { 28 var elm = tinyMCE.isMSIE ? e.srcElement : e.target; 29 var inst = tinyMCE.selectedInstance, args = ''; 30 var self = TinyMCE_SpellCheckerPlugin; 31 var cm = self._contextMenu; 32 var p, p2, x, y, sx, sy, h, elm; 33 34 // Handle click on word 35 if ((e.type == "click" || e.type == "contextmenu") && elm) { 36 do { 37 if (tinyMCE.getAttrib(elm, 'class') == "mceItemHiddenSpellWord") { 38 inst.spellCheckerElm = elm; 39 40 // Setup arguments 41 args += 'id=' + inst.editorId + "|" + (++self._counter); 42 args += '&cmd=suggest&check=' + encodeURIComponent(elm.innerHTML); 43 args += '&lang=' + escape(inst.spellCheckerLang); 44 45 elm = inst.spellCheckerElm; 46 p = tinyMCE.getAbsPosition(inst.iframeElement); 47 p2 = tinyMCE.getAbsPosition(elm); 48 h = parseInt(elm.offsetHeight); 49 sx = inst.getBody().scrollLeft; 50 sy = inst.getBody().scrollTop; 51 x = p.absLeft + p2.absLeft - sx; 52 y = p.absTop + p2.absTop - sy + h; 53 54 cm.clear(); 55 cm.addTitle(tinyMCE.getLang('lang_spellchecker_wait', '', true)); 56 cm.show(); 57 cm.moveTo(x, y); 58 59 inst.selection.selectNode(elm, false, false); 60 61 self._sendAjax(self.baseURL + self._ajaxPage, self._ajaxResponse, 'post', args); 62 63 tinyMCE.cancelEvent(e); 64 return false; 65 } 66 } while ((elm = elm.parentNode)); 67 } 68 69 return true; 70 }, 71 72 initInstance : function(inst) { 73 var self = TinyMCE_SpellCheckerPlugin, m = self._menu, cm = self._contextMenu, e; 74 75 tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/spellchecker/css/content.css"); 76 77 if (!tinyMCE.hasMenu('spellcheckercontextmenu')) { 78 tinyMCE.importCSS(document, tinyMCE.baseURL + "/plugins/spellchecker/css/spellchecker.css"); 79 80 cm.init({drop_menu : false}); 81 tinyMCE.addMenu('spellcheckercontextmenu', cm); 82 } 83 84 if (!tinyMCE.hasMenu('spellcheckermenu')) { 85 m.init({}); 86 tinyMCE.addMenu('spellcheckermenu', m); 87 } 88 89 inst.spellCheckerLang = 'en'; 90 self._buildSettingsMenu(inst, null); 91 92 e = self._getBlockBoxLayer(inst).create('div', 'mceBlockBox', document.getElementById(inst.editorId + '_parent')); 93 self._getMsgBoxLayer(inst).create('div', 'mceMsgBox', document.getElementById(inst.editorId + '_parent')); 94 }, 95 96 _getMsgBoxLayer : function(inst) { 97 if (!inst.spellCheckerMsgBoxL) 98 inst.spellCheckerMsgBoxL = new TinyMCE_Layer(inst.editorId + '_spellcheckerMsgBox', false); 99 100 return inst.spellCheckerMsgBoxL; 101 }, 102 103 _getBlockBoxLayer : function(inst) { 104 if (!inst.spellCheckerBoxL) 105 inst.spellCheckerBoxL = new TinyMCE_Layer(inst.editorId + '_spellcheckerBlockBox', false); 106 107 return inst.spellCheckerBoxL; 108 }, 109 110 _buildSettingsMenu : function(inst, lang) { 111 var i, ar = tinyMCE.getParam('spellchecker_languages', '+English=en').split(','), p; 112 var self = TinyMCE_SpellCheckerPlugin, m = self._menu, c; 113 114 m.clear(); 115 m.addTitle(tinyMCE.getLang('lang_spellchecker_langs', '', true)); 116 117 for (i=0; i<ar.length; i++) { 118 if (ar[i] != '') { 119 p = ar[i].split('='); 120 c = 'mceMenuCheckItem'; 121 122 if (p[0].charAt(0) == '+') { 123 p[0] = p[0].substring(1); 124 125 if (lang == null) { 126 c = 'mceMenuSelectedItem'; 127 inst.spellCheckerLang = p[1]; 128 } 129 } 130 131 if (lang == p[1]) 132 c = 'mceMenuSelectedItem'; 133 134 m.add({text : p[0], js : "tinyMCE.execInstanceCommand('" + inst.editorId + "','mceSpellCheckerSetLang',false,'" + p[1] + "');", class_name : c}); 8 (function() { 9 var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM; 10 11 tinymce.create('tinymce.plugins.SpellcheckerPlugin', { 12 getInfo : function() { 13 return { 14 longname : 'Spellchecker', 15 author : 'Moxiecode Systems AB', 16 authorurl : 'http://tinymce.moxiecode.com', 17 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker', 18 version : "2.0b2" 19 }; 20 }, 21 22 init : function(ed, url) { 23 var t = this, cm; 24 25 t.url = url; 26 t.editor = ed; 27 28 // Register commands 29 ed.addCommand('mceSpellCheck', function() { 30 if (!t.active) { 31 ed.setProgressState(1); 32 t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) { 33 if (r.length > 0) { 34 t.active = 1; 35 t._markWords(r); 36 ed.setProgressState(0); 37 ed.nodeChanged(); 38 } else { 39 ed.setProgressState(0); 40 ed.windowManager.alert('spellchecker.no_mpell'); 41 } 42 }); 43 } else 44 t._done(); 45 }); 46 47 ed.onInit.add(function() { 48 ed.dom.loadCSS(url + '/css/content.css'); 49 }); 50 51 ed.onClick.add(t._showMenu, t); 52 ed.onContextMenu.add(t._showMenu, t); 53 ed.onBeforeGetContent.add(function() { 54 if (t.active) 55 t._removeWords(); 56 }); 57 58 ed.onNodeChange.add(function(ed, cm) { 59 cm.setActive('spellchecker', t.active); 60 }); 61 62 ed.onSetContent.add(function() { 63 t._done(); 64 }); 65 66 ed.onBeforeGetContent.add(function() { 67 t._done(); 68 }); 69 70 ed.onBeforeExecCommand.add(function(ed, cmd) { 71 if (cmd == 'mceFullScreen') 72 t._done(); 73 }); 74 75 // Find selected language 76 t.languages = {}; 77 each(ed.getParam('spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv').split(','), function(v) { 78 v = v.split('='); 79 80 if (v[0].indexOf('+') === 0) { 81 v[0] = v[0].substring(1); 82 t.selectedLang = v[1]; 83 } 84 85 t.languages[v[0]] = v[1]; 86 }); 87 }, 88 89 createControl : function(n, cm) { 90 var t = this, c, ed = t.editor; 91 92 if (n == 'spellchecker') { 93 c = cm.createSplitButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); 94 95 c.onRenderMenu.add(function(c, m) { 96 m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 97 each(t.languages, function(v, k) { 98 var o = {icon : 1}, mi; 99 100 o.onclick = function() { 101 mi.setSelected(1); 102 t.selectedItem.setSelected(0); 103 t.selectedItem = mi; 104 t.selectedLang = v; 105 }; 106 107 o.title = k; 108 mi = m.add(o); 109 mi.setSelected(v == t.selectedLang); 110 111 if (v == t.selectedLang) 112 t.selectedItem = mi; 113 }) 114 }); 115 116 return c; 135 117 } 136 } 137 }, 138 139 setupContent : function(editor_id, body, doc) { 140 TinyMCE_SpellCheckerPlugin._removeWords(doc, null, true); 141 }, 142 143 getControlHTML : function(cn) { 144 switch (cn) { 145 case "spellchecker": 146 return TinyMCE_SpellCheckerPlugin._getMenuButtonHTML(cn, 'lang_spellchecker_desc', '{$pluginurl}/images/spellchecker.gif', 'lang_spellchecker_desc', 'mceSpellCheckerMenu', 'mceSpellCheck'); 147 } 148 149 return ""; 150 }, 151 152 /** 153 * Returns the HTML code for a normal button control. 154 * 155 * @param {string} id Button control id, this will be the suffix for the element id, the prefix is the editor id. 156 * @param {string} lang Language variable key name to insert as the title/alt of the button image. 157 * @param {string} img Image URL to insert, {$themeurl} and {$pluginurl} will be replaced. 158 * @param {string} mlang Language variable key name to insert as the title/alt of the menu button image. 159 * @param {string} mid Menu by id to display when the menu button is pressed. 160 * @param {string} cmd Command to execute when the user clicks the button. 161 * @param {string} ui Optional user interface boolean for command. 162 * @param {string} val Optional value for command. 163 * @return HTML code for a normal button based in input information. 164 * @type string 165 */ 166 _getMenuButtonHTML : function(id, lang, img, mlang, mid, cmd, ui, val) { 167 var h = '', m, x; 168 169 cmd = 'tinyMCE.hideMenus();tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; 170 171 if (typeof(ui) != "undefined" && ui != null) 172 cmd += ',' + ui; 173 174 if (typeof(val) != "undefined" && val != null) 175 cmd += ",'" + val + "'"; 176 177 cmd += ');'; 178 179 // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled 180 if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isMSIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { 181 // Tiled button 182 x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); 183 h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceTiledButton mceButtonNormal" target="_self">'; 184 h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" title="{$' + lang + '}" />'; 185 h += '<img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" onclick="' + mcmd + 'return false;" />'; 186 h += '</a>'; 187 } else { 188 if (tinyMCE.isMSIE && !tinyMCE.isOpera) 189 h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton" onmouseover="tinyMCE.plugins.spellchecker._menuButtonEvent(\'over\',this);" onmouseout="tinyMCE.plugins.spellchecker._menuButtonEvent(\'out\',this);">'; 190 else 191 h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton">'; 192 193 h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceMenuButtonNormal" target="_self">'; 194 h += '<img src="' + img + '" title="{$' + lang + '}" /></a>'; 195 h += '<a href="#" onclick="tinyMCE.plugins.spellchecker._toggleMenu(\'{$editor_id}\',\'' + mid + '\');return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />'; 196 h += '</a></span>'; 197 } 198 199 return h; 200 }, 201 202 _menuButtonEvent : function(e, o) { 203 var t = this; 204 205 // Give IE some time since it's buggy!! :( 206 window.setTimeout(function() { 207 t._menuButtonEvent2(e, o); 208 }, 1); 209 }, 210 211 _menuButtonEvent2 : function(e, o) { 212 if (o.className == 'mceMenuButtonFocus') 213 return; 214 215 if (e == 'over') 216 o.className = o.className + ' mceMenuHover'; 217 else 218 o.className = o.className.replace(/\s.*$/, ''); 219 }, 220 221 _toggleMenu : function(editor_id, id) { 222 var self = TinyMCE_SpellCheckerPlugin; 223 var e = document.getElementById(editor_id + '_spellchecker'); 224 var inst = tinyMCE.getInstanceById(editor_id); 225 226 if (self._menu.isVisible()) { 227 tinyMCE.hideMenus(); 228 return; 229 } 230 231 tinyMCE.lastMenuBtnClass = e.className.replace(/\s.*$/, ''); 232 tinyMCE.switchClass(editor_id + '_spellchecker', 'mceMenuButtonFocus'); 233 234 self._menu.moveRelativeTo(e, 'bl'); 235 self._menu.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? 0 : 1, -1); 236 237 if (tinyMCE.isOpera) 238 self._menu.moveBy(0, -2); 239 240 self._onMenuEvent(inst, self._menu, 'show'); 241 242 self._menu.show(); 243 244 tinyMCE.lastSelectedMenuBtn = editor_id + '_spellchecker'; 245 }, 246 247 _onMenuEvent : function(inst, m, n) { 248 TinyMCE_SpellCheckerPlugin._buildSettingsMenu(inst, inst.spellCheckerLang); 249 }, 250 251 execCommand : function(editor_id, element, command, user_interface, value) { 252 var inst = tinyMCE.getInstanceById(editor_id), self = TinyMCE_SpellCheckerPlugin, args = '', co, bb, mb, nl, i, e, mbs; 253 254 // Handle commands 255 switch (command) { 256 case "mceSpellCheck": 257 if (!inst.spellcheckerOn) { 258 inst.spellCheckerBookmark = inst.selection.getBookmark(); 259 260 // Fix for IE bug: #1610184 261 if (tinyMCE.isRealIE) 262 tinyMCE.setInnerHTML(inst.getBody(), inst.getBody().innerHTML); 263 264 // Setup arguments 265 args += 'id=' + inst.editorId + "|" + (++self._counter); 266 args += '&cmd=spell&check=' + encodeURIComponent(self._getWordList(inst.getBody())).replace(/\'/g, '%27'); 267 args += '&lang=' + escape(inst.spellCheckerLang); 268 269 co = document.getElementById(inst.editorId + '_parent').firstChild; 270 bb = self._getBlockBoxLayer(inst); 271 bb.moveRelativeTo(co, 'tl'); 272 bb.resizeTo(co.offsetWidth, co.offsetHeight); 273 bb.show(); 274 275 // Setup message box 276 mb = self._getMsgBoxLayer(inst); 277 e = mb.getElement(); 278 279 if (e.childNodes[0]) 280 e.removeChild(e.childNodes[0]); 281 282 mbs = document.createElement("span"); 283 mbs.innerHTML = '<span>' + tinyMCE.getLang('lang_spellchecker_swait', '', true) + '</span>'; 284 e.appendChild(mbs); 285 286 mb.show(); 287 mb.moveRelativeTo(co, 'cc'); 288 289 if (tinyMCE.isMSIE && !tinyMCE.isOpera) { 290 nl = co.getElementsByTagName('select'); 291 for (i=0; i<nl.length; i++) 292 nl[i].disabled = true; 293 } 294 295 inst.spellcheckerOn = true; 296 tinyMCE.switchClass(editor_id + '_spellchecker', 'mceMenuButtonSelected'); 297 298 self._sendAjax(self.baseURL + self._ajaxPage, self._ajaxResponse, 'post', args); 299 } else { 300 self._removeWords(inst.getDoc()); 301 inst.spellcheckerOn = false; 302 tinyMCE.switchClass(editor_id + '_spellchecker', 'mceMenuButton'); 303 } 304 305 return true; 306 307 case "mceSpellCheckReplace": 308 if (inst.spellCheckerElm) 309 tinyMCE.setOuterHTML(inst.spellCheckerElm, value); 310 311 self._checkDone(inst); 312 self._contextMenu.hide(); 313 self._menu.hide(); 314 315 return true; 316 317 case "mceSpellCheckIgnore": 318 if (inst.spellCheckerElm) 319 self._removeWord(inst.spellCheckerElm); 320 321 self._checkDone(inst); 322 self._contextMenu.hide(); 323 self._menu.hide(); 324 return true; 325 326 case "mceSpellCheckIgnoreAll": 327 if (inst.spellCheckerElm) 328 self._removeWords(inst.getDoc(), inst.spellCheckerElm.innerHTML); 329 330 self._checkDone(inst); 331 self._contextMenu.hide(); 332 self._menu.hide(); 333 return true; 334 335 case "mceSpellCheckerSetLang": 336 tinyMCE.hideMenus(); 337 inst.spellCheckerLang = value; 338 self._removeWords(inst.getDoc()); 339 inst.spellcheckerOn = false; 340 tinyMCE.switchClass(editor_id + '_spellchecker', 'mceMenuButton'); 341 return true; 342 } 343 344 // Pass to next handler in chain 345 return false; 346 }, 347 348 cleanup : function(type, content, inst) { 349 switch (type) { 350 case "get_from_editor_dom": 351 TinyMCE_SpellCheckerPlugin._removeWords(content, null, true); 352 inst.spellcheckerOn = false; 353 break; 354 } 355 356 return content; 357 }, 358 359 // Private plugin specific methods 360 361 _displayUI : function(inst) { 362 var self = TinyMCE_SpellCheckerPlugin; 363 var bb = self._getBlockBoxLayer(inst); 364 var mb = self._getMsgBoxLayer(inst); 365 var nl, i; 366 var co = document.getElementById(inst.editorId + '_parent').firstChild; 367 368 if (tinyMCE.isMSIE && !tinyMCE.isOpera) { 369 nl = co.getElementsByTagName('select'); 370 for (i=0; i<nl.length; i++) 371 nl[i].disabled = false; 372 } 373 374 bb.hide(); 375 376 // Boom, crash in FF if focus isn't else were 377 // el.style.display='none' on a opacity element seems to crash it 378 mb.hide(); 379 }, 380 381 _ajaxResponse : function(xml, text) { 382 var el = xml ? xml.documentElement : null; 383 var inst = tinyMCE.selectedInstance, self = TinyMCE_SpellCheckerPlugin; 384 var cmd = el ? el.getAttribute("cmd") : null, err, id = el ? el.getAttribute("id") : null; 385 386 if (id) 387 inst = tinyMCE.getInstanceById(id.substring(0, id.indexOf('|'))); 388 389 // Workaround for crash in Gecko 390 if (tinyMCE.isGecko) 391 window.focus(); 392 393 self._displayUI(inst); 394 395 // Restore the selection again 396 if (tinyMCE.isGecko) { 397 inst.getWin().focus(); 398 inst.selection.moveToBookmark(inst.spellCheckerBookmark); 399 } 400 401 // Ignore suggestions for other ajax responses 402 if (cmd == "suggest" && id != inst.editorId + "|" + self._counter) 403 return; 404 405 if (!el) { 406 text = '' + text; 407 408 if (text.length > 500) 409 text = text.substring(500); 410 411 inst.spellcheckerOn = false; 412 tinyMCE.switchClass(inst.editorId + '_spellchecker', 'mceMenuButton'); 413 alert("Could not execute AJAX call, server didn't return valid a XML.\nResponse: " + text); 414 return; 415 } 416 417 err = el.getAttribute("error"); 418 419 if (err == "true") { 420 inst.spellcheckerOn = false; 421 tinyMCE.switchClass(inst.editorId + '_spellchecker', 'mceMenuButton'); 422 alert(el.getAttribute("msg")); 423 return; 424 } 425 426 switch (cmd) { 427 case "spell": 428 if (xml.documentElement.firstChild) { 429 self._markWords(inst.getDoc(), inst.getBody(), decodeURIComponent(el.firstChild.nodeValue).split('+')); 430 inst.selection.moveToBookmark(inst.spellCheckerBookmark); 431 432 if(tinyMCE.getParam('spellchecker_report_misspellings', false)) 433 alert(tinyMCE.getLang('lang_spellchecker_mpell_found', '', true, {words : self._countWords(inst)})); 434 } else 435 alert(tinyMCE.getLang('lang_spellchecker_no_mpell', '', true)); 436 437 self._checkDone(inst); 438 439 // Odd stuff FF removed useCSS, disable state for it 440 inst.useCSS = false; 441 442 break; 443 444 case "suggest": 445 self._buildMenu(el.firstChild ? decodeURIComponent(el.firstChild.nodeValue).split('+') : null, 10); 446 self._contextMenu.show(); 447 break; 448 } 449 }, 450 451 _getWordSeparators : function() { 452 var i, re = '', ch = tinyMCE.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}§©«®±¶·¸»¼½¾¿×÷¤\u201d\u201c'); 453 454 for (i=0; i<ch.length; i++) 455 re += '\\' + ch.charAt(i); 456 457 return re; 458 }, 459 460 _getWordList : function(n) { 461 var i, x, s, nv = '', nl = tinyMCE.getNodeTree(n, [], 3), wl = []; 462 var re = TinyMCE_SpellCheckerPlugin._getWordSeparators(); 463 464 for (i=0; i<nl.length; i++) { 465 if (!new RegExp('/SCRIPT|STYLE/').test(nl[i].parentNode.nodeName)) 466 nv += nl[i].nodeValue + " "; 467 } 468 469 nv = nv.replace(new RegExp('([0-9]|[' + re + '])', 'g'), ' '); 470 nv = tinyMCE.trim(nv.replace(/(\s+)/g, ' ')); 471 472 nl = nv.split(/\s+/); 473 for (i=0; i<nl.length; i++) { 474 s = false; 475 for (x=0; x<wl.length; x++) { 476 if (wl[x] == nl[i]) { 477 s = true; 478 break; 479 } 480 } 481 482 if (!s && nl[i].length > 0) 483 wl[wl.length] = nl[i]; 484 } 485 486 return wl.join(' '); 487 }, 488 489 _removeWords : function(doc, word, cleanup) { 490 var i, c, nl = doc.getElementsByTagName("span"); 491 var self = TinyMCE_SpellCheckerPlugin; 492 var inst = tinyMCE.selectedInstance, b = inst ? inst.selection.getBookmark() : null; 493 494 word = typeof(word) == 'undefined' ? null : word; 495 496 for (i=nl.length-1; i>=0; i--) { 497 c = tinyMCE.getAttrib(nl[i], 'class'); 498 499 if ((c == 'mceItemHiddenSpellWord' || c == 'mceItemHidden') && (word == null || nl[i].innerHTML == word)) 500 self._removeWord(nl[i]); 501 } 502 503 if (b && !cleanup) 504 inst.selection.moveToBookmark(b); 505 }, 506 507 _checkDone : function(inst) { 508 var self = TinyMCE_SpellCheckerPlugin; 509 var w = self._countWords(inst); 510 511 if (w == 0) { 512 self._removeWords(inst.getDoc()); 513 inst.spellcheckerOn = false; 514 tinyMCE.switchClass(inst.editorId + '_spellchecker', 'mceMenuButton'); 515 } 516 }, 517 518 _countWords : function(inst) { 519 var i, w = 0, nl = inst.getDoc().getElementsByTagName("span"), c; 520 var self = TinyMCE_SpellCheckerPlugin; 521 522 for (i=nl.length-1; i>=0; i--) { 523 c = tinyMCE.getAttrib(nl[i], 'class'); 524 525 if (c == 'mceItemHiddenSpellWord') 526 w++; 527 } 528 529 return w; 530 }, 531 532 _removeWord : function(e) { 533 if (e != null) 534 tinyMCE.setOuterHTML(e, e.innerHTML); 535 }, 536 537 _markWords : function(doc, n, wl) { 538 var i, nv, nn, nl = tinyMCE.getNodeTree(n, new Array(), 3); 539 var r1, r2, r3, r4, r5, w = ''; 540 var re = TinyMCE_SpellCheckerPlugin._getWordSeparators(); 541 542 for (i=0; i<wl.length; i++) { 543 if (wl[i].length > 0) 544 w += wl[i] + ((i == wl.length-1) ? '' : '|'); 545 } 546 547 for (i=0; i<nl.length; i++) { 548 nv = nl[i].nodeValue; 118 }, 119 120 // Internal functions 121 122 _walk : function(n, f) { 123 var d = this.editor.getDoc(), w; 124 125 if (d.createTreeWalker) { 126 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); 127 128 while ((n = w.nextNode()) != null) 129 f.call(this, n); 130 } else 131 tinymce.walk(n, f, 'childNodes'); 132 }, 133 134 _getSeparators : function() { 135 var re = '', i, str = this.editor.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}§©«®±¶·¸»¼½¾¿×÷¤\u201d\u201c'); 136 137 // Build word separator regexp 138 for (i=0; i<str.length; i++) 139 re += '\\' + str.charAt(i); 140 141 return re; 142 }, 143 144 _getWords : function() { 145 var ed = this.editor, wl = [], tx = '', lo = {}; 146 147 // Get area text 148 this._walk(ed.getBody(), function(n) { 149 if (n.nodeType == 3) 150 tx += n.nodeValue + ' '; 151 }); 152 153 // Split words by separator 154 tx = tx.replace(new RegExp('([0-9]|[' + this._getSeparators() + '])', 'g'), ' '); 155 tx = tinymce.trim(tx.replace(/(\s+)/g, ' ')); 156 157 // Build word array and remove duplicates 158 each(tx.split(' '), function(v) { 159 if (!lo[v]) { 160 wl.push(v); 161 lo[v] = 1; 162 } 163 }); 164 165 return wl; 166 }, 167 168 _removeWords : function(w) { 169 var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark(); 170 171 each(dom.select('span').reverse(), function(n) { 172 if (n && (dom.hasClass(n, 'mceItemHiddenSpellWord') || dom.hasClass(n, 'mceItemHidden'))) { 173 if (!w || dom.decode(n.innerHTML) == w) 174 dom.remove(n, 1); 175 } 176 }); 177 178 se.moveToBookmark(b); 179 }, 180 181 _markWords : function(wl) { 182 var r1, r2, r3, r4, r5, w = '', ed = this.editor, re = this._getSeparators(), dom = ed.dom, nl = []; 183 var se = ed.selection, b = se.getBookmark(); 184 185 each(wl, function(v) { 186 w += (w ? '|' : '') + v; 187 }); 549 188 550 189 r1 = new RegExp('([' + re + '])(' + w + ')([' + re + '])', 'g'); … … 554 193 r5 = new RegExp('(' + w + ')([' + re + '])', 'g'); 555 194 556 if (r1.test(nv) || r2.test(nv) || r3.test(nv) || r4.test(nv)) { 557 nv = tinyMCE.xmlEncode(nv).replace(''', "'"); 558 nv = nv.replace(r5, '<span class="mceItemHiddenSpellWord">$1</span>$2'); 559 nv = nv.replace(r3, '<span class="mceItemHiddenSpellWord">$1</span>$2'); 560 561 nn = doc.createElement('span'); 562 nn.className = "mceItemHidden"; 563 nn.innerHTML = nv; 564 565 // Remove old text node 566 nl[i].parentNode.replaceChild(nn, nl[i]); 195 // Collect all text nodes 196 this._walk(this.editor.getBody(), function(n) { 197 if (n.nodeType == 3) { 198 nl.push(n); 199 } 200 }); 201 202 // Wrap incorrect words in spans 203 each(nl, function(n) { 204 var v; 205 206 if (n.nodeType == 3) { 207 v = n.nodeValue; 208 209 if (r1.test(v) || r2.test(v) || r3.test(v) || r4.test(v)) { 210 v = dom.encode(v); 211 v = v.replace(r5, '<span class="mceItemHiddenSpellWord">$1</span>$2'); 212 v = v.replace(r3, '<span class="mceItemHiddenSpellWord">$1</span>$2'); 213 214 dom.replace(dom.create('span', {'class' : 'mceItemHidden'}, v), n); 215 } 216 } 217 }); 218 219 se.moveToBookmark(b); 220 }, 221 222 _showMenu : function(ed, e) { 223 var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()); 224 225 if (!m) { 226 p1 = DOM.getPos(ed.getContentAreaContainer()); 227 //p2 = DOM.getPos(ed.getContainer()); 228 229 m = ed.controlManager.createDropMenu('spellcheckermenu', { 230 offset_x : p1.x, 231 offset_y : p1.y, 232 'class' : 'noIcons' 233 }); 234 235 t._menu = m; 567 236 } 237 238 if (dom.hasClass(e.target, 'mceItemHiddenSpellWord')) { 239 m.removeAll(); 240 m.add({title : 'spellchecker.wait', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 241 242 t._sendRPC('getSuggestions', [t.selectedLang, dom.decode(e.target.innerHTML)], function(r) { 243 m.removeAll(); 244 245 if (r.length > 0) { 246 m.add({title : 'spellchecker.sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 247 each(r, function(v) { 248 m.add({title : v, onclick : function() { 249 dom.replace(ed.getDoc().createTextNode(v), e.target); 250 t._checkDone(); 251 }}); 252 }); 253 254 m.addSeparator(); 255 } else 256 m.add({title : 'spellchecker.no_sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 257 258 m.add({ 259 title : 'spellchecker.ignore_word', 260 onclick : function() { 261 dom.remove(e.target, 1); 262 t._checkDone(); 263 } 264 }); 265 266 m.add({ 267 title : 'spellchecker.ignore_words', 268 onclick : function() { 269 t._removeWords(dom.decode(e.target.innerHTML)); 270 t._checkDone(); 271 } 272 }); 273 274 m.update(); 275 }); 276 277 ed.selection.select(e.target); 278 p1 = dom.getPos(e.target); 279 m.showMenu(p1.x, p1.y + e.target.offsetHeight - vp.y); 280 281 return tinymce.dom.Event.cancel(e); 282 } else 283 m.hideMenu(); 284 }, 285 286 _checkDone : function() { 287 var t = this, ed = t.editor, dom = ed.dom, o; 288 289 each(dom.select('span'), function(n) { 290 if (n && dom.hasClass(n, 'mceItemHiddenSpellWord')) { 291 o = true; 292 return false; 293 } 294 }); 295 296 if (!o) 297 t._done(); 298 }, 299 300 _done : function() { 301 var t = this, la = t.active; 302 303 t.active = 0; 304 t._removeWords(); 305 306 if (t._menu) 307 t._menu.hideMenu(); 308 309 if (la) 310 t.editor.nodeChanged(); 311 }, 312 313 _sendRPC : function(m, p, cb) { 314 var t = this, url = t.editor.getParam("spellchecker_rpc_url", this.url+'/rpc.php'); 315 316 if (url == '{backend}') { 317 alert('Please specify: spellchecker_rpc_url'); 318 return; 319 } 320 321 JSONRequest.sendRPC({ 322 url : url, 323 method : m, 324 params : p, 325 success : cb, 326 error : function(e, x) { 327 t.editor.setProgressState(0); 328 t.editor.windowManager.alert(e.errstr || ('Error response: ' + x.responseText)); 329 } 330 }); 568 331 } 569 }, 570 571 _buildMenu : function(sg, max) { 572 var i, self = TinyMCE_SpellCheckerPlugin, cm = self._contextMenu; 573 574 cm.clear(); 575 576 if (sg != null) { 577 cm.addTitle(tinyMCE.getLang('lang_spellchecker_sug', '', true)); 578 579 for (i=0; i<sg.length && i<max; i++) 580 cm.addItem(sg[i], 'tinyMCE.execCommand("mceSpellCheckReplace",false,"' + sg[i] + '");'); 581 582 cm.addSeparator(); 583 } else 584 cm.addTitle(tinyMCE.getLang('lang_spellchecker_no_sug', '', true)); 585 586 cm.addItem(tinyMCE.getLang('lang_spellchecker_ignore_word', '', true), 'tinyMCE.execCommand(\'mceSpellCheckIgnore\');'); 587 cm.addItem(tinyMCE.getLang('lang_spellchecker_ignore_words', '', true), 'tinyMCE.execCommand(\'mceSpellCheckIgnoreAll\');'); 588 589 cm.update(); 590 }, 591 592 _getAjaxHTTP : function() { 593 try { 594 return new ActiveXObject('Msxml2.XMLHTTP') 595 } catch (e) { 596 try { 597 return new ActiveXObject('Microsoft.XMLHTTP') 598 } catch (e) { 599 return new XMLHttpRequest(); 600 } 601 } 602 }, 603 604 /** 605 * Perform AJAX call. 606 * 607 * @param {string} u URL of AJAX service. 608 * @param {function} f Function to call when response arrives. 609 * @param {string} m Request method post or get. 610 * @param {Array} a Array with arguments to send. 611 */ 612 _sendAjax : function(u, f, m, a) { 613 var x = TinyMCE_SpellCheckerPlugin._getAjaxHTTP(); 614 615 x.open(m, u, true); 616 617 x.onreadystatechange = function() { 618 if (x.readyState == 4) 619 f(x.responseXML, x.responseText); 620 }; 621 622 if (m == 'post') 623 x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 624 625 x.send(a); 626 } 627 }; 628 629 // Register plugin 630 tinyMCE.addPlugin('spellchecker', TinyMCE_SpellCheckerPlugin); 332 }); 333 334 // Register plugin 335 tinymce.PluginManager.add('spellchecker', tinymce.plugins.SpellcheckerPlugin); 336 })(); -
trunk/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js
r6567 r6632 1 1 /* Import plugin specific language pack */ 2 tinyMCE.importPluginLanguagePack('wordpress', 'en');2 //tinyMCE.importPluginLanguagePack('wordpress', 'en'); 3 3 4 4 var TinyMCE_wordpressPlugin = { … … 288 288 // We have a TON of cleanup to do. 289 289 290 if ( tinyMCE.activeEditor.isHidden() ) { 291 // return content; 292 } 293 290 294 // Mark </p> if it has any attributes. 291 295 content = content.replace(new RegExp('(<p[^>]+>.*?)</p>', 'mg'), '$1</p#>'); … … 295 299 296 300 // Get it ready for wpautop. 297 301 content = content.replace(new RegExp('\\s*<p>', 'mgi'), ''); 298 302 content = content.replace(new RegExp('\\s*</p>\\s*', 'mgi'), '\n\n'); 299 303 content = content.replace(new RegExp('\\n\\s*\\n', 'mgi'), '\n\n'); … … 305 309 content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n'); 306 310 content = content.replace(new RegExp('<li>', 'g'), '\t<li>'); 307 311 312 if ( content.indexOf('<object') != -1 ) { 313 content = content.replace(new RegExp('\\s*<param([^>]*)>\\s*', 'g'), "<param$1>"); // no pee inside object/embed 314 content = content.replace(new RegExp('\\s*</embed>\\s*', 'g'), '</embed>'); 315 } 316 308 317 // Unmark special paragraph closing tags 309 318 content = content.replace(new RegExp('</p#>', 'g'), '</p>\n'); … … 366 375 }; 367 376 368 tinyMCE.addPlugin("wordpress", TinyMCE_wordpressPlugin);377 //tinyMCE.addPlugin("wordpress", TinyMCE_wordpressPlugin); 369 378 370 379 /* This little hack protects our More and Page placeholders from the removeformat command */ … … 477 486 var pdr = ta.parentNode; 478 487 479 if ( inst ) {488 if ( ! inst.isHidden(id) ) { 480 489 edToggle(H, P); 481 490 … … 493 502 var y1 = table.offsetTop + table.offsetHeight; 494 503 495 if ( TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_height") == null ) {504 if ( tinymce.util.Cookie.get("TinyMCE_" + inst.editorId + "_height") == null ) { 496 505 var expires = new Date(); 497 506 expires.setTime(expires.getTime() + 3600000 * 24 * 30); 498 507 var offset = tinyMCE.isMSIE ? 1 : 2; 499 TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + inst.editorId + "_height", "" + (table.offsetHeight - offset), expires);508 tinymce.util.Cookie.set("TinyMCE_" + inst.editorId + "_height", "" + (table.offsetHeight - offset), expires); 500 509 } 501 510 502 511 // Unload the rich editor 503 inst.triggerSave(false, false);504 htm =inst.formElement.value;505 tinyMCE.removeMCEControl(id);506 document.getElementById(id).value = htm;507 --tinyMCE.idCounter;512 // inst.triggerSave(false, false); 513 // inst.formElement.value; 514 inst.hide(); // tinyMCE.removeMCEControl(id); 515 // document.getElementById(id).value = htm; 516 // --tinyMCE.idCounter; 508 517 509 518 // Reveal Quicktags and textarea … … 544 553 545 554 // Load the rich editor with formatted html 546 if ( tinyMCE.isMSIE ) { 555 //if ( tinyMCE.isMSIE ) { 556 // ta.value = wpautop(ta.value); 557 // tinyMCE.addMCEControl(ta, id); 558 //} else { 547 559 ta.value = wpautop(ta.value); 548 tinyMCE.addMCEControl(ta, id); 549 } else { 550 htm = wpautop(ta.value); 551 tinyMCE.addMCEControl(ta, id); 552 tinyMCE.getInstanceById(id).execCommand('mceSetContent', null, htm); 553 } 560 inst.show() // tinyMCE.addMCEControl(ta, id); 561 //tinyMCE.getInstanceById(id).execCommand('mceSetContent', null, htm); 562 //} 554 563 555 564 if ( tinyMCE.isMSIE && !tinyMCE.isOpera ) { -
trunk/wp-includes/js/tinymce/plugins/wordpress/popups.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/plugins/wordpress/wordpress.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/themes/advanced/about.htm
r4799 r6632 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 1 2 <html xmlns="http://www.w3.org/1999/xhtml"> 2 3 <head> 3 <title>{$lang_about_title}</title> 4 <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script> 5 <script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script> 6 <script language="javascript" type="text/javascript" src="jscripts/about.js"></script> 7 <base target="_self" /> 4 <title>{#advanced_dlg.about_title}</title> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="../../utils/mctabs.js"></script> 7 <script type="text/javascript" src="js/about.js"></script> 8 8 </head> 9 <body id="about" onload="tinyMCEPopup.executeOnLoad('init();');"style="display: none">9 <body id="about" style="display: none"> 10 10 <div class="tabs"> 11 11 <ul> 12 <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{ $lang_about}</a></span></li>13 <li id="help_tab" ><span><a href="javascript:mcTabs.displayTab('help_tab','help_panel');" onmousedown="return false;">{$lang_help}</a></span></li>14 <li id="plugins_tab"><span><a href="javascript:mcTabs.displayTab('plugins_tab','plugins_panel');" onmousedown="return false;">{ $lang_plugins}</a></span></li>12 <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advanced_dlg.about_general}</a></span></li> 13 <li id="help_tab" style="display:none"><span><a href="javascript:mcTabs.displayTab('help_tab','help_panel');" onmousedown="return false;">{#advanced_dlg.about_help}</a></span></li> 14 <li id="plugins_tab"><span><a href="javascript:mcTabs.displayTab('plugins_tab','plugins_panel');" onmousedown="return false;">{#advanced_dlg.about_plugins}</a></span></li> 15 15 </ul> 16 16 </div> … … 18 18 <div class="panel_wrapper"> 19 19 <div id="general_panel" class="panel current"> 20 <h3>{ $lang_about_title}</h3>21 <p>Version: {$tinymce_version} ({$tinymce_releasedate})</p>20 <h3>{#advanced_dlg.about_title}</h3> 21 <p>Version: <span id="version"></span> (<span id="date"></span>)</p> 22 22 <p>TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under <a href="../../license.txt" target="_blank">LGPL</a> 23 23 by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.</p> … … 25 25 <p>For more information about this software visit the <a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE website</a>.</p> 26 26 27 <div id="buttoncontainer"></div> 27 <div id="buttoncontainer"> 28 <a href="http://www.moxiecode.com" target="_blank"><img src="http://tinymce.moxiecode.com/images/gotmoxie.png" alt="Got Moxie?" border="0" /></a> 29 <a href="http://sourceforge.net/projects/tinymce/" target="_blank"><img src="http://sourceforge.net/sflogo.php?group_id=103281" alt="Hosted By Sourceforge" border="0" /></a> 30 <a href="http://www.freshmeat.net/projects/tinymce" target="_blank"><img src="http://tinymce.moxiecode.com/images/fm.gif" alt="Also on freshmeat" border="0" /></a> 31 </div> 28 32 </div> 29 33 30 34 <div id="plugins_panel" class="panel"> 31 35 <div id="pluginscontainer"> 32 <h3>{ $lang_loaded_plugins}</h3>36 <h3>{#advanced_dlg.about_loaded}</h3> 33 37 34 38 <div id="plugintablecontainer"> … … 46 50 <div class="mceActionPanel"> 47 51 <div style="float: right"> 48 <input type="button" id="cancel" name="cancel" value="{ $lang_close}" onclick="tinyMCEPopup.close();" />52 <input type="button" id="cancel" name="cancel" value="{#close}" onclick="tinyMCEPopup.close();" /> 49 53 </div> 50 54 </div> -
trunk/wp-includes/js/tinymce/themes/advanced/anchor.htm
r3664 r6632 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 1 2 <html xmlns="http://www.w3.org/1999/xhtml"> 2 3 <head> 3 <title>{ $lang_insert_anchor_title}</title>4 <script language="javascript"type="text/javascript" src="../../tiny_mce_popup.js"></script>5 <script language="javascript" type="text/javascript" src="jscripts/anchor.js"></script>4 <title>{#advanced_dlg.anchor_title}</title> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="js/anchor.js"></script> 6 7 <base target="_self" /> 7 8 </head> 8 <body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none"> 9 <form onsubmit="insertAnchor();return false;" action="#"> 10 9 <body style="display: none"> 10 <form onsubmit="AnchorDialog.update();return false;" action="#"> 11 11 <table border="0" cellpadding="4" cellspacing="0"> 12 12 <tr> 13 <td colspan="2" class="title">{ $lang_insert_anchor_title}</td>13 <td colspan="2" class="title">{#advanced_dlg.anchor_title}</td> 14 14 </tr> 15 15 <tr> 16 <td nowrap="nowrap">{ $lang_insert_anchor_name}:</td>16 <td nowrap="nowrap">{#advanced_dlg.anchor_name}:</td> 17 17 <td><input name="anchorName" type="text" id="anchorName" value="" style="width: 200px" /></td> 18 18 </tr> … … 21 21 <div class="mceActionPanel"> 22 22 <div style="float: left"> 23 <input type="button" id="insert" name="insert" value="{ $lang_update}" onclick="insertAnchor();" />23 <input type="button" id="insert" name="insert" value="{#update}" onclick="AnchorDialog.update();" /> 24 24 </div> 25 25 26 26 <div style="float: right"> 27 <input type="button" id="cancel" name="cancel" value="{ $lang_cancel}" onclick="tinyMCEPopup.close();" />27 <input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" /> 28 28 </div> 29 29 </div> 30 31 30 </form> 32 31 </body> -
trunk/wp-includes/js/tinymce/themes/advanced/charmap.htm
r4506 r6632 1 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 2 <head> 3 <title>{ $lang_theme_charmap_title}</title>3 <title>{#advanced_dlg.charmap_title}</title> 4 4 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> 5 <script language="javascript"type="text/javascript" src="../../tiny_mce_popup.js"></script>6 <script language="javascript" type="text/javascript" src="jscripts/charmap.js"></script>5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="js/charmap.js"></script> 7 7 <base target="_self" /> 8 8 </head> 9 <body onload="tinyMCEPopup.executeOnLoad('init();');"style="display: none">9 <body style="display: none"> 10 10 <table align="center" border="0" cellspacing="0" cellpadding="2"> 11 11 <tr> 12 <td colspan="2" class="title">{ $lang_theme_charmap_title}</td>12 <td colspan="2" class="title">{#advanced_dlg.charmap_title}</td> 13 13 </tr> 14 14 <tr> 15 <td rowspan="2" align="left" valign="top">16 <script language="javascript" type="text/javascript">renderCharMapHTML();</script>15 <td id="charmap" rowspan="2" align="left" valign="top"> 16 <!-- Chars will be rendered here --> 17 17 </td> 18 18 <td width="100" align="center" valign="top"> -
trunk/wp-includes/js/tinymce/themes/advanced/color_picker.htm
r5487 r6632 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 1 2 <html xmlns="http://www.w3.org/1999/xhtml"> 2 3 <head> 3 <title>{$lang_theme_colorpicker_title}</title> 4 <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script> 5 <script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script> 6 <script language="javascript" type="text/javascript" src="jscripts/color_picker.js"></script> 7 <link href="css/colorpicker.css" rel="stylesheet" type="text/css" /> 4 <title>{#advanced_dlg.colorpicker_title}</title> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="../../utils/mctabs.js"></script> 7 <script type="text/javascript" src="js/color_picker.js"></script> 8 8 <base target="_self" /> 9 9 </head> 10 <body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">10 <body id="colorpicker" style="display: none"> 11 11 <div class="tabs"> 12 12 <ul> 13 <li id="picker_tab" class="current"><span><a href="javascript:mcTabs.displayTab('picker_tab','picker_panel');" onmousedown="return false;">{ $lang_color_picker_tab}</a></span></li>14 <li id="rgb_tab"><span><a href=" #" onclick="generateWebColors();mcTabs.displayTab('rgb_tab','rgb_panel');" onmousedown="return false;">{$lang_web_colors_tab}</a></span></li>15 <li id="named_tab"><span><a href=" #" onclick="generateNamedColors();javascript:mcTabs.displayTab('named_tab','named_panel');" onmousedown="return false;">{$lang_named_colors_tab}</a></span></li>13 <li id="picker_tab" class="current"><span><a href="javascript:mcTabs.displayTab('picker_tab','picker_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_picker_tab}</a></span></li> 14 <li id="rgb_tab"><span><a href="javascript:;" onclick="generateWebColors();mcTabs.displayTab('rgb_tab','rgb_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_palette_tab}</a></span></li> 15 <li id="named_tab"><span><a href="javascript:;" onclick="generateNamedColors();javascript:mcTabs.displayTab('named_tab','named_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_named_tab}</a></span></li> 16 16 </ul> 17 17 </div> … … 20 20 <div id="picker_panel" class="panel current"> 21 21 <fieldset> 22 <legend>{ $lang_color_picker}</legend>22 <legend>{#advanced_dlg.colorpicker_picker_title}</legend> 23 23 <div id="picker"> 24 <img id="color picker" src="images/colors.jpg" onclick="computeColor(event)" onmousedown="isMouseDown = true;return false;" onmouseup="isMouseDown = false;" onmousemove="if (isMouseDown && isMouseOver) computeColor(event); return false;" onmouseover="isMouseOver=true;" onmouseout="isMouseOver=false;" />24 <img id="colors" src="img/colorpicker.jpg" onclick="computeColor(event)" onmousedown="isMouseDown = true;return false;" onmouseup="isMouseDown = false;" onmousemove="if (isMouseDown && isMouseOver) computeColor(event); return false;" onmouseover="isMouseOver=true;" onmouseout="isMouseOver=false;" /> 25 25 26 26 <div id="light"> … … 35 35 <div id="rgb_panel" class="panel"> 36 36 <fieldset> 37 <legend>{ $lang_web_colors}</legend>37 <legend>{#advanced_dlg.colorpicker_palette_title}</legend> 38 38 <div id="webcolors"> 39 39 <!-- Gets filled with web safe colors--> … … 46 46 <div id="named_panel" class="panel"> 47 47 <fieldset> 48 <legend>{ $lang_named_colors}</legend>48 <legend>{#advanced_dlg.colorpicker_named_title}</legend> 49 49 <div id="namedcolors"> 50 50 <!-- Gets filled with named colors--> … … 54 54 55 55 <div id="colornamecontainer"> 56 { $lang_color_name} <span id="colorname"></span>56 {#advanced_dlg.colorpicker_name} <span id="colorname"></span> 57 57 </div> 58 58 </fieldset> … … 62 62 <div class="mceActionPanel"> 63 63 <div style="float: left"> 64 <input type="button" id="insert" name="insert" value="{ $lang_theme_colorpicker_apply}" onclick="insertAction();" />64 <input type="button" id="insert" name="insert" value="{#apply}" onclick="insertAction();" /> 65 65 </div> 66 66 … … 68 68 69 69 <div id="previewblock"> 70 <label for="color">{ $lang_color}</label> <input id="color" type="text" size="8" maxlength="8" class="text" />70 <label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" maxlength="8" class="text" /> 71 71 </div> 72 72 </div> -
trunk/wp-includes/js/tinymce/themes/advanced/css/colorpicker.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/themes/advanced/css/editor_content.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/themes/advanced/css/editor_popup.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/themes/advanced/css/editor_ui.css
-
Property
svn:eol-style
set to
native
-
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/themes/advanced/editor_template.js
r5577 r6632 1 1 /** 2 * $Id: editor_template_src.js 256 2007-04-24 09:03:20Z spocke $2 * $Id: editor_template_src.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * @author Moxiecode 5 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 6 6 */ 7 7 8 /* Import theme specific language pack */ 9 tinyMCE.importThemeLanguagePack('advanced'); 10 11 var TinyMCE_AdvancedTheme = { 12 // Private theme fields 13 _defColors : "000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF", 14 _autoImportCSSClasses : true, 15 _resizer : {}, 16 _buttons : [ 17 // Control id, button img, button title, command, user_interface, value 18 ['bold', '{$lang_bold_img}', 'lang_bold_desc', 'Bold'], 19 ['italic', '{$lang_italic_img}', 'lang_italic_desc', 'Italic'], 20 ['underline', '{$lang_underline_img}', 'lang_underline_desc', 'Underline'], 21 ['strikethrough', 'strikethrough.gif', 'lang_striketrough_desc', 'Strikethrough'], 22 ['justifyleft', 'justifyleft.gif', 'lang_justifyleft_desc', 'JustifyLeft'], 23 ['justifycenter', 'justifycenter.gif', 'lang_justifycenter_desc', 'JustifyCenter'], 24 ['justifyright', 'justifyright.gif', 'lang_justifyright_desc', 'JustifyRight'], 25 ['justifyfull', 'justifyfull.gif', 'lang_justifyfull_desc', 'JustifyFull'], 26 ['bullist', 'bullist.gif', 'lang_bullist_desc', 'InsertUnorderedList'], 27 ['numlist', 'numlist.gif', 'lang_numlist_desc', 'InsertOrderedList'], 28 ['outdent', 'outdent.gif', 'lang_outdent_desc', 'Outdent'], 29 ['indent', 'indent.gif', 'lang_indent_desc', 'Indent'], 30 ['cut', 'cut.gif', 'lang_cut_desc', 'Cut'], 31 ['copy', 'copy.gif', 'lang_copy_desc', 'Copy'], 32 ['paste', 'paste.gif', 'lang_paste_desc', 'Paste'], 33 ['undo', 'undo.gif', 'lang_undo_desc', 'Undo'], 34 ['redo', 'redo.gif', 'lang_redo_desc', 'Redo'], 35 ['link', 'link.gif', 'lang_link_desc', 'mceLink', true], 36 ['unlink', 'unlink.gif', 'lang_unlink_desc', 'unlink'], 37 ['image', 'image.gif', 'lang_image_desc', 'mceImage', true], 38 ['cleanup', 'cleanup.gif', 'lang_cleanup_desc', 'mceCleanup'], 39 ['help', 'help.gif', 'lang_help_desc', 'mceHelp'], 40 ['code', 'code.gif', 'lang_theme_code_desc', 'mceCodeEditor'], 41 ['hr', 'hr.gif', 'lang_theme_hr_desc', 'inserthorizontalrule'], 42 ['removeformat', 'removeformat.gif', 'lang_theme_removeformat_desc', 'removeformat'], 43 ['sub', 'sub.gif', 'lang_theme_sub_desc', 'subscript'], 44 ['sup', 'sup.gif', 'lang_theme_sup_desc', 'superscript'], 45 ['forecolor', 'forecolor.gif', 'lang_theme_forecolor_desc', 'forecolor', true], 46 ['forecolorpicker', 'forecolor.gif', 'lang_theme_forecolor_desc', 'forecolorpicker', true], 47 ['backcolor', 'backcolor.gif', 'lang_theme_backcolor_desc', 'HiliteColor', true], 48 ['backcolorpicker', 'backcolor.gif', 'lang_theme_backcolor_desc', 'backcolorpicker', true], 49 ['charmap', 'charmap.gif', 'lang_theme_charmap_desc', 'mceCharMap'], 50 ['visualaid', 'visualaid.gif', 'lang_theme_visualaid_desc', 'mceToggleVisualAid'], 51 ['anchor', 'anchor.gif', 'lang_theme_anchor_desc', 'mceInsertAnchor'], 52 ['newdocument', 'newdocument.gif', 'lang_newdocument_desc', 'mceNewDocument'] 53 ], 54 55 _buttonMap : 'anchor,backcolor,bold,bullist,charmap,cleanup,code,copy,cut,forecolor,help,hr,image,indent,italic,justifycenter,justifyfull,justifyleft,justifyright,link,newdocument,numlist,outdent,paste,redo,removeformat,strikethrough,sub,sup,underline,undo,unlink,visualaid,advhr,ltr,rtl,emotions,flash,fullpage,fullscreen,iespell,insertdate,inserttime,pastetext,pasteword,selectall,preview,print,save,replace,search,table,cell_props,delete_col,delete_row,col_after,col_before,row_after,row_before,merge_cells,row_props,split_cells,delete_table', 56 57 /** 58 * Returns HTML code for the specificed control. 59 */ 60 getControlHTML : function(button_name) { 61 var i, x, but; 62 63 // Lookup button in button list 64 for (i=0; i<TinyMCE_AdvancedTheme._buttons.length; i++) { 65 but = TinyMCE_AdvancedTheme._buttons[i]; 66 67 if (but[0] == button_name && (button_name == "forecolor" || button_name == "backcolor")) 68 return tinyMCE.getMenuButtonHTML(but[0], but[2], '{$themeurl}/images/' + but[1], but[3] + "Menu", but[3], (but.length > 4 ? but[4] : false), (but.length > 5 ? but[5] : null)); 69 70 if (but[0] == button_name) 71 return tinyMCE.getButtonHTML(but[0], but[2], '{$themeurl}/images/' + but[1], but[3], (but.length > 4 ? but[4] : false), (but.length > 5 ? but[5] : null)); 72 } 73 74 // Custom controlls other than buttons 75 switch (button_name) { 76 case "formatselect": 77 var html = '<select id="{$editor_id}_formatSelect" name="{$editor_id}_formatSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FormatBlock\',false,this.options[this.selectedIndex].value);" class="mceSelectList">'; 78 var formats = tinyMCE.getParam("theme_advanced_blockformats", "p,address,pre,h1,h2,h3,h4,h5,h6", true).split(','); 79 var lookup = [ 80 ['p', '{$lang_theme_paragraph}'], 81 ['address', '{$lang_theme_address}'], 82 ['pre', '{$lang_theme_pre}'], 83 ['h1', '{$lang_theme_h1}'], 84 ['h2', '{$lang_theme_h2}'], 85 ['h3', '{$lang_theme_h3}'], 86 ['h4', '{$lang_theme_h4}'], 87 ['h5', '{$lang_theme_h5}'], 88 ['h6', '{$lang_theme_h6}'], 89 ['div', '{$lang_theme_div}'], 90 ['blockquote', '{$lang_theme_blockquote}'], 91 ['code', '{$lang_theme_code}'], 92 ['dt', '{$lang_theme_dt}'], 93 ['dd', '{$lang_theme_dd}'], 94 ['samp', '{$lang_theme_samp}'] 95 ]; 96 97 html += '<option value="">{$lang_theme_block}</option>'; 98 99 // Build format select 100 for (var i=0; i<formats.length; i++) { 101 for (var x=0; x<lookup.length; x++) { 102 if (formats[i] == lookup[x][0]) 103 html += '<option value="<' + lookup[x][0] + '>">' + lookup[x][1] + '</option>'; 8 (function() { 9 var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID; 10 11 // Tell it to load theme specific language pack(s) 12 tinymce.ThemeManager.requireLangPack('advanced'); 13 14 tinymce.create('tinymce.themes.AdvancedTheme', { 15 // Control name lookup, format: title, command 16 controls : { 17 bold : ['bold_desc', 'Bold'], 18 italic : ['italic_desc', 'Italic'], 19 underline : ['underline_desc', 'Underline'], 20 strikethrough : ['striketrough_desc', 'Strikethrough'], 21 justifyleft : ['justifyleft_desc', 'JustifyLeft'], 22 justifycenter : ['justifycenter_desc', 'JustifyCenter'], 23 justifyright : ['justifyright_desc', 'JustifyRight'], 24 justifyfull : ['justifyfull_desc', 'JustifyFull'], 25 bullist : ['bullist_desc', 'InsertUnorderedList'], 26 numlist : ['numlist_desc', 'InsertOrderedList'], 27 outdent : ['outdent_desc', 'Outdent'], 28 indent : ['indent_desc', 'Indent'], 29 cut : ['cut_desc', 'Cut'], 30 copy : ['copy_desc', 'Copy'], 31 paste : ['paste_desc', 'Paste'], 32 undo : ['undo_desc', 'Undo'], 33 redo : ['redo_desc', 'Redo'], 34 link : ['link_desc', 'mceLink'], 35 unlink : ['unlink_desc', 'unlink'], 36 image : ['image_desc', 'mceImage'], 37 cleanup : ['cleanup_desc', 'mceCleanup'], 38 help : ['help_desc', 'mceHelp'], 39 code : ['code_desc', 'mceCodeEditor'], 40 hr : ['hr_desc', 'InsertHorizontalRule'], 41 removeformat : ['removeformat_desc', 'RemoveFormat'], 42 sub : ['sub_desc', 'subscript'], 43 sup : ['sup_desc', 'superscript'], 44 forecolor : ['forecolor_desc', 'ForeColor'], 45 forecolorpicker : ['forecolor_desc', 'mceForeColor'], 46 backcolor : ['backcolor_desc', 'HiliteColor'], 47 backcolorpicker : ['backcolor_desc', 'mceBackColor'], 48 charmap : ['charmap_desc', 'mceCharMap'], 49 visualaid : ['visualaid_desc', 'mceToggleVisualAid'], 50 anchor : ['anchor_desc', 'mceInsertAnchor'], 51 newdocument : ['newdocument_desc', 'mceNewDocument'], 52 blockquote : ['blockquote_desc', 'mceBlockQuote'] 53 }, 54 55 stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'], 56 57 init : function(ed, url) { 58 var t = this, s; 59 60 t.editor = ed; 61 t.url = url; 62 t.onResolveName = new tinymce.util.Dispatcher(this); 63 64 // Default settings 65 t.settings = s = extend({ 66 theme_advanced_path : true, 67 theme_advanced_toolbar_location : 'bottom', 68 theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect", 69 theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code", 70 theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap", 71 theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6", 72 theme_advanced_toolbar_align : "center", 73 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", 74 theme_advanced_font_sizes : "1,2,3,4,5,6,7", 75 theme_advanced_more_colors : 1, 76 theme_advanced_row_height : 23, 77 theme_advanced_resize_horizontal : 1, 78 theme_advanced_resizing_use_cookie : 1 79 }, ed.settings); 80 81 if (s.theme_advanced_statusbar_location == 'none') 82 s.theme_advanced_statusbar_location = 0; 83 84 // Init editor 85 ed.onInit.add(function() { 86 ed.onNodeChange.add(t._nodeChanged, t); 87 ed.dom.loadCSS(ed.baseURI.toAbsolute("themes/advanced/skins/" + ed.settings.skin + "/content.css")); 88 }); 89 90 ed.onSetProgressState.add(function(ed, b, ti) { 91 var co, id = ed.id, tb; 92 93 if (b) { 94 t.progressTimer = setTimeout(function() { 95 co = ed.getContainer(); 96 co = co.insertBefore(DOM.create('DIV', {style : 'position:relative'}), co.firstChild); 97 tb = DOM.get(ed.id + '_tbl'); 98 99 DOM.add(co, 'div', {id : id + '_blocker', 'class' : 'mceBlocker', style : {width : tb.clientWidth + 2, height : tb.clientHeight + 2}}); 100 DOM.add(co, 'div', {id : id + '_progress', 'class' : 'mceProgress', style : {left : tb.clientWidth / 2, top : tb.clientHeight / 2}}); 101 }, ti || 0); 102 } else { 103 DOM.remove(id + '_blocker'); 104 DOM.remove(id + '_progress'); 105 clearTimeout(t.progressTimer); 106 } 107 }); 108 109 DOM.loadCSS(ed.baseURI.toAbsolute(s.editor_css || "themes/advanced/skins/" + ed.settings.skin + "/ui.css")); 110 }, 111 112 createControl : function(n, cf) { 113 var cd, c; 114 115 if (c = cf.createControl(n)) 116 return c; 117 118 switch (n) { 119 case "styleselect": 120 return this._createStyleSelect(); 121 122 case "formatselect": 123 return this._createBlockFormats(); 124 125 case "fontselect": 126 return this._createFontSelect(); 127 128 case "fontsizeselect": 129 return this._createFontSizeSelect(); 130 131 case "forecolor": 132 return this._createForeColorMenu(); 133 134 case "backcolor": 135 return this._createBackColorMenu(); 136 } 137 138 if ((cd = this.controls[n])) 139 return cf.createButton(n, {title : "advanced." + cd[0], cmd : cd[1], ui : cd[2], value : cd[3]}); 140 }, 141 142 execCommand : function(cmd, ui, val) { 143 var f = this['_' + cmd]; 144 145 if (f) { 146 f.call(this, ui, val); 147 return true; 148 } 149 150 return false; 151 }, 152 153 _importClasses : function() { 154 var ed = this.editor, c = ed.controlManager.get('styleselect'); 155 156 if (c.getLength() == 0) { 157 each(ed.dom.getClasses(), function(o) { 158 c.add(o['class'], o['class']); 159 }); 160 } 161 }, 162 163 _createStyleSelect : function(n) { 164 var t = this, ed = t.editor, cf = ed.controlManager, c = cf.createListBox('styleselect', { 165 title : 'advanced.style_select', 166 onselect : function(v) { 167 if (c.selectedValue === v) { 168 ed.execCommand('mceSetStyleInfo', 0, {command : 'removeformat'}); 169 c.select(); 170 return false; 171 } else 172 ed.execCommand('mceSetCSSClass', 0, v); 173 } 174 }); 175 176 each((t.settings.theme_advanced_styles || '').split(';'), function(v) { 177 var p = v.split('='); 178 179 if (v) 180 c.add(t.editor.translate(p[0]), p[1]); 181 }); 182 183 c.onPostRender.add(function(ed, n) { 184 Event.add(n, 'focus', t._importClasses, t); 185 Event.add(n, 'mousedown', t._importClasses, t); 186 }); 187 188 return c; 189 }, 190 191 _createFontSelect : function() { 192 var c, t = this; 193 194 c = t.editor.controlManager.createListBox('fontselect', {title : 'advanced.fontdefault', cmd : 'FontName'}); 195 196 each(t.settings.theme_advanced_fonts.split(';'), function(v) { 197 var p = v.split('='), st; 198 199 if (p[1].indexOf('dings') == -1) 200 st = 'font-family:' + p[1]; 201 202 c.add(t.editor.translate(p[0]), p[1], {style : st}); 203 }); 204 205 return c; 206 }, 207 208 _createFontSizeSelect : function() { 209 var c, t = this, lo = [ 210 "1 (8 pt)", 211 "2 (10 pt)", 212 "3 (12 pt)", 213 "4 (14 pt)", 214 "5 (18 pt)", 215 "6 (24 pt)", 216 "7 (36 pt)" 217 ], fz = [8, 10, 12, 14, 18, 24, 36]; 218 219 c = t.editor.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', cmd : 'FontSize'}); 220 221 each(t.settings.theme_advanced_font_sizes.split(','), function(v) { 222 c.add(lo[parseInt(v) - 1], v, {'style' : 'font-size:' + fz[v - 1] + 'pt', 'class' : 'fontSize' + v}); 223 }); 224 225 return c; 226 }, 227 228 _createBlockFormats : function() { 229 var c, fmts = { 230 p : 'advanced.paragraph', 231 address : 'advanced.address', 232 pre : 'advanced.pre', 233 h1 : 'advanced.h1', 234 h2 : 'advanced.h2', 235 h3 : 'advanced.h3', 236 h4 : 'advanced.h4', 237 h5 : 'advanced.h5', 238 h6 : 'advanced.h6', 239 div : 'advanced.div', 240 blockquote : 'advanced.blockquote', 241 code : 'advanced.code', 242 dt : 'advanced.dt', 243 dd : 'advanced.dd', 244 samp : 'advanced.samp' 245 }, t = this; 246 247 c = t.editor.controlManager.createListBox('formatselect', {title : 'advanced.block', cmd : 'FormatBlock'}); 248 249 each(t.settings.theme_advanced_blockformats.split(','), function(v) { 250 c.add(t.editor.translate(fmts[v]), v, {element : v, 'class' : v.indexOf('h') == 0 ? '' : 'preview'}); 251 }); 252 253 return c; 254 }, 255 256 _createForeColorMenu : function() { 257 var c, t = this, s = t.settings, o = {}, v; 258 259 if (s.theme_advanced_more_colors) { 260 o.more_colors_func = function() { 261 t._mceColorPicker(0, { 262 color : c.value, 263 func : function(co) { 264 c.setColor(co); 265 } 266 }); 267 }; 268 } 269 270 if (v = s.theme_advanced_text_colors) 271 o.colors = v; 272 273 o.title = 'advanced.forecolor_desc'; 274 o.cmd = 'ForeColor'; 275 o.scope = this; 276 277 c = t.editor.controlManager.createColorSplitButton('forecolor', o); 278 279 return c; 280 }, 281 282 _createBackColorMenu : function() { 283 var c, t = this, s = t.settings, o = {}, v; 284 285 if (s.theme_advanced_more_colors) { 286 o.more_colors_func = function() { 287 t._mceColorPicker(0, { 288 color : c.value, 289 func : function(co) { 290 c.setColor(co); 291 } 292 }); 293 }; 294 } 295 296 if (v = s.theme_advanced_background_colors) 297 o.colors = v; 298 299 o.title = 'advanced.backcolor_desc'; 300 o.cmd = 'HiliteColor'; 301 o.scope = this; 302 303 c = t.editor.controlManager.createColorSplitButton('backcolor', o); 304 305 return c; 306 }, 307 308 renderUI : function(o) { 309 var n, ic, tb, t = this, ed = t.editor, s = t.settings, sc, p, nl; 310 311 n = p = DOM.create('div', {id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin'}); 312 313 if (!DOM.boxModel) 314 n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'}); 315 316 n = sc = DOM.add(n, 'table', {id : ed.id + '_tbl', 'class' : 'mceLayout', cellSpacing : 0, cellPadding : 0}); 317 n = tb = DOM.add(n, 'tbody'); 318 319 switch ((s.theme_advanced_layout_manager || '').toLowerCase()) { 320 case "rowlayout": 321 ic = t._rowLayout(s, tb, o); 322 break; 323 324 case "customlayout": 325 ic = ed.execCallback("theme_advanced_custom_layout", s, tb, o, p); 326 break; 327 328 default: 329 ic = t._simpleLayout(s, tb, o, p); 330 } 331 332 n = o.targetNode; 333 334 // Add classes to first and last TRs 335 nl = sc.rows; 336 DOM.addClass(nl[0], 'first'); 337 DOM.addClass(nl[nl.length - 1], 'last'); 338 339 // Add classes to first and last TDs 340 each(DOM.select('tr', tb), function(n) { 341 DOM.addClass(n.firstChild, 'first'); 342 DOM.addClass(n.childNodes[n.childNodes.length - 1], 'last'); 343 }); 344 345 if (DOM.get(s.theme_advanced_toolbar_container)) 346 DOM.get(s.theme_advanced_toolbar_container).appendChild(p); 347 else 348 DOM.insertAfter(p, n); 349 350 Event.add(ed.id + '_path_row', 'click', function(e) { 351 e = e.target; 352 353 if (e.nodeName == 'A') { 354 t._sel(e.href.replace(/^[^#]*#/, '')); 355 356 return Event.cancel(e); 357 } 358 }); 359 /* 360 if (DOM.get(ed.id + '_path_row')) { 361 Event.add(ed.id + '_tbl', 'mouseover', function(e) { 362 var re; 363 364 e = e.target; 365 366 if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) { 367 re = DOM.get(ed.id + '_path_row'); 368 t.lastPath = re.innerHTML; 369 DOM.setHTML(re, e.parentNode.title); 104 370 } 371 }); 372 373 Event.add(ed.id + '_tbl', 'mouseout', function(e) { 374 if (t.lastPath) { 375 DOM.setHTML(ed.id + '_path_row', t.lastPath); 376 t.lastPath = 0; 377 } 378 }); 379 } 380 */ 381 if (s.theme_advanced_toolbar_location == 'external') 382 o.deltaHeight = 0; 383 384 t.deltaHeight = o.deltaHeight; 385 o.targetNode = null; 386 387 return { 388 iframeContainer : ic, 389 editorContainer : ed.id + '_parent', 390 sizeContainer : sc, 391 deltaHeight : o.deltaHeight 392 }; 393 }, 394 395 getInfo : function() { 396 return { 397 longname : 'Simple theme', 398 author : 'Moxiecode Systems AB', 399 authorurl : 'http://tinymce.moxiecode.com', 400 version : tinymce.majorVersion + "." + tinymce.minorVersion 401 } 402 }, 403 404 _simpleLayout : function(s, tb, o, p) { 405 var t = this, ed = t.editor, lo = s.theme_advanced_toolbar_location, sl = s.theme_advanced_statusbar_location, n, ic, etb, c; 406 407 // Create toolbar container at top 408 if (lo == 'top') 409 t._addToolbars(tb, o); 410 411 // Create external toolbar 412 if (lo == 'external') { 413 n = c = DOM.create('div', {style : 'position:relative'}); 414 n = DOM.add(n, 'div', {id : ed.id + '_external', 'class' : 'mceExternalToolbar'}); 415 DOM.add(n, 'a', {id : ed.id + '_external_close', href : 'javascript:;', 'class' : 'mceExternalClose'}); 416 n = DOM.add(n, 'table', {id : ed.id + '_tblext', cellSpacing : 0, cellPadding : 0}); 417 etb = DOM.add(n, 'tbody'); 418 419 if (p.firstChild.className == 'mceOldBoxModel') 420 p.firstChild.appendChild(c); 421 else 422 p.insertBefore(c, p.firstChild); 423 424 t._addToolbars(etb, o); 425 426 ed.onMouseUp.add(function() { 427 var e = DOM.get(ed.id + '_external'); 428 DOM.show(e); 429 430 DOM.hide(lastExtID); 431 432 var f = Event.add(ed.id + '_external_close', 'click', function() { 433 DOM.hide(ed.id + '_external'); 434 Event.remove(ed.id + '_external_close', 'click', f); 435 }); 436 437 DOM.show(e); 438 DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1); 439 440 // Fixes IE rendering bug 441 DOM.hide(e); 442 DOM.show(e); 443 e.style.filter = ''; 444 445 lastExtID = ed.id + '_external'; 446 447 e = null; 448 }); 449 } 450 451 if (sl == 'top') 452 t._addStatusBar(tb, o); 453 454 // Create iframe container 455 if (!s.theme_advanced_toolbar_container) { 456 n = DOM.add(tb, 'tr'); 457 n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); 458 } 459 460 // Create toolbar container at bottom 461 if (lo == 'bottom') 462 t._addToolbars(tb, o); 463 464 if (sl == 'bottom') 465 t._addStatusBar(tb, o); 466 467 return ic; 468 }, 469 470 _rowLayout : function(s, tb, o) { 471 var t = this, ed = t.editor, dc, da, cf = ed.controlManager, n, ic, to; 472 473 dc = s.theme_advanced_containers_default_class || ''; 474 da = s.theme_advanced_containers_default_align || 'center'; 475 476 each((s.theme_advanced_containers || '').split(','), function(c, i) { 477 var v = s['theme_advanced_container_' + c].toLowerCase(); 478 479 switch (v) { 480 case 'mceeditor': 481 n = DOM.add(tb, 'tr'); 482 n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); 483 break; 484 485 case 'mceelementpath': 486 t._addStatusBar(tb, o); 487 break; 488 489 default: 490 n = DOM.add(DOM.add(tb, 'tr'), 'td', { 491 'class' : 'mceToolbar ' + (s['theme_advanced_container_' + c + '_class'] || dc), 492 align : s['theme_advanced_container_' + c + '_align'] || da 493 }); 494 495 to = cf.createToolbar("toolbar" + i); 496 t._addControls(v, to); 497 DOM.setHTML(n, to.renderHTML()); 498 o.deltaHeight -= s.theme_advanced_row_height; 105 499 } 106 107 html += '</select>'; 108 109 return html; 110 111 case "styleselect": 112 return '<select id="{$editor_id}_styleSelect" onmousedown="tinyMCE.themes.advanced._setupCSSClasses(\'{$editor_id}\');" name="{$editor_id}_styleSelect" onfocus="tinyMCE.addSelectAccessibility(event,this,window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceSetCSSClass\',false,this.options[this.selectedIndex].value);" class="mceSelectList">{$style_select_options}</select>'; 113 114 case "fontselect": 115 var fontHTML = '<select id="{$editor_id}_fontNameSelect" name="{$editor_id}_fontNameSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontName\',false,this.options[this.selectedIndex].value);" class="mceSelectList"><option value="">{$lang_theme_fontdefault}</option>'; 116 var iFonts = 'Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,times new roman,times,serif;Tahoma=tahoma,arial,helvetica,sans-serif;Times New Roman=times new roman,times,serif;Verdana=verdana,arial,helvetica,sans-serif;Impact=impact;WingDings=wingdings'; 117 var nFonts = '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,sand;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'; 118 var fonts = tinyMCE.getParam("theme_advanced_fonts", nFonts).split(';'); 119 for (i=0; i<fonts.length; i++) { 120 if (fonts[i] != '') { 121 var parts = fonts[i].split('='); 122 fontHTML += '<option value="' + parts[1] + '">' + parts[0] + '</option>'; 500 }); 501 502 return ic; 503 }, 504 505 _addControls : function(v, tb) { 506 var t = this, s = t.settings, di, cf = t.editor.controlManager; 507 508 if (s.theme_advanced_disable && !t._disabled) { 509 di = {}; 510 511 each(s.theme_advanced_disable.split(','), function(v) { 512 di[v] = 1; 513 }); 514 515 t._disabled = di; 516 } else 517 di = t._disabled; 518 519 each(v.split(','), function(n) { 520 var c; 521 522 if (di && di[n]) 523 return; 524 525 // Compatiblity with 2.x 526 if (n == 'tablecontrols') { 527 each(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"], function(n) { 528 n = t.createControl(n, cf); 529 530 if (n) 531 tb.add(n); 532 }); 533 534 return; 535 } 536 537 c = t.createControl(n, cf); 538 539 if (c) 540 tb.add(c); 541 }); 542 }, 543 544 _addToolbars : function(c, o) { 545 var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = []; 546 547 n = DOM.add(DOM.add(c, 'tr'), 'td', {'class' : 'mceToolbar', align : s.theme_advanced_toolbar_align}); 548 549 if (!ed.getParam('accessibility_focus') || ed.getParam('tab_focus')) 550 h.push(DOM.createHTML('a', {href : '#', onfocus : 'tinyMCE.get(\'' + ed.id + '\').focus();'}, '<!-- IE -->')); 551 552 h.push(DOM.createHTML('a', {href : '#', accesskey : 'q', title : ed.getLang("advanced.toolbar_focus")}, '<!-- IE -->')); 553 554 // Create toolbar and add the controls 555 for (i=1; (v = s['theme_advanced_buttons' + i]); i++) { 556 tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i}); 557 558 if (s['theme_advanced_buttons' + i + '_add']) 559 v += ',' + s['theme_advanced_buttons' + i + '_add']; 560 561 if (s['theme_advanced_buttons' + i + '_add_before']) 562 v = s['theme_advanced_buttons' + i + '_add_before'] + ',' + v; 563 564 t._addControls(v, tb, di); 565 566 //n.appendChild(n = tb.render()); 567 h.push(tb.renderHTML()); 568 569 o.deltaHeight -= s.theme_advanced_row_height; 570 } 571 572 h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->')); 573 DOM.setHTML(n, h.join('')); 574 }, 575 576 _addStatusBar : function(tb, o) { 577 var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td; 578 579 n = DOM.add(tb, 'tr'); 580 n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'}); 581 n = DOM.add(n, 'div', {id : ed.id + '_path_row'}, s.theme_advanced_path ? ed.translate('advanced.path') + ': ' : ' '); 582 DOM.add(n, 'a', {href : '#', accesskey : 'x'}); 583 584 if (s.theme_advanced_resizing && !tinymce.isOldWebKit) { 585 DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'resize'}); 586 587 if (s.theme_advanced_resizing_use_cookie) { 588 ed.onPostRender.add(function() { 589 var o = Cookie.getHash("TinyMCE_" + ed.id + "_size"), c = DOM.get(ed.id + '_tbl'); 590 591 if (!o) 592 return; 593 594 if (s.theme_advanced_resize_horizontal) 595 c.style.width = o.cw + 'px'; 596 597 c.style.height = o.ch + 'px'; 598 DOM.get(ed.id + '_ifr').style.height = (parseInt(o.ch) + t.deltaHeight) + 'px'; 599 }); 600 } 601 602 ed.onPostRender.add(function() { 603 Event.add(ed.id + '_resize', 'mousedown', function(e) { 604 var c, p, w, h, n, pa; 605 606 // Measure container 607 c = DOM.get(ed.id + '_tbl'); 608 w = c.clientWidth; 609 h = c.clientHeight; 610 611 miw = s.theme_advanced_resizing_min_width || 100; 612 mih = s.theme_advanced_resizing_min_height || 100; 613 maw = s.theme_advanced_resizing_max_width || 0xFFFF; 614 mah = s.theme_advanced_resizing_max_height || 0xFFFF; 615 616 // Setup placeholder 617 p = DOM.add(DOM.get(ed.id + '_parent'), 'div', {'class' : 'mcePlaceHolder'}); 618 DOM.setStyles(p, {width : w, height : h}); 619 620 // Replace with placeholder 621 DOM.hide(c); 622 DOM.show(p); 623 624 // Create internal resize obj 625 r = { 626 x : e.screenX, 627 y : e.screenY, 628 w : w, 629 h : h, 630 dx : null, 631 dy : null 632 }; 633 634 // Start listening 635 mf = Event.add(document, 'mousemove', function(e) { 636 var w, h; 637 638 // Calc delta values 639 r.dx = e.screenX - r.x; 640 r.dy = e.screenY - r.y; 641 642 // Boundery fix box 643 w = Math.max(miw, r.w + r.dx); 644 h = Math.max(mih, r.h + r.dy); 645 w = Math.min(maw, w); 646 h = Math.min(mah, h); 647 648 // Resize placeholder 649 if (s.theme_advanced_resize_horizontal) 650 p.style.width = w + 'px'; 651 652 p.style.height = h + 'px'; 653 654 return Event.cancel(e); 655 }); 656 657 me = Event.add(document, 'mouseup', function(e) { 658 var ifr; 659 660 // Stop listening 661 Event.remove(document, 'mousemove', mf); 662 Event.remove(document, 'mouseup', me); 663 664 c.style.display = ''; 665 DOM.remove(p); 666 667 if (r.dx === null) 668 return; 669 670 ifr = DOM.get(ed.id + '_ifr'); 671 672 if (s.theme_advanced_resize_horizontal) 673 c.style.width = (r.w + r.dx) + 'px'; 674 675 c.style.height = (r.h + r.dy) + 'px'; 676 ifr.style.height = (ifr.clientHeight + r.dy) + 'px'; 677 678 if (s.theme_advanced_resizing_use_cookie) { 679 Cookie.setHash("TinyMCE_" + ed.id + "_size", { 680 cw : r.w + r.dx, 681 ch : r.h + r.dy 682 }); 683 } 684 }); 685 686 return Event.cancel(e); 687 }); 688 }); 689 } 690 691 o.deltaHeight -= 21; 692 n = tb = null; 693 }, 694 695 _nodeChanged : function(ed, cm, n, co) { 696 var t = this, p, de = 0, v, c, s = t.settings; 697 698 tinymce.each(t.stateControls, function(c) { 699 cm.setActive(c, ed.queryCommandState(t.controls[c][1])); 700 }); 701 702 cm.setActive('visualaid', ed.hasVisual); 703 cm.setDisabled('undo', !ed.undoManager.hasUndo() && !ed.typing); 704 cm.setDisabled('redo', !ed.undoManager.hasRedo()); 705 cm.setDisabled('outdent', !ed.queryCommandState('Outdent')); 706 707 p = DOM.getParent(n, 'A'); 708 if (c = cm.get('link')) { 709 if (!p || !p.name) { 710 c.setDisabled(!p && co); 711 c.setActive(!!p); 712 } 713 } 714 715 if (c = cm.get('unlink')) { 716 c.setDisabled(!p && co); 717 c.setActive(!!p && !p.name); 718 } 719 720 if (c = cm.get('anchor')) { 721 c.setActive(!!p && p.name); 722 723 if (tinymce.isWebKit) { 724 p = DOM.getParent(n, 'IMG'); 725 c.setActive(!!p && DOM.getAttrib(p, 'mce_name') == 'a'); 726 } 727 } 728 729 p = DOM.getParent(n, 'IMG'); 730 if (c = cm.get('image')) 731 c.setActive(!!p && n.className.indexOf('mceItem') == -1); 732 733 if (c = cm.get('styleselect')) { 734 if (n.className) { 735 t._importClasses(); 736 c.select(n.className); 737 } else 738 c.select(); 739 } 740 741 if (c = cm.get('formatselect')) { 742 p = DOM.getParent(n, DOM.isBlock); 743 744 if (p) 745 c.select(p.nodeName.toLowerCase()); 746 } 747 748 if (c = cm.get('fontselect')) 749 c.select(ed.queryCommandValue('FontName')); 750 751 if (c = cm.get('fontsizeselect')) 752 c.select(ed.queryCommandValue('FontSize')); 753 754 if (s.theme_advanced_path && s.theme_advanced_statusbar_location) { 755 p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'}); 756 DOM.setHTML(p, ''); 757 758 ed.dom.getParent(n, function(n) { 759 var na = n.nodeName.toLowerCase(), u, pi, ti = ''; 760 761 // Ignore non element and hidden elements 762 if (n.nodeType != 1 || (DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved'))) 763 return; 764 765 // Fake name 766 if (v = DOM.getAttrib(n, 'mce_name')) 767 na = v; 768 769 // Handle prefix 770 if (tinymce.isIE && n.scopeName !== 'HTML') 771 na = n.scopeName + ':' + na; 772 773 // Remove internal prefix 774 na = na.replace(/mce\:/g, ''); 775 776 // Handle node name 777 switch (na) { 778 case 'b': 779 na = 'strong'; 780 break; 781 782 case 'i': 783 na = 'em'; 784 break; 785 786 case 'img': 787 if (v = DOM.getAttrib(n, 'src')) 788 ti += 'src: ' + v + ' '; 789 790 break; 791 792 case 'a': 793 if (v = DOM.getAttrib(n, 'name')) { 794 ti += 'name: ' + v + ' '; 795 na += '#' + v; 796 } 797 798 if (v = DOM.getAttrib(n, 'href')) 799 ti += 'href: ' + v + ' '; 800 801 break; 802 803 case 'font': 804 if (s.convert_fonts_to_spans) 805 na = 'span'; 806 807 if (v = DOM.getAttrib(n, 'face')) 808 ti += 'font: ' + v + ' '; 809 810 if (v = DOM.getAttrib(n, 'size')) 811 ti += 'size: ' + v + ' '; 812 813 if (v = DOM.getAttrib(n, 'color')) 814 ti += 'color: ' + v + ' '; 815 816 break; 817 818 case 'span': 819 if (v = DOM.getAttrib(n, 'style')) 820 ti += 'style: ' + v + ' '; 821 822 break; 123 823 } 124 } 125 126 fontHTML += '</select>'; 127 return fontHTML; 128 129 case "fontsizeselect": 130 return '<select id="{$editor_id}_fontSizeSelect" name="{$editor_id}_fontSizeSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontSize\',false,this.options[this.selectedIndex].value);" class="mceSelectList">'+ 131 '<option value="0">{$lang_theme_font_size}</option>'+ 132 '<option value="1">1 (8 pt)</option>'+ 133 '<option value="2">2 (10 pt)</option>'+ 134 '<option value="3">3 (12 pt)</option>'+ 135 '<option value="4">4 (14 pt)</option>'+ 136 '<option value="5">5 (18 pt)</option>'+ 137 '<option value="6">6 (24 pt)</option>'+ 138 '<option value="7">7 (36 pt)</option>'+ 139 '</select>'; 140 141 case "|": 142 case "separator": 143 return '<img src="{$themeurl}/images/separator.gif" width="2" height="20" class="mceSeparatorLine" alt="" />'; 144 145 case "spacer": 146 return '<img src="{$themeurl}/images/separator.gif" width="2" height="15" border="0" class="mceSeparatorLine" style="vertical-align: middle" alt="" />'; 147 148 case "rowseparator": 149 return '<br />'; 150 } 151 152 return ""; 153 }, 154 155 /** 156 * Theme specific execcommand handling. 157 */ 158 execCommand : function(editor_id, element, command, user_interface, value) { 159 switch (command) { 160 case 'mceHelp': 161 tinyMCE.openWindow({ 162 file : 'about.htm', 163 width : 480, 164 height : 380 165 }, { 166 tinymce_version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion, 167 tinymce_releasedate : tinyMCE.releaseDate, 168 inline : "yes" 169 }); 170 return true; 171 172 case "mceLink": 173 var inst = tinyMCE.getInstanceById(editor_id); 174 var doc = inst.getDoc(); 175 var selectedText = ""; 176 177 if (tinyMCE.isMSIE) { 178 var rng = doc.selection.createRange(); 179 selectedText = rng.text; 180 } else 181 selectedText = inst.getSel().toString(); 182 183 if (!tinyMCE.linkElement) { 184 if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0)) 185 return true; 186 } 187 188 var href = "", target = "", title = "", onclick = "", action = "insert", style_class = ""; 189 190 if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a") 191 tinyMCE.linkElement = tinyMCE.selectedElement; 192 193 // Is anchor not a link 194 if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "") 195 tinyMCE.linkElement = null; 196 197 if (tinyMCE.linkElement) { 198 href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href'); 199 target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target'); 200 title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title'); 201 onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick'); 202 style_class = tinyMCE.getAttrib(tinyMCE.linkElement, 'class'); 203 204 // Try old onclick to if copy/pasted content 205 if (onclick == "") 206 onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick'); 207 208 onclick = tinyMCE.cleanupEventStr(onclick); 209 210 href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);"); 211 212 // Use mce_href if defined 213 mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_href'); 214 if (mceRealHref != "") { 215 href = mceRealHref; 216 217 if (tinyMCE.getParam('convert_urls')) 218 href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);"); 219 } 220 221 action = "update"; 222 } 223 224 var template = new Array(); 225 226 template['file'] = 'link.htm'; 227 template['width'] = 310; 228 template['height'] = 200; 229 230 // Language specific width and height addons 231 template['width'] += tinyMCE.getLang('lang_insert_link_delta_width', 0); 232 template['height'] += tinyMCE.getLang('lang_insert_link_delta_height', 0); 233 234 if (inst.settings['insertlink_callback']) { 235 var returnVal = eval(inst.settings['insertlink_callback'] + "(href, target, title, onclick, action, style_class);"); 236 if (returnVal && returnVal['href']) 237 TinyMCE_AdvancedTheme._insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']); 238 } else { 239 tinyMCE.openWindow(template, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class, inline : "yes"}); 240 } 241 242 return true; 243 244 case "mceImage": 245 var src = "", alt = "", border = "", hspace = "", vspace = "", width = "", height = "", align = ""; 246 var title = "", onmouseover = "", onmouseout = "", action = "insert"; 247 var img = tinyMCE.imgElement; 248 var inst = tinyMCE.getInstanceById(editor_id); 249 250 if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") { 251 img = tinyMCE.selectedElement; 252 tinyMCE.imgElement = img; 253 } 254 255 if (img) { 256 // Is it a internal MCE visual aid image, then skip this one. 257 if (tinyMCE.getAttrib(img, 'name').indexOf('mce_') == 0) 258 return true; 259 260 src = tinyMCE.getAttrib(img, 'src'); 261 alt = tinyMCE.getAttrib(img, 'alt'); 262 263 // Try polling out the title 264 if (alt == "") 265 alt = tinyMCE.getAttrib(img, 'title'); 266 267 // Fix width/height attributes if the styles is specified 268 if (tinyMCE.isGecko) { 269 var w = img.style.width; 270 if (w != null && w != "") 271 img.setAttribute("width", w); 272 273 var h = img.style.height; 274 if (h != null && h != "") 275 img.setAttribute("height", h); 276 } 277 278 border = tinyMCE.getAttrib(img, 'border'); 279 hspace = tinyMCE.getAttrib(img, 'hspace'); 280 vspace = tinyMCE.getAttrib(img, 'vspace'); 281 width = tinyMCE.getAttrib(img, 'width'); 282 height = tinyMCE.getAttrib(img, 'height'); 283 align = tinyMCE.getAttrib(img, 'align'); 284 onmouseover = tinyMCE.getAttrib(img, 'onmouseover'); 285 onmouseout = tinyMCE.getAttrib(img, 'onmouseout'); 286 title = tinyMCE.getAttrib(img, 'title'); 287 288 // Is realy specified? 289 if (tinyMCE.isMSIE) { 290 width = img.attributes['width'].specified ? width : ""; 291 height = img.attributes['height'].specified ? height : ""; 292 } 293 294 //onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover)); 295 //onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout)); 296 297 src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);"); 298 299 // Use mce_src if defined 300 mceRealSrc = tinyMCE.getAttrib(img, 'mce_src'); 301 if (mceRealSrc != "") { 302 src = mceRealSrc; 303 304 if (tinyMCE.getParam('convert_urls')) 305 src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);"); 306 } 307 308 //if (onmouseover != "") 309 // onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);"); 310 311 //if (onmouseout != "") 312 // onmouseout = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, img, true);"); 313 314 action = "update"; 315 } 316 317 var template = new Array(); 318 319 template['file'] = 'image.htm?src={$src}'; 320 template['width'] = 355; 321 template['height'] = 265 + (tinyMCE.isMSIE ? 25 : 0); 322 323 // Language specific width and height addons 324 template['width'] += tinyMCE.getLang('lang_insert_image_delta_width', 0); 325 template['height'] += tinyMCE.getLang('lang_insert_image_delta_height', 0); 326 327 if (inst.settings['insertimage_callback']) { 328 var returnVal = eval(inst.settings['insertimage_callback'] + "(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);"); 329 if (returnVal && returnVal['src']) 330 TinyMCE_AdvancedTheme._insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']); 331 } else 332 tinyMCE.openWindow(template, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action, inline : "yes"}); 333 334 return true; 335 336 case "forecolor": 337 var fcp = new TinyMCE_Layer(editor_id + '_fcPreview', false), p, img, elm; 338 339 TinyMCE_AdvancedTheme._hideMenus(editor_id); 340 341 if (!fcp.exists()) { 342 fcp.create('div', 'mceColorPreview', document.getElementById(editor_id + '_toolbar')); 343 elm = fcp.getElement(); 344 elm._editor_id = editor_id; 345 elm._command = "forecolor"; 346 elm._switchId = editor_id + "_forecolor"; 347 tinyMCE.addEvent(elm, 'click', TinyMCE_AdvancedTheme._handleMenuEvent); 348 tinyMCE.addEvent(elm, 'mouseover', TinyMCE_AdvancedTheme._handleMenuEvent); 349 tinyMCE.addEvent(elm, 'mouseout', TinyMCE_AdvancedTheme._handleMenuEvent); 350 } 351 352 img = tinyMCE.selectNodes(document.getElementById(editor_id + "_forecolor"), function(n) {return n.nodeName == "IMG";})[0]; 353 p = tinyMCE.getAbsPosition(img, document.getElementById(editor_id + '_toolbar')); 354 355 fcp.moveTo(p.absLeft, p.absTop); 356 fcp.getElement().style.backgroundColor = value != null ? value : tinyMCE.getInstanceById(editor_id).foreColor; 357 fcp.show(); 358 359 return false; 360 361 case "forecolorpicker": 362 this._pickColor(editor_id, 'forecolor'); 363 return true; 364 365 case "forecolorMenu": 366 TinyMCE_AdvancedTheme._hideMenus(editor_id); 367 368 // Create color layer 369 var ml = new TinyMCE_Layer(editor_id + '_fcMenu'); 370 371 if (!ml.exists()) 372 ml.create('div', 'mceMenu', document.body, TinyMCE_AdvancedTheme._getColorHTML(editor_id, 'theme_advanced_text_colors', 'forecolor')); 373 374 tinyMCE.switchClass(editor_id + '_forecolor', 'mceMenuButtonFocus'); 375 ml.moveRelativeTo(document.getElementById(editor_id + "_forecolor"), 'bl'); 376 377 ml.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? -1 : 1, -1); 378 379 if (tinyMCE.isOpera) 380 ml.moveBy(0, -2); 381 382 ml.show(); 383 return true; 384 385 case "HiliteColor": 386 var bcp = new TinyMCE_Layer(editor_id + '_bcPreview', false), p, img; 387 388 TinyMCE_AdvancedTheme._hideMenus(editor_id); 389 390 if (!bcp.exists()) { 391 bcp.create('div', 'mceColorPreview', document.getElementById(editor_id + '_toolbar')); 392 elm = bcp.getElement(); 393 elm._editor_id = editor_id; 394 elm._command = "HiliteColor"; 395 elm._switchId = editor_id + "_backcolor"; 396 tinyMCE.addEvent(elm, 'click', TinyMCE_AdvancedTheme._handleMenuEvent); 397 tinyMCE.addEvent(elm, 'mouseover', TinyMCE_AdvancedTheme._handleMenuEvent); 398 tinyMCE.addEvent(elm, 'mouseout', TinyMCE_AdvancedTheme._handleMenuEvent); 399 } 400 401 img = tinyMCE.selectNodes(document.getElementById(editor_id + "_backcolor"), function(n) {return n.nodeName == "IMG";})[0]; 402 p = tinyMCE.getAbsPosition(img, document.getElementById(editor_id + '_toolbar')); 403 404 bcp.moveTo(p.absLeft, p.absTop); 405 bcp.getElement().style.backgroundColor = value != null ? value : tinyMCE.getInstanceById(editor_id).backColor; 406 bcp.show(); 407 408 return false; 409 410 case "HiliteColorMenu": 411 TinyMCE_AdvancedTheme._hideMenus(editor_id); 412 413 // Create color layer 414 var ml = new TinyMCE_Layer(editor_id + '_bcMenu'); 415 416 if (!ml.exists()) 417 ml.create('div', 'mceMenu', document.body, TinyMCE_AdvancedTheme._getColorHTML(editor_id, 'theme_advanced_background_colors', 'HiliteColor')); 418 419 tinyMCE.switchClass(editor_id + '_backcolor', 'mceMenuButtonFocus'); 420 ml.moveRelativeTo(document.getElementById(editor_id + "_backcolor"), 'bl'); 421 422 ml.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? -1 : 1, -1); 423 424 if (tinyMCE.isOpera) 425 ml.moveBy(0, -2); 426 427 ml.show(); 428 return true; 429 430 case "backcolorpicker": 431 this._pickColor(editor_id, 'HiliteColor'); 432 return true; 433 434 case "mceColorPicker": 435 if (user_interface) { 436 var template = []; 437 438 if (!value['callback'] && !value['color']) 439 value['color'] = value['document'].getElementById(value['element_id']).value; 440 441 template['file'] = 'color_picker.htm'; 442 template['width'] = 380; 443 template['height'] = 250; 444 template['close_previous'] = "no"; 445 446 template['width'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_width', 0); 447 template['height'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_height', 0); 448 449 if (typeof(value['store_selection']) == "undefined") 450 value['store_selection'] = true; 451 452 tinyMCE.lastColorPickerValue = value; 453 tinyMCE.openWindow(template, {editor_id : editor_id, mce_store_selection : value['store_selection'], inline : "yes", command : "mceColorPicker", input_color : value['color']}); 454 } else { 455 var savedVal = tinyMCE.lastColorPickerValue, elm; 456 457 if (savedVal['callback']) { 458 savedVal['callback'](value); 459 return true; 460 } 461 462 elm = savedVal['document'].getElementById(savedVal['element_id']); 463 elm.value = value; 464 465 if (elm.onchange != null && elm.onchange != '') 466 eval('elm.onchange();'); 467 } 468 return true; 469 470 case "mceCodeEditor": 471 var template = new Array(); 472 473 template['file'] = 'source_editor.htm'; 474 template['width'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_width", 720)); 475 template['height'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_height", 580)); 476 477 tinyMCE.openWindow(template, {editor_id : editor_id, resizable : "yes", scrollbars : "no", inline : "yes"}); 478 return true; 479 480 case "mceCharMap": 481 var template = new Array(); 482 483 template['file'] = 'charmap.htm'; 484 template['width'] = 550 + (tinyMCE.isOpera ? 40 : 0); 485 template['height'] = 250; 486 487 template['width'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_width', 0); 488 template['height'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_height', 0); 489 490 tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"}); 491 return true; 492 493 case "mceInsertAnchor": 494 var template = new Array(); 495 496 template['file'] = 'anchor.htm'; 497 template['width'] = 320; 498 template['height'] = 90 + (tinyMCE.isNS7 ? 30 : 0); 499 500 template['width'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_width', 0); 501 template['height'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_height', 0); 502 503 tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"}); 504 return true; 505 506 case "mceNewDocument": 507 if (confirm(tinyMCE.getLang('lang_newdocument'))) 508 tinyMCE.execInstanceCommand(editor_id, 'mceSetContent', false, ' '); 509 510 return true; 511 } 512 513 return false; 514 }, 515 516 /** 517 * Editor instance template function. 518 */ 519 getEditorTemplate : function(settings, editorId) { 520 function removeFromArray(in_array, remove_array) { 521 var outArray = new Array(), skip; 522 523 for (var i=0; i<in_array.length; i++) { 524 skip = false; 525 526 for (var j=0; j<remove_array.length; j++) { 527 if (in_array[i] == remove_array[j]) { 528 skip = true; 529 } 530 } 531 532 if (!skip) { 533 outArray[outArray.length] = in_array[i]; 534 } 535 } 536 537 return outArray; 538 } 539 540 function addToArray(in_array, add_array) { 541 for (var i=0; i<add_array.length; i++) { 542 in_array[in_array.length] = add_array[i]; 543 } 544 545 return in_array; 546 } 547 548 var template = new Array(); 549 var deltaHeight = 0; 550 var resizing = tinyMCE.getParam("theme_advanced_resizing", false); 551 var path = tinyMCE.getParam("theme_advanced_path", true); 552 var statusbarHTML = '<div id="{$editor_id}_path" class="mceStatusbarPathText" style="display: ' + (path ? "block" : "none") + '"> </div><div id="{$editor_id}_resize" class="mceStatusbarResize" style="display: ' + (resizing ? "block" : "none") + '" onmousedown="tinyMCE.themes.advanced._setResizing(event,\'{$editor_id}\',true);"></div><br style="clear: both" />'; 553 var layoutManager = tinyMCE.getParam("theme_advanced_layout_manager", "SimpleLayout"); 554 555 // Setup style select options -- MOVED UP FOR EXTERNAL TOOLBAR COMPATABILITY! 556 var styleSelectHTML = '<option value="">{$lang_theme_style_select}</option>'; 557 if (settings['theme_advanced_styles']) { 558 var stylesAr = settings['theme_advanced_styles'].split(';'); 559 560 for (var i=0; i<stylesAr.length; i++) { 561 var key, value; 562 563 key = stylesAr[i].split('=')[0]; 564 value = stylesAr[i].split('=')[1]; 565 566 styleSelectHTML += '<option value="' + value + '">' + key + '</option>'; 567 } 568 569 TinyMCE_AdvancedTheme._autoImportCSSClasses = false; 570 } 571 572 switch(layoutManager) { 573 case "SimpleLayout" : //the default TinyMCE Layout (for backwards compatibility)... 574 var toolbarHTML = ""; 575 var toolbarLocation = tinyMCE.getParam("theme_advanced_toolbar_location", "bottom"); 576 var toolbarAlign = tinyMCE.getParam("theme_advanced_toolbar_align", "center"); 577 var pathLocation = tinyMCE.getParam("theme_advanced_path_location", "none"); // Compatiblity 578 var statusbarLocation = tinyMCE.getParam("theme_advanced_statusbar_location", pathLocation); 579 var defVals = { 580 theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect", 581 theme_advanced_buttons2 : "bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code", 582 theme_advanced_buttons3 : "hr,removeformat,visualaid,separator,sub,sup,separator,charmap" 583 }; 584 585 // Add accessibility control 586 toolbarHTML += '<a href="#" accesskey="q" title="' + tinyMCE.getLang("lang_toolbar_focus") + '"'; 587 588 if (!tinyMCE.getParam("accessibility_focus")) 589 toolbarHTML += ' onfocus="tinyMCE.getInstanceById(\'' + editorId + '\').getWin().focus();"'; 590 591 toolbarHTML += '></a>'; 592 593 // Render rows 594 for (var i=1; i<100; i++) { 595 var def = defVals["theme_advanced_buttons" + i]; 596 597 var buttons = tinyMCE.getParam("theme_advanced_buttons" + i, def == null ? '' : def, true, ','); 598 if (buttons.length == 0) 599 break; 600 601 buttons = removeFromArray(buttons, tinyMCE.getParam("theme_advanced_disable", "", true, ',')); 602 buttons = addToArray(buttons, tinyMCE.getParam("theme_advanced_buttons" + i + "_add", "", true, ',')); 603 buttons = addToArray(tinyMCE.getParam("theme_advanced_buttons" + i + "_add_before", "", true, ','), buttons); 604 605 for (var b=0; b<buttons.length; b++) 606 toolbarHTML += tinyMCE.getControlHTML(buttons[b]); 607 608 if (buttons.length > 0) { 609 toolbarHTML += "<br />"; 610 deltaHeight -= 23; 611 } 612 } 613 614 // Add accessibility control 615 toolbarHTML += '<a href="#" accesskey="z" onfocus="tinyMCE.getInstanceById(\'' + editorId + '\').getWin().focus();"></a>'; 616 617 // Setup template html 618 template['html'] = '<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width_style};height:{$height_style}"><tbody>'; 619 620 if (toolbarLocation == "top") 621 template['html'] += '<tr><td dir="ltr" class="mceToolbarTop" align="' + toolbarAlign + '" height="1" nowrap="nowrap"><span id="' + editorId + '_toolbar" class="mceToolbarContainer">' + toolbarHTML + '</span></td></tr>'; 622 623 if (statusbarLocation == "top") { 624 template['html'] += '<tr><td class="mceStatusbarTop" height="1">' + statusbarHTML + '</td></tr>'; 625 deltaHeight -= 23; 626 } 627 628 template['html'] += '<tr><td align="center"><span id="{$editor_id}"></span></td></tr>'; 629 630 if (toolbarLocation == "bottom") 631 template['html'] += '<tr><td dir="ltr" class="mceToolbarBottom" align="' + toolbarAlign + '" height="1"><span id="' + editorId + '_toolbar" class="mceToolbarContainer">' + toolbarHTML + '</span></td></tr>'; 632 633 // External toolbar changes 634 if (toolbarLocation == "external") { 635 var bod = document.body; 636 var elm = document.createElement ("div"); 637 638 toolbarHTML = tinyMCE.replaceVar(toolbarHTML, 'style_select_options', styleSelectHTML); 639 toolbarHTML = tinyMCE.applyTemplate(toolbarHTML, {editor_id : editorId}); 640 641 elm.className = "mceToolbarExternal"; 642 elm.id = editorId+"_toolbar"; 643 elm.innerHTML = '<table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table>'; 644 bod.appendChild (elm); 645 // bod.style.marginTop = elm.offsetHeight + "px"; 646 647 deltaHeight = 0; 648 tinyMCE.getInstanceById(editorId).toolbarElement = elm; 649 650 //template['html'] = '<div id="mceExternalToolbar" align="center" class="mceToolbarExternal"><table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table></div>' + template["html"]; 651 } else { 652 tinyMCE.getInstanceById(editorId).toolbarElement = null; 653 } 654 655 if (statusbarLocation == "bottom") { 656 template['html'] += '<tr><td class="mceStatusbarBottom" height="1">' + statusbarHTML + '</td></tr>'; 657 deltaHeight -= 23; 658 } 659 660 template['html'] += '</tbody></table>'; 661 //"SimpleLayout" 662 break; 663 664 case "RowLayout" : //Container Layout - containers defined in "theme_advanced_containers" are rendered from top to bottom. 665 template['html'] = '<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>'; 666 667 var containers = tinyMCE.getParam("theme_advanced_containers", "", true, ","); 668 var defaultContainerCSS = tinyMCE.getParam("theme_advanced_containers_default_class", "container"); 669 var defaultContainerAlign = tinyMCE.getParam("theme_advanced_containers_default_align", "center"); 670 671 //Render Containers: 672 for (var i = 0; i < containers.length; i++) 673 { 674 if (containers[i] == "mceEditor") //Exceptions for mceEditor and ... 675 template['html'] += '<tr><td align="center" class="mceEditor_border"><span id="{$editor_id}"></span></td></tr>'; 676 else if (containers[i] == "mceElementpath" || containers[i] == "mceStatusbar") // ... mceElementpath: 677 { 678 var pathClass = "mceStatusbar"; 679 680 if (i == containers.length-1) 681 { 682 pathClass = "mceStatusbarBottom"; 683 } 684 else if (i == 0) 685 { 686 pathClass = "mceStatusbar"; 687 } 688 else 689 { 690 deltaHeight-=2; 691 } 692 693 template['html'] += '<tr><td class="' + pathClass + '" height="1">' + statusbarHTML + '</td></tr>'; 694 deltaHeight -= 22; 695 } else { // Render normal Container 696 var curContainer = tinyMCE.getParam("theme_advanced_container_"+containers[i], "", true, ','); 697 var curContainerHTML = ""; 698 var curAlign = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align", defaultContainerAlign); 699 var curCSS = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class", defaultContainerCSS); 700 701 curContainer = removeFromArray(curContainer, tinyMCE.getParam("theme_advanced_disable", "", true, ',')); 702 703 for (var j=0; j<curContainer.length; j++) 704 curContainerHTML += tinyMCE.getControlHTML(curContainer[j]); 705 706 if (curContainer.length > 0) { 707 curContainerHTML += "<br />"; 708 deltaHeight -= 23; 709 } 710 711 template['html'] += '<tr><td class="' + curCSS + '" align="' + curAlign + '" height="1">' + curContainerHTML + '</td></tr>'; 712 } 713 } 714 715 template['html'] += '</tbody></table>'; 716 //RowLayout 717 break; 718 719 case "CustomLayout" : //User defined layout callback... 720 var customLayout = tinyMCE.getParam("theme_advanced_custom_layout",""); 721 722 if (customLayout != "" && eval("typeof(" + customLayout + ")") != "undefined") { 723 template = eval(customLayout + "(template);"); 724 } 725 break; 726 } 727 728 if (resizing) 729 template['html'] += '<span id="{$editor_id}_resize_box" class="mceResizeBox"></span>'; 730 731 template['html'] = tinyMCE.replaceVar(template['html'], 'style_select_options', styleSelectHTML); 732 733 // Set to default values 734 if (!template['delta_width']) 735 template['delta_width'] = 0; 736 737 if (!template['delta_height']) 738 template['delta_height'] = deltaHeight; 739 740 return template; 741 }, 742 743 initInstance : function(inst) { 744 if (tinyMCE.getParam("theme_advanced_resizing", false)) { 745 if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) { 746 var w = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_width"); 747 var h = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_height"); 748 749 TinyMCE_AdvancedTheme._resizeTo(inst, w, h, tinyMCE.getParam("theme_advanced_resize_horizontal", true)); 750 } 751 } 752 753 inst.addShortcut('ctrl', 'k', 'lang_link_desc', 'mceLink'); 754 }, 755 756 removeInstance : function(inst) { 757 new TinyMCE_Layer(inst.editorId + '_fcMenu').remove(); 758 new TinyMCE_Layer(inst.editorId + '_bcMenu').remove(); 759 }, 760 761 hideInstance : function(inst) { 762 TinyMCE_AdvancedTheme._hideMenus(inst.editorId); 763 }, 764 765 _handleMenuEvent : function(e) { 766 var te = tinyMCE.isMSIE ? window.event.srcElement : e.target; 767 tinyMCE._menuButtonEvent(e.type == "mouseover" ? "over" : "out", document.getElementById(te._switchId)); 768 769 if (e.type == "click") 770 tinyMCE.execInstanceCommand(te._editor_id, te._command); 771 }, 772 773 _hideMenus : function(id) { 774 var fcml = new TinyMCE_Layer(id + '_fcMenu'), bcml = new TinyMCE_Layer(id + '_bcMenu'); 775 776 if (fcml.exists() && fcml.isVisible()) { 777 tinyMCE.switchClass(id + '_forecolor', 'mceMenuButton'); 778 fcml.hide(); 779 } 780 781 if (bcml.exists() && bcml.isVisible()) { 782 tinyMCE.switchClass(id + '_backcolor', 'mceMenuButton'); 783 bcml.hide(); 784 } 785 }, 786 787 /** 788 * Node change handler. 789 */ 790 handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection, setup_content) { 791 var alignNode, breakOut, classNode; 792 793 function selectByValue(select_elm, value, first_index) { 794 first_index = typeof(first_index) == "undefined" ? false : true; 795 796 if (select_elm) { 797 for (var i=0; i<select_elm.options.length; i++) { 798 var ov = "" + select_elm.options[i].value; 799 800 if (first_index && ov.toLowerCase().indexOf(value.toLowerCase()) == 0) { 801 select_elm.selectedIndex = i; 802 return true; 803 } 804 805 if (ov == value) { 806 select_elm.selectedIndex = i; 807 return true; 808 } 809 } 810 } 811 812 return false; 813 }; 814 815 // No node provided 816 if (node == null) 817 return; 818 819 // Update path 820 var pathElm = document.getElementById(editor_id + "_path"); 821 var inst = tinyMCE.getInstanceById(editor_id); 822 var doc = inst.getDoc(); 823 TinyMCE_AdvancedTheme._hideMenus(editor_id); 824 825 if (pathElm) { 826 // Get node path 827 var parentNode = node; 828 var path = new Array(); 829 830 while (parentNode != null) { 831 if (parentNode.nodeName.toUpperCase() == "BODY") { 832 break; 833 } 834 835 // Only append element nodes to path 836 if (parentNode.nodeType == 1 && tinyMCE.getAttrib(parentNode, "class").indexOf('mceItemHidden') == -1) { 837 path[path.length] = parentNode; 838 } 839 840 parentNode = parentNode.parentNode; 841 } 842 843 // Setup HTML 844 var html = ""; 845 for (var i=path.length-1; i>=0; i--) { 846 var nodeName = path[i].nodeName.toLowerCase(); 847 var nodeData = ""; 848 849 if (nodeName.indexOf("html:") == 0) 850 nodeName = nodeName.substring(5); 851 852 if (nodeName == "b") { 853 nodeName = "strong"; 854 } 855 856 if (nodeName == "i") { 857 nodeName = "em"; 858 } 859 860 if (nodeName == "span") { 861 var cn = tinyMCE.getAttrib(path[i], "class"); 862 if (cn != "" && cn.indexOf('mceItem') == -1) 863 nodeData += "class: " + cn + " "; 864 865 var st = tinyMCE.getAttrib(path[i], "style"); 866 if (st != "") { 867 st = tinyMCE.serializeStyle(tinyMCE.parseStyle(st)); 868 nodeData += "style: " + tinyMCE.xmlEncode(st) + " "; 869 } 870 } 871 872 if (nodeName == "font") { 873 if (tinyMCE.getParam("convert_fonts_to_spans")) 874 nodeName = "span"; 875 876 var face = tinyMCE.getAttrib(path[i], "face"); 877 if (face != "") 878 nodeData += "font: " + tinyMCE.xmlEncode(face) + " "; 879 880 var size = tinyMCE.getAttrib(path[i], "size"); 881 if (size != "") 882 nodeData += "size: " + tinyMCE.xmlEncode(size) + " "; 883 884 var color = tinyMCE.getAttrib(path[i], "color"); 885 if (color != "") 886 nodeData += "color: " + tinyMCE.xmlEncode(color) + " "; 887 } 888 889 if (tinyMCE.getAttrib(path[i], 'id') != "") { 890 nodeData += "id: " + path[i].getAttribute('id') + " "; 891 } 892 893 var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false); 894 if (className != "" && className.indexOf('mceItem') == -1) 895 nodeData += "class: " + className + " "; 896 897 if (tinyMCE.getAttrib(path[i], 'src') != "") { 898 var src = tinyMCE.getAttrib(path[i], "mce_src"); 899 900 if (src == "") 901 src = tinyMCE.getAttrib(path[i], "src"); 902 903 nodeData += "src: " + tinyMCE.xmlEncode(src) + " "; 904 } 905 906 if (path[i].nodeName == 'A' && tinyMCE.getAttrib(path[i], 'href') != "") { 907 var href = tinyMCE.getAttrib(path[i], "mce_href"); 908 909 if (href == "") 910 href = tinyMCE.getAttrib(path[i], "href"); 911 912 nodeData += "href: " + tinyMCE.xmlEncode(href) + " "; 913 } 914 915 className = tinyMCE.getAttrib(path[i], "class"); 916 if ((nodeName == "img" || nodeName == "span") && className.indexOf('mceItem') != -1) { 917 nodeName = className.replace(/mceItem([a-z]+)/gi, '$1').toLowerCase(); 918 nodeData = path[i].getAttribute('title'); 919 } 920 921 if (nodeName == "a" && (anchor = tinyMCE.getAttrib(path[i], "name")) != "") { 922 nodeName = "a"; 923 nodeName += "#" + tinyMCE.xmlEncode(anchor); 924 nodeData = ""; 925 } 926 927 if (tinyMCE.getAttrib(path[i], 'name').indexOf("mce_") != 0) { 928 var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false); 929 if (className != "" && className.indexOf('mceItem') == -1) { 930 nodeName += "." + className; 931 } 932 } 933 934 var cmd = 'tinyMCE.execInstanceCommand(\'' + editor_id + '\',\'mceSelectNodeDepth\',false,\'' + i + '\');'; 935 html += '<a title="' + nodeData + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" target="_self" class="mcePathItem">' + nodeName + '</a>'; 936 937 if (i > 0) { 938 html += " » "; 939 } 940 } 941 942 pathElm.innerHTML = '<a href="#" accesskey="x"></a>' + tinyMCE.getLang('lang_theme_path') + ": " + html + ' '; 943 } 944 945 // Reset old states 946 tinyMCE.switchClass(editor_id + '_justifyleft', 'mceButtonNormal'); 947 tinyMCE.switchClass(editor_id + '_justifyright', 'mceButtonNormal'); 948 tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonNormal'); 949 tinyMCE.switchClass(editor_id + '_justifyfull', 'mceButtonNormal'); 950 tinyMCE.switchClass(editor_id + '_bold', 'mceButtonNormal'); 951 tinyMCE.switchClass(editor_id + '_italic', 'mceButtonNormal'); 952 tinyMCE.switchClass(editor_id + '_underline', 'mceButtonNormal'); 953 tinyMCE.switchClass(editor_id + '_strikethrough', 'mceButtonNormal'); 954 tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonNormal'); 955 tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonNormal'); 956 tinyMCE.switchClass(editor_id + '_sub', 'mceButtonNormal'); 957 tinyMCE.switchClass(editor_id + '_sup', 'mceButtonNormal'); 958 tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonNormal'); 959 tinyMCE.switchClass(editor_id + '_link', 'mceButtonDisabled'); 960 tinyMCE.switchClass(editor_id + '_unlink', 'mceButtonDisabled'); 961 tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonDisabled'); 962 tinyMCE.switchClass(editor_id + '_image', 'mceButtonNormal'); 963 tinyMCE.switchClass(editor_id + '_hr', 'mceButtonNormal'); 964 965 if (node.nodeName == "A" && tinyMCE.getAttrib(node, "class").indexOf('mceItemAnchor') != -1) 966 tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonSelected'); 967 968 // Get link 969 var anchorLink = tinyMCE.getParentElement(node, "a", "href"); 970 971 if (anchorLink || any_selection) { 972 tinyMCE.switchClass(editor_id + '_link', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal'); 973 tinyMCE.switchClass(editor_id + '_unlink', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal'); 974 } 975 976 // Handle visual aid 977 tinyMCE.switchClass(editor_id + '_visualaid', visual_aid ? 'mceButtonSelected' : 'mceButtonNormal'); 978 979 if (undo_levels != -1) { 980 tinyMCE.switchClass(editor_id + '_undo', 'mceButtonDisabled'); 981 tinyMCE.switchClass(editor_id + '_redo', 'mceButtonDisabled'); 982 } 983 984 // Within li, blockquote 985 if (tinyMCE.getParentElement(node, "li,blockquote")) 986 tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonNormal'); 987 988 // Has redo levels 989 if (undo_index != -1 && (undo_index < undo_levels-1 && undo_levels > 0)) 990 tinyMCE.switchClass(editor_id + '_redo', 'mceButtonNormal'); 991 992 // Has undo levels 993 if (undo_index != -1 && (undo_index > 0 && undo_levels > 0)) 994 tinyMCE.switchClass(editor_id + '_undo', 'mceButtonNormal'); 995 996 // Select class in select box 997 var selectElm = document.getElementById(editor_id + "_styleSelect"); 998 999 if (selectElm) { 1000 TinyMCE_AdvancedTheme._setupCSSClasses(editor_id); 1001 1002 classNode = node; 1003 breakOut = false; 1004 var index = 0; 1005 1006 do { 1007 if (classNode && classNode.className) { 1008 for (var i=0; i<selectElm.options.length; i++) { 1009 if (selectElm.options[i].value == classNode.className) { 1010 index = i; 1011 breakOut = true; 1012 break; 824 825 if (v = DOM.getAttrib(n, 'id')) 826 ti += 'id: ' + v + ' '; 827 828 if (v = n.className) { 829 v = v.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g, ''); 830 831 if (v && v.indexOf('mceItem') == -1) { 832 ti += 'class: ' + v + ' '; 833 834 if (DOM.isBlock(n) || na == 'img' || na == 'span') 835 na += '.' + v; 1013 836 } 1014 837 } 838 839 na = na.replace(/(html:)/g, ''); 840 na = {name : na, node : n, title : ti}; 841 t.onResolveName.dispatch(t, na); 842 ti = na.title; 843 na = na.name; 844 845 //u = "javascript:tinymce.EditorManager.get('" + ed.id + "').theme._sel('" + (de++) + "');"; 846 pi = DOM.create('a', {'href' : "#" + (de++) + "", onmousedown : "return false;", title : ti}, na); 847 848 if (p.hasChildNodes()) { 849 p.insertBefore(document.createTextNode(' \u00bb '), p.firstChild); 850 p.insertBefore(pi, p.firstChild); 851 } else 852 p.appendChild(pi); 853 }, ed.getBody()); 854 } 855 }, 856 857 // Commands gets called by execCommand 858 859 _sel : function(v) { 860 this.editor.execCommand('mceSelectNodeDepth', false, v); 861 }, 862 863 _mceInsertAnchor : function(ui, v) { 864 var ed = this.editor; 865 866 ed.windowManager.open({ 867 url : tinymce.baseURL + '/themes/advanced/anchor.htm', 868 width : 320 + parseInt(ed.getLang('advanced.anchor_delta_width', 0)), 869 height : 90 + parseInt(ed.getLang('advanced.anchor_delta_height', 0)), 870 inline : true 871 }, { 872 theme_url : this.url 873 }); 874 }, 875 876 _mceCharMap : function() { 877 var ed = this.editor; 878 879 ed.windowManager.open({ 880 url : tinymce.baseURL + '/themes/advanced/charmap.htm', 881 width : 550 + parseInt(ed.getLang('advanced.charmap_delta_width', 0)), 882 height : 250 + parseInt(ed.getLang('advanced.charmap_delta_height', 0)), 883 inline : true 884 }, { 885 theme_url : this.url 886 }); 887 }, 888 889 _mceHelp : function() { 890 var ed = this.editor; 891 892 ed.windowManager.open({ 893 url : tinymce.baseURL + '/themes/advanced/about.htm', 894 width : 480, 895 height : 380, 896 inline : true 897 }, { 898 theme_url : this.url 899 }); 900 }, 901 902 _mceColorPicker : function(u, v) { 903 var ed = this.editor; 904 905 v = v || {}; 906 907 ed.windowManager.open({ 908 url : tinymce.baseURL + '/themes/advanced/color_picker.htm', 909 width : 375 + parseInt(ed.getLang('advanced.colorpicker_delta_width', 0)), 910 height : 250 + parseInt(ed.getLang('advanced.colorpicker_delta_height', 0)), 911 close_previous : false, 912 inline : true 913 }, { 914 input_color : v.color, 915 func : v.func, 916 theme_url : this.url 917 }); 918 }, 919 920 _mceCodeEditor : function(ui, val) { 921 var ed = this.editor; 922 923 ed.windowManager.open({ 924 url : tinymce.baseURL + '/themes/advanced/source_editor.htm', 925 width : parseInt(ed.getParam("theme_advanced_source_editor_width", 720)), 926 height : parseInt(ed.getParam("theme_advanced_source_editor_height", 580)), 927 inline : true, 928 resizable : true, 929 maximizable : true 930 }, { 931 theme_url : this.url 932 }); 933 }, 934 935 _mceImage : function(ui, val) { 936 var ed = this.editor; 937 938 ed.windowManager.open({ 939 url : tinymce.baseURL + '/themes/advanced/image.htm', 940 width : 355 + parseInt(ed.getLang('advanced.image_delta_width', 0)), 941 height : 275 + parseInt(ed.getLang('advanced.image_delta_height', 0)), 942 inline : true 943 }, { 944 theme_url : this.url 945 }); 946 }, 947 948 _mceLink : function(ui, val) { 949 var ed = this.editor; 950 951 ed.windowManager.open({ 952 url : tinymce.baseURL + '/themes/advanced/link.htm', 953 width : 310 + parseInt(ed.getLang('advanced.link_delta_width', 0)), 954 height : 200 + parseInt(ed.getLang('advanced.link_delta_height', 0)), 955 inline : true 956 }, { 957 theme_url : this.url 958 }); 959 }, 960 961 _mceNewDocument : function() { 962 var ed = this.editor; 963 964 ed.windowManager.confirm('advanced.newdocument', function(s) { 965 if (s) 966 ed.execCommand('mceSetContent', false, ''); 967 }); 968 }, 969 970 _mceForeColor : function() { 971 var t = this; 972 973 this._mceColorPicker(0, { 974 func : function(co) { 975 t.editor.execCommand('ForeColor', false, co); 1015 976 } 1016 } while (!breakOut && classNode != null && (classNode = classNode.parentNode) != null); 1017 1018 selectElm.selectedIndex = index; 977 }); 978 }, 979 980 _mceBackColor : function() { 981 var t = this; 982 983 this._mceColorPicker(0, { 984 func : function(co) { 985 t.editor.execCommand('HiliteColor', false, co); 986 } 987 }); 1019 988 } 1020 1021 // Select formatblock 1022 var selectElm = document.getElementById(editor_id + "_formatSelect"); 1023 if (selectElm) { 1024 var elm = tinyMCE.getParentElement(node, "p,div,h1,h2,h3,h4,h5,h6,pre,address"); 1025 1026 if (elm) 1027 selectByValue(selectElm, "<" + elm.nodeName.toLowerCase() + ">"); 1028 else 1029 selectByValue(selectElm, ""); 1030 } 1031 1032 // Select fontselect 1033 var selectElm = document.getElementById(editor_id + "_fontNameSelect"); 1034 if (selectElm) { 1035 if (!tinyMCE.isSafari && !(tinyMCE.isMSIE && !tinyMCE.isOpera)) { 1036 var face = inst.queryCommandValue('FontName'); 1037 1038 face = face == null || face == "" ? "" : face; 1039 1040 selectByValue(selectElm, face, face != ""); 1041 } else { 1042 var elm = tinyMCE.getParentElement(node, "font", "face"); 1043 1044 if (elm) { 1045 var family = tinyMCE.getAttrib(elm, "face"); 1046 1047 if (family == '') 1048 family = '' + elm.style.fontFamily; 1049 1050 if (!selectByValue(selectElm, family, family != "")) 1051 selectByValue(selectElm, ""); 1052 } else 1053 selectByValue(selectElm, ""); 1054 } 1055 } 1056 1057 // Select fontsize 1058 var selectElm = document.getElementById(editor_id + "_fontSizeSelect"); 1059 if (selectElm) { 1060 if (!tinyMCE.isSafari && !tinyMCE.isOpera) { 1061 var size = inst.queryCommandValue('FontSize'); 1062 selectByValue(selectElm, size == null || size == "" ? "0" : size); 1063 } else { 1064 var elm = tinyMCE.getParentElement(node, "font", "size"); 1065 if (elm) { 1066 var size = tinyMCE.getAttrib(elm, "size"); 1067 1068 if (size == '') { 1069 var sizes = new Array('', '8px', '10px', '12px', '14px', '18px', '24px', '36px'); 1070 1071 size = '' + elm.style.fontSize; 1072 1073 for (var i=0; i<sizes.length; i++) { 1074 if (('' + sizes[i]) == size) { 1075 size = i; 1076 break; 1077 } 1078 } 1079 } 1080 1081 if (!selectByValue(selectElm, size)) 1082 selectByValue(selectElm, ""); 1083 } else 1084 selectByValue(selectElm, "0"); 1085 } 1086 } 1087 1088 // Handle align attributes 1089 alignNode = node; 1090 breakOut = false; 1091 do { 1092 if (!alignNode.getAttribute || !alignNode.getAttribute('align')) 1093 continue; 1094 1095 switch (alignNode.getAttribute('align').toLowerCase()) { 1096 case "left": 1097 tinyMCE.switchClass(editor_id + '_justifyleft', 'mceButtonSelected'); 1098 breakOut = true; 1099 break; 1100 1101 case "right": 1102 tinyMCE.switchClass(editor_id + '_justifyright', 'mceButtonSelected'); 1103 breakOut = true; 1104 break; 1105 1106 case "middle": 1107 case "center": 1108 tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonSelected'); 1109 breakOut = true; 1110 break; 1111 1112 case "justify": 1113 tinyMCE.switchClass(editor_id + '_justifyfull', 'mceButtonSelected'); 1114 breakOut = true; 1115 break; 1116 } 1117 } while (!breakOut && (alignNode = alignNode.parentNode) != null); 1118 1119 // Div justification 1120 var div = tinyMCE.getParentElement(node, "div"); 1121 if (div && div.style.textAlign == "center") 1122 tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonSelected'); 1123 1124 // Do special text 1125 if (!setup_content) { 1126 // , "JustifyLeft", "_justifyleft", "JustifyCenter", "justifycenter", "JustifyRight", "justifyright", "JustifyFull", "justifyfull", "InsertUnorderedList", "bullist", "InsertOrderedList", "numlist", "InsertUnorderedList", "bullist", "Outdent", "outdent", "Indent", "indent", "subscript", "sub" 1127 var ar = new Array("Bold", "_bold", "Italic", "_italic", "Strikethrough", "_strikethrough", "superscript", "_sup", "subscript", "_sub"); 1128 for (var i=0; i<ar.length; i+=2) { 1129 if (inst.queryCommandState(ar[i])) 1130 tinyMCE.switchClass(editor_id + ar[i+1], 'mceButtonSelected'); 1131 } 1132 1133 if (inst.queryCommandState("Underline") && (node.parentNode == null || node.parentNode.nodeName != "A")) 1134 tinyMCE.switchClass(editor_id + '_underline', 'mceButtonSelected'); 1135 } 1136 1137 // Handle elements 1138 do { 1139 switch (node.nodeName) { 1140 case "UL": 1141 tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonSelected'); 1142 break; 1143 1144 case "OL": 1145 tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonSelected'); 1146 break; 1147 1148 case "HR": 1149 tinyMCE.switchClass(editor_id + '_hr', 'mceButtonSelected'); 1150 break; 1151 1152 case "IMG": 1153 if (tinyMCE.getAttrib(node, 'name').indexOf('mce_') != 0 && tinyMCE.getAttrib(node, 'class').indexOf('mceItem') == -1) { 1154 tinyMCE.switchClass(editor_id + '_image', 'mceButtonSelected'); 1155 } 1156 break; 1157 } 1158 } while ((node = node.parentNode) != null); 1159 }, 1160 1161 // Private theme internal functions 1162 1163 // This function auto imports CSS classes into the class selection droplist 1164 _setupCSSClasses : function(editor_id) { 1165 var i, selectElm; 1166 1167 if (!TinyMCE_AdvancedTheme._autoImportCSSClasses) 1168 return; 1169 1170 selectElm = document.getElementById(editor_id + '_styleSelect'); 1171 1172 if (selectElm && selectElm.getAttribute('cssImported') != 'true') { 1173 var csses = tinyMCE.getCSSClasses(editor_id); 1174 if (csses && selectElm) { 1175 for (i=0; i<csses.length; i++) 1176 selectElm.options[selectElm.options.length] = new Option(csses[i], csses[i]); 1177 } 1178 1179 // Only do this once 1180 if (csses != null && csses.length > 0) 1181 selectElm.setAttribute('cssImported', 'true'); 1182 } 1183 }, 1184 1185 _setCookie : function(name, value, expires, path, domain, secure) { 1186 var curCookie = name + "=" + escape(value) + 1187 ((expires) ? "; expires=" + expires.toGMTString() : "") + 1188 ((path) ? "; path=" + escape(path) : "") + 1189 ((domain) ? "; domain=" + domain : "") + 1190 ((secure) ? "; secure" : ""); 1191 1192 document.cookie = curCookie; 1193 }, 1194 1195 _getCookie : function(name) { 1196 var dc = document.cookie; 1197 var prefix = name + "="; 1198 var begin = dc.indexOf("; " + prefix); 1199 1200 if (begin == -1) { 1201 begin = dc.indexOf(prefix); 1202 1203 if (begin != 0) 1204 return null; 1205 } else 1206 begin += 2; 1207 1208 var end = document.cookie.indexOf(";", begin); 1209 1210 if (end == -1) 1211 end = dc.length; 1212 1213 return unescape(dc.substring(begin + prefix.length, end)); 1214 }, 1215 1216 _resizeTo : function(inst, w, h, set_w) { 1217 var editorContainer = document.getElementById(inst.editorId + '_parent'); 1218 var tableElm = editorContainer.firstChild; 1219 var iframe = inst.iframeElement; 1220 1221 if (w == null || w == "null") { 1222 set_w = false; 1223 w = 0; 1224 } 1225 1226 if (h == null || h == "null") 1227 return; 1228 1229 w = parseInt(w); 1230 h = parseInt(h); 1231 1232 if (tinyMCE.isGecko) { 1233 w += 2; 1234 h += 2; 1235 } 1236 1237 var dx = w - tableElm.clientWidth; 1238 var dy = h - tableElm.clientHeight; 1239 1240 w = w < 1 ? 30 : w; 1241 h = h < 1 ? 30 : h; 1242 1243 if (set_w) 1244 tableElm.style.width = w + "px"; 1245 1246 if ( !tinyMCE.isMSIE || tinyMCE.isMSIE7 || tinyMCE.isOpera ) // WordPress: do this later to avoid creeping toolbar bug in MSIE6 1247 tableElm.style.height = h + "px"; 1248 1249 iw = iframe.clientWidth + dx; 1250 ih = iframe.clientHeight + dy; 1251 1252 iw = iw < 1 ? 30 : iw; 1253 ih = ih < 1 ? 30 : ih; 1254 /* WordPress: found that this led to a shrinking editor with every resize. 1255 (Gray background creeps in 1px at a time.) 1256 if (tinyMCE.isGecko) { 1257 iw -= 2; 1258 ih -= 2; 1259 } 1260 */ 1261 1262 if (set_w) 1263 iframe.style.width = iw + "px"; 1264 1265 iframe.style.height = ih + "px"; 1266 1267 // Is it to small, make it bigger again 1268 if (set_w) { 1269 var tableBodyElm = tableElm.firstChild; 1270 var minIframeWidth = tableBodyElm.scrollWidth; 1271 if (inst.iframeElement.clientWidth < minIframeWidth) { 1272 dx = minIframeWidth - inst.iframeElement.clientWidth; 1273 1274 inst.iframeElement.style.width = (iw + dx) + "px"; 1275 } 1276 } 1277 1278 tableElm.style.height = h + "px"; // WordPress: see above 1279 1280 // Remove pesky table controls 1281 inst.useCSS = false; 1282 }, 1283 1284 /** 1285 * Handles resizing events. 1286 */ 1287 _resizeEventHandler : function(e) { 1288 var resizer = TinyMCE_AdvancedTheme._resizer; 1289 1290 // Do nothing 1291 if (!resizer.resizing) 1292 return; 1293 1294 e = typeof(e) == "undefined" ? window.event : e; 1295 1296 var dx = e.screenX - resizer.downX; 1297 var dy = e.screenY - resizer.downY; 1298 var resizeBox = resizer.resizeBox; 1299 var editorId = resizer.editorId; 1300 1301 switch (e.type) { 1302 case "mousemove": 1303 var w, h; 1304 1305 w = resizer.width + dx; 1306 h = resizer.height + dy; 1307 1308 w = w < 1 ? 1 : w; 1309 h = h < 1 ? 1 : h; 1310 1311 if (resizer.horizontal) 1312 resizeBox.style.width = w + "px"; 1313 1314 resizeBox.style.height = h + "px"; 1315 break; 1316 1317 case "mouseup": 1318 TinyMCE_AdvancedTheme._setResizing(e, editorId, false); 1319 TinyMCE_AdvancedTheme._resizeTo(tinyMCE.getInstanceById(editorId), resizer.width + dx, resizer.height + dy, resizer.horizontal); 1320 1321 // Expire in a month 1322 if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) { 1323 var expires = new Date(); 1324 expires.setTime(expires.getTime() + 3600000 * 24 * 30); 1325 1326 // Set the cookies 1327 TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_width", "" + (resizer.horizontal ? resizer.width + dx : ""), expires); 1328 TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_height", "" + (resizer.height + dy), expires); 1329 } 1330 break; 1331 } 1332 }, 1333 1334 /** 1335 * Starts/stops the editor resizing. 1336 */ 1337 _setResizing : function(e, editor_id, state) { 1338 e = typeof(e) == "undefined" ? window.event : e; 1339 1340 var resizer = TinyMCE_AdvancedTheme._resizer; 1341 var editorContainer = document.getElementById(editor_id + '_parent'); 1342 var editorArea = document.getElementById(editor_id + '_parent').firstChild; 1343 var resizeBox = document.getElementById(editor_id + '_resize_box'); 1344 var inst = tinyMCE.getInstanceById(editor_id); 1345 1346 if (state) { 1347 // Place box over editor area 1348 var width = editorArea.clientWidth; 1349 var height = editorArea.clientHeight; 1350 1351 resizeBox.style.width = width + "px"; 1352 resizeBox.style.height = height + "px"; 1353 1354 resizer.iframeWidth = inst.iframeElement.clientWidth; 1355 resizer.iframeHeight = inst.iframeElement.clientHeight; 1356 1357 // Hide editor and show resize box 1358 editorArea.style.display = "none"; 1359 resizeBox.style.display = "block"; 1360 1361 // Add event handlers, only once 1362 if (!resizer.eventHandlers) { 1363 if (tinyMCE.isMSIE) 1364 tinyMCE.addEvent(document, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler); 1365 else 1366 tinyMCE.addEvent(window, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler); 1367 1368 tinyMCE.addEvent(document, "mouseup", TinyMCE_AdvancedTheme._resizeEventHandler); 1369 1370 resizer.eventHandlers = true; 1371 } 1372 1373 resizer.resizing = true; 1374 resizer.downX = e.screenX; 1375 resizer.downY = e.screenY; 1376 resizer.width = parseInt(resizeBox.style.width); 1377 resizer.height = parseInt(resizeBox.style.height); 1378 resizer.editorId = editor_id; 1379 resizer.resizeBox = resizeBox; 1380 resizer.horizontal = tinyMCE.getParam("theme_advanced_resize_horizontal", true); 1381 } else { 1382 resizer.resizing = false; 1383 resizeBox.style.display = "none"; 1384 editorArea.style.display = tinyMCE.isMSIE && !tinyMCE.isOpera ? "block" : "table"; 1385 tinyMCE.execCommand('mceResetDesignMode'); 1386 } 1387 }, 1388 1389 _getColorHTML : function(id, n, cm) { 1390 var i, h, cl; 1391 1392 h = '<span class="mceMenuLine"></span>'; 1393 cl = tinyMCE.getParam(n, TinyMCE_AdvancedTheme._defColors).split(','); 1394 1395 h += '<table class="mceColors"><tr>'; 1396 for (i=0; i<cl.length; i++) { 1397 c = 'tinyMCE.execInstanceCommand(\'' + id + '\', \'' + cm + '\', false, \'#' + cl[i] + '\');'; 1398 h += '<td><a href="javascript:' + c + '" style="background-color: #' + cl[i] + '" onclick="' + c + ';return false;"></a></td>'; 1399 1400 if ((i+1) % 8 == 0) 1401 h += '</tr><tr>'; 1402 } 1403 1404 h += '</tr></table>'; 1405 1406 if (tinyMCE.getParam("theme_advanced_more_colors", true)) 1407 h += '<a href="javascript:void(0);" onclick="TinyMCE_AdvancedTheme._pickColor(\'' + id + '\',\'' + cm + '\');" class="mceMoreColors">' + tinyMCE.getLang('lang_more_colors') + '</a>'; 1408 1409 return h; 1410 }, 1411 1412 _pickColor : function(id, cm) { 1413 var inputColor, inst = tinyMCE.selectedInstance; 1414 1415 if (cm == 'forecolor' && inst) 1416 inputColor = inst.foreColor; 1417 1418 if ((cm == 'backcolor' || cm == 'HiliteColor') && inst) 1419 inputColor = inst.backColor; 1420 1421 tinyMCE.execCommand('mceColorPicker', true, {color : inputColor, callback : function(c) { 1422 tinyMCE.execInstanceCommand(id, cm, false, c); 1423 }}); 1424 }, 1425 1426 _insertImage : function(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout) { 1427 tinyMCE.execCommand("mceInsertContent", false, tinyMCE.createTagHTML('img', { 1428 src : tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src), // Force absolute 1429 mce_src : src, 1430 alt : alt, 1431 border : border, 1432 hspace : hspace, 1433 vspace : vspace, 1434 width : width, 1435 height : height, 1436 align : align, 1437 title : title, 1438 onmouseover : onmouseover, 1439 onmouseout : onmouseout 1440 })); 1441 }, 1442 1443 _insertLink : function(href, target, title, onclick, style_class) { 1444 tinyMCE.execCommand('mceBeginUndoLevel'); 1445 1446 if (tinyMCE.selectedInstance && tinyMCE.selectedElement && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") { 1447 var doc = tinyMCE.selectedInstance.getDoc(); 1448 var linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a"); 1449 var newLink = false; 1450 1451 if (!linkElement) { 1452 linkElement = doc.createElement("a"); 1453 newLink = true; 1454 } 1455 1456 var mhref = href; 1457 var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);"); 1458 mhref = tinyMCE.getParam('convert_urls') ? href : mhref; 1459 1460 tinyMCE.setAttrib(linkElement, 'href', thref); 1461 tinyMCE.setAttrib(linkElement, 'mce_href', mhref); 1462 tinyMCE.setAttrib(linkElement, 'target', target); 1463 tinyMCE.setAttrib(linkElement, 'title', title); 1464 tinyMCE.setAttrib(linkElement, 'onclick', onclick); 1465 tinyMCE.setAttrib(linkElement, 'class', style_class); 1466 1467 if (newLink) { 1468 linkElement.appendChild(tinyMCE.selectedElement.cloneNode(true)); 1469 tinyMCE.selectedElement.parentNode.replaceChild(linkElement, tinyMCE.selectedElement); 1470 } 1471 1472 return; 1473 } 1474 1475 if (!tinyMCE.linkElement && tinyMCE.selectedInstance) { 1476 if (tinyMCE.isSafari) { 1477 tinyMCE.execCommand("mceInsertContent", false, '<a href="' + tinyMCE.uniqueURL + '">' + tinyMCE.selectedInstance.selection.getSelectedHTML() + '</a>'); 1478 } else 1479 tinyMCE.selectedInstance.contentDocument.execCommand("createlink", false, tinyMCE.uniqueURL); 1480 1481 tinyMCE.linkElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL); 1482 1483 var elementArray = tinyMCE.getElementsByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL); 1484 1485 for (var i=0; i<elementArray.length; i++) { 1486 var mhref = href; 1487 var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, elementArray[i]);"); 1488 mhref = tinyMCE.getParam('convert_urls') ? href : mhref; 1489 1490 tinyMCE.setAttrib(elementArray[i], 'href', thref); 1491 tinyMCE.setAttrib(elementArray[i], 'mce_href', mhref); 1492 tinyMCE.setAttrib(elementArray[i], 'target', target); 1493 tinyMCE.setAttrib(elementArray[i], 'title', title); 1494 tinyMCE.setAttrib(elementArray[i], 'onclick', onclick); 1495 tinyMCE.setAttrib(elementArray[i], 'class', style_class); 1496 } 1497 1498 tinyMCE.linkElement = elementArray[0]; 1499 } 1500 1501 if (tinyMCE.linkElement) { 1502 var mhref = href; 1503 href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement);"); 1504 mhref = tinyMCE.getParam('convert_urls') ? href : mhref; 1505 1506 tinyMCE.setAttrib(tinyMCE.linkElement, 'href', href); 1507 tinyMCE.setAttrib(tinyMCE.linkElement, 'mce_href', mhref); 1508 tinyMCE.setAttrib(tinyMCE.linkElement, 'target', target); 1509 tinyMCE.setAttrib(tinyMCE.linkElement, 'title', title); 1510 tinyMCE.setAttrib(tinyMCE.linkElement, 'onclick', onclick); 1511 tinyMCE.setAttrib(tinyMCE.linkElement, 'class', style_class); 1512 } 1513 1514 tinyMCE.execCommand('mceEndUndoLevel'); 1515 } 1516 }; 1517 1518 tinyMCE.addTheme("advanced", TinyMCE_AdvancedTheme); 1519 1520 // Add default buttons maps for advanced theme and all internal plugins 1521 tinyMCE.addButtonMap(TinyMCE_AdvancedTheme._buttonMap); 989 }); 990 991 tinymce.ThemeManager.add('advanced', tinymce.themes.AdvancedTheme); 992 }()); -
trunk/wp-includes/js/tinymce/themes/advanced/image.htm
r5577 r6632 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 1 2 <html xmlns="http://www.w3.org/1999/xhtml"> 2 3 <head> 3 <title>{ $lang_insert_image_title}</title>4 <script language="javascript"type="text/javascript" src="../../tiny_mce_popup.js"></script>5 <script language="javascript"type="text/javascript" src="../../utils/mctabs.js"></script>6 <script language="javascript"type="text/javascript" src="../../utils/form_utils.js"></script>7 <script language="javascript" type="text/javascript" src="jscripts/image.js"></script>4 <title>{#advanced_dlg.image_title}</title> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="../../utils/mctabs.js"></script> 7 <script type="text/javascript" src="../../utils/form_utils.js"></script> 8 <script type="text/javascript" src="js/image.js"></script> 8 9 <base target="_self" /> 9 10 </head> 10 <!-- WordPress: extra onload stuff is WP --> 11 <body id="image" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('src').focus();" style="display: none"> 12 <form onsubmit="insertImage();return false;" action="#"> 11 <body id="image" style="display: none"> 12 <form onsubmit="ImageDialog.update();return false;" action="#"> 13 13 <div class="tabs"> 14 14 <ul> 15 <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{ $lang_insert_image_title}</a></span></li>15 <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advanced_dlg.image_title}</a></span></li> 16 16 </ul> 17 17 </div> … … 21 21 <table border="0" cellpadding="4" cellspacing="0"> 22 22 <tr> 23 <td nowrap="nowrap"><label for="src">{ $lang_insert_image_src}</label></td>23 <td nowrap="nowrap"><label for="src">{#advanced_dlg.image_src}</label></td> 24 24 <td><table border="0" cellspacing="0" cellpadding="0"> 25 25 <tr> 26 <td><input id="src" name="src" type="text" value="" style="width: 200px" onchange=" getImageData();" /></td>26 <td><input id="src" name="src" type="text" value="" style="width: 200px" onchange="ImageDialog.getImageData();" /></td> 27 27 <td id="srcbrowsercontainer"> </td> 28 28 </tr> 29 29 </table></td> 30 30 </tr> 31 <!-- Image list --> 32 <script language="javascript"> 33 if (typeof(tinyMCEImageList) != "undefined" && tinyMCEImageList.length > 0) { 34 var html = ""; 35 36 html += '<tr><td><label for="image_list">{$lang_image_list}</label></td>'; 37 html += '<td><select id="image_list" name="image_list" style="width: 200px" onchange="this.form.src.value=this.options[this.selectedIndex].value;resetImageData();getImageData();">'; 38 html += '<option value="">---</option>'; 39 40 for (var i=0; i<tinyMCEImageList.length; i++) 41 html += '<option value="' + tinyMCEImageList[i][1] + '">' + tinyMCEImageList[i][0] + '</option>'; 42 43 html += '</select></td></tr>'; 44 45 document.write(html); 46 } 47 </script> 48 <!-- /Image list --> 31 <tr> 32 <td><label for="image_list">{#advanced_dlg.image_list}</label></td> 33 <td><select id="image_list" name="image_list" onchange="document.getElementById('src').value=this.options[this.selectedIndex].value;document.getElementById('alt').value=this.options[this.selectedIndex].text;"></select></td> 34 </tr> 49 35 <tr> 50 <td nowrap="nowrap"><label for="alt">{ $lang_insert_image_alt}</label></td>36 <td nowrap="nowrap"><label for="alt">{#advanced_dlg.image_alt}</label></td> 51 37 <td><input id="alt" name="alt" type="text" value="" style="width: 200px" /></td> 52 38 </tr> 53 39 <tr> 54 <td nowrap="nowrap"><label for="align">{$lang_insert_image_align}</label></td> 55 <td><select id="align" name="align"> 56 <option value="">{$lang_insert_image_align_default}</option> 57 <option value="baseline">{$lang_insert_image_align_baseline}</option> 58 <option value="top">{$lang_insert_image_align_top}</option> 59 <option value="middle">{$lang_insert_image_align_middle}</option> 60 <option value="bottom">{$lang_insert_image_align_bottom}</option> 61 <option value="texttop">{$lang_insert_image_align_texttop}</option> 62 <option value="absmiddle">{$lang_insert_image_align_absmiddle}</option> 63 <option value="absbottom">{$lang_insert_image_align_absbottom}</option> 64 <option value="left">{$lang_insert_image_align_left}</option> 65 <option value="right">{$lang_insert_image_align_right}</option> 40 <td nowrap="nowrap"><label for="align">{#advanced_dlg.image_align}</label></td> 41 <td><select id="align" name="align" onchange="ImageDialog.updateStyle();"> 42 <option value="">{#not_set}</option> 43 <option value="baseline">{#advanced_dlg.image_align_baseline}</option> 44 <option value="top">{#advanced_dlg.image_align_top}</option> 45 <option value="middle">{#advanced_dlg.image_align_middle}</option> 46 <option value="bottom">{#advanced_dlg.image_align_bottom}</option> 47 <option value="text-top">{#advanced_dlg.image_align_texttop}</option> 48 <option value="text-bottom">{#advanced_dlg.image_align_textbottom}</option> 49 <option value="left">{#advanced_dlg.image_align_left}</option> 50 <option value="right">{#advanced_dlg.image_align_right}</option> 66 51 </select></td> 67 52 </tr> 68 53 <tr> 69 <td nowrap="nowrap"><label for="width">{ $lang_insert_image_dimensions}</label></td>54 <td nowrap="nowrap"><label for="width">{#advanced_dlg.image_dimensions}</label></td> 70 55 <td><input id="width" name="width" type="text" value="" size="3" maxlength="5" /> 71 56 x … … 73 58 </tr> 74 59 <tr> 75 <td nowrap="nowrap"><label for="border">{ $lang_insert_image_border}</label></td>76 <td><input id="border" name="border" type="text" value="" size="3" maxlength="3" /></td>60 <td nowrap="nowrap"><label for="border">{#advanced_dlg.image_border}</label></td> 61 <td><input id="border" name="border" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td> 77 62 </tr> 78 63 <tr> 79 <td nowrap="nowrap"><label for="vspace">{ $lang_insert_image_vspace}</label></td>80 <td><input id="vspace" name="vspace" type="text" value="" size="3" maxlength="3" /></td>64 <td nowrap="nowrap"><label for="vspace">{#advanced_dlg.image_vspace}</label></td> 65 <td><input id="vspace" name="vspace" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td> 81 66 </tr> 82 67 <tr> 83 <td nowrap="nowrap"><label for="hspace">{ $lang_insert_image_hspace}</label></td>84 <td><input id="hspace" name="hspace" type="text" value="" size="3" maxlength="3" /></td>68 <td nowrap="nowrap"><label for="hspace">{#advanced_dlg.image_hspace}</label></td> 69 <td><input id="hspace" name="hspace" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td> 85 70 </tr> 86 71 </table> … … 89 74 90 75 <div class="mceActionPanel"> 91 <!-- WordPress: buttons reversed! -->92 76 <div style="float: left"> 93 <input type="button" id=" cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />77 <input type="button" id="insert" name="insert" value="{#insert}" onclick="ImageDialog.update();" /> 94 78 </div> 95 79 96 80 <div style="float: right"> 97 <input type=" submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertImage();" />81 <input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" /> 98 82 </div> 99 83 </div> -
trunk/wp-includes/js/tinymce/themes/advanced/langs/en.js
r5577 r6632 1 // UK lang variables 2 3 tinyMCE.addToLang('',{ 4 theme_style_select : '-- Styles --', 5 theme_code_desc : 'Edit HTML Source', 6 theme_code_title : 'HTML Source Editor', 7 theme_code_wordwrap : 'Word wrap', 8 theme_sub_desc : 'Subscript', 9 theme_sup_desc : 'Superscript', 10 theme_hr_desc : 'Insert horizontal ruler', 11 theme_removeformat_desc : 'Remove formatting', 12 theme_custom1_desc : 'Your custom description here', 13 insert_image_border : 'Border', 14 insert_image_dimensions : 'Dimensions', 15 insert_image_vspace : 'Vertical space', 16 insert_image_hspace : 'Horizontal space', 17 insert_image_align : 'Alignment', 18 insert_image_align_default : '-- Not set --', 19 insert_image_align_baseline : 'Baseline', 20 insert_image_align_top : 'Top', 21 insert_image_align_middle : 'Middle', 22 insert_image_align_bottom : 'Bottom', 23 insert_image_align_texttop : 'TextTop', 24 insert_image_align_absmiddle : 'Absolute Middle', 25 insert_image_align_absbottom : 'Absolute Bottom', 26 insert_image_align_left : 'Left', 27 insert_image_align_right : 'Right', 28 theme_font_size : '-- Font size --', 29 theme_fontdefault : '-- Font family --', 30 theme_block : '-- Format --', 31 theme_paragraph : 'Paragraph', 32 theme_div : 'Div', 33 theme_address : 'Address', 34 theme_pre : 'Preformatted', 35 theme_h1 : 'Heading 1', 36 theme_h2 : 'Heading 2', 37 theme_h3 : 'Heading 3', 38 theme_h4 : 'Heading 4', 39 theme_h5 : 'Heading 5', 40 theme_h6 : 'Heading 6', 41 theme_blockquote : 'Blockquote', 42 theme_code : 'Code', 43 theme_samp : 'Code sample', 44 theme_dt : 'Definition term ', 45 theme_dd : 'Definition description', 46 theme_colorpicker_title : 'Select a color', 47 theme_colorpicker_apply : 'Apply', 48 theme_forecolor_desc : 'Select text color', 49 theme_backcolor_desc : 'Select background color', 50 theme_charmap_title : 'Select custom character', 51 theme_charmap_desc : 'Insert custom character', 52 theme_visualaid_desc : 'Toggle guidelines/invisible elements', 53 insert_anchor_title : 'Insert/edit anchor', 54 insert_anchor_name : 'Anchor name', 55 theme_anchor_desc : 'Insert/edit anchor', 56 theme_insert_link_titlefield : 'Title', 57 theme_clipboard_msg : 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?', 58 theme_path : 'Path', 59 cut_desc : 'Cut', 60 copy_desc : 'Copy', 61 paste_desc : 'Paste', 62 link_list : 'Link list', 63 image_list : 'Image list', 64 browse : 'Browse', 65 image_props_desc : 'Image properties', 66 newdocument_desc : 'New document', 67 class_name : 'Class', 68 newdocument : 'Are you sure you want clear all contents?', 69 about_title : 'About TinyMCE', 70 about : 'About', 71 license : 'License', 72 plugins : 'Plugins', 73 plugin : 'Plugin', 74 author : 'Author', 75 version : 'Version', 76 loaded_plugins : 'Loaded plugins', 77 help : 'Help', 78 not_set : '-- Not set --', 79 close : 'Close', 80 toolbar_focus : 'Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X', 81 invalid_data : 'Error: Invalid values entered, these are marked in red.', 82 more_colors : 'More colors', 83 color_picker_tab : 'Picker', 84 color_picker : 'Color picker', 85 web_colors_tab : 'Palette', 86 web_colors : 'Palette colors', 87 named_colors_tab : 'Named', 88 named_colors : 'Named colors', 89 color : 'Color:', 90 color_name : 'Name:', 91 is_email : 'The URL you entered seems to be an email address, do you want to add the required mailto: prefix?', 92 is_external : 'The URL you entered seems to external link, do you want to add the required http:// prefix?' 1 tinyMCE.addI18n('en.advanced',{ 2 style_select:"Styles", 3 font_size:"Font size", 4 fontdefault:"Font family", 5 block:"Format", 6 paragraph:"Paragraph", 7 div:"Div", 8 address:"Address", 9 pre:"Preformatted", 10 h1:"Heading 1", 11 h2:"Heading 2", 12 h3:"Heading 3", 13 h4:"Heading 4", 14 h5:"Heading 5", 15 h6:"Heading 6", 16 blockquote:"Blockquote", 17 code:"Code", 18 samp:"Code sample", 19 dt:"Definition term ", 20 dd:"Definition description", 21 bold_desc:"Bold (Ctrl+B)", 22 italic_desc:"Italic (Ctrl+I)", 23 underline_desc:"Underline (Ctrl+U)", 24 striketrough_desc:"Strikethrough", 25 justifyleft_desc:"Align left", 26 justifycenter_desc:"Align center", 27 justifyright_desc:"Align right", 28 justifyfull_desc:"Align full", 29 bullist_desc:"Unordered list", 30 numlist_desc:"Ordered list", 31 outdent_desc:"Outdent", 32 indent_desc:"Indent", 33 undo_desc:"Undo (Ctrl+Z)", 34 redo_desc:"Redo (Ctrl+Y)", 35 link_desc:"Insert/edit link", 36 unlink_desc:"Unlink", 37 image_desc:"Insert/edit image", 38 cleanup_desc:"Cleanup messy code", 39 code_desc:"Edit HTML Source", 40 sub_desc:"Subscript", 41 sup_desc:"Superscript", 42 hr_desc:"Insert horizontal ruler", 43 removeformat_desc:"Remove formatting", 44 custom1_desc:"Your custom description here", 45 forecolor_desc:"Select text color", 46 backcolor_desc:"Select background color", 47 charmap_desc:"Insert custom character", 48 visualaid_desc:"Toggle guidelines/invisible elements", 49 anchor_desc:"Insert/edit anchor", 50 cut_desc:"Cut", 51 copy_desc:"Copy", 52 paste_desc:"Paste", 53 image_props_desc:"Image properties", 54 newdocument_desc:"New document", 55 help_desc:"Help", 56 blockquote_desc:"Blockquote", 57 clipboard_msg:"Copy/Cut/Paste is not available in Mozilla and Firefox.\r\nDo you want more information about this issue?", 58 path:"Path", 59 newdocument:"Are you sure you want clear all contents?", 60 toolbar_focus:"Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X", 61 more_colors:"More colors" 93 62 }); -
trunk/wp-includes/js/tinymce/themes/advanced/link.htm
r5577 r6632 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 1 2 <html xmlns="http://www.w3.org/1999/xhtml"> 2 3 <head> 3 <title>{ $lang_insert_link_title}</title>4 <script language="javascript"type="text/javascript" src="../../tiny_mce_popup.js"></script>5 <script language="javascript"type="text/javascript" src="../../utils/mctabs.js"></script>6 <script language="javascript"type="text/javascript" src="../../utils/form_utils.js"></script>7 <script language="javascript"type="text/javascript" src="../../utils/validate.js"></script>8 <script language="javascript" type="text/javascript" src="jscripts/link.js"></script>4 <title>{#advanced_dlg.link_title}</title> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="../../utils/mctabs.js"></script> 7 <script type="text/javascript" src="../../utils/form_utils.js"></script> 8 <script type="text/javascript" src="../../utils/validate.js"></script> 9 <script type="text/javascript" src="js/link.js"></script> 9 10 <base target="_self" /> 10 11 </head> 11 <!-- WordPress: onload after the init();'); --> 12 <body id="link" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('href').focus();" style="display: none"> 13 <form onsubmit="insertLink();return false;" action="#"> 12 <body id="link" style="display: none"> 13 <form onsubmit="LinkDialog.update();return false;" action="#"> 14 14 <div class="tabs"> 15 15 <ul> 16 <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{ $lang_insert_link_title}</a></span></li>16 <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advanced_dlg.link_title}</a></span></li> 17 17 </ul> 18 18 </div> … … 23 23 <table border="0" cellpadding="4" cellspacing="0"> 24 24 <tr> 25 <td nowrap="nowrap"><label for="href">{ $lang_insert_link_url}</label></td>25 <td nowrap="nowrap"><label for="href">{#advanced_dlg.link_url}</label></td> 26 26 <td><table border="0" cellspacing="0" cellpadding="0"> 27 27 <tr> 28 <td><input id="href" name="href" type="text" value="" style="width: 200px" onchange=" checkPrefix(this);" /></td>28 <td><input id="href" name="href" type="text" value="" style="width: 200px" onchange="LinkDialog.checkPrefix(this);" /></td> 29 29 <td id="hrefbrowsercontainer"> </td> 30 30 </tr> 31 31 </table></td> 32 32 </tr> 33 <!-- Link list --> 34 <script language="javascript"> 35 if (typeof(tinyMCELinkList) != "undefined" && tinyMCELinkList.length > 0) { 36 var html = ""; 37 38 html += '<tr><td><label for="link_list">{$lang_link_list}</label></td>'; 39 html += '<td><select id="link_list" name="link_list" style="width: 200px" onchange="this.form.href.value=this.options[this.selectedIndex].value;">'; 40 html += '<option value="">---</option>'; 41 42 for (var i=0; i<tinyMCELinkList.length; i++) 43 html += '<option value="' + tinyMCELinkList[i][1] + '">' + tinyMCELinkList[i][0] + '</option>'; 44 45 html += '</select></td></tr>'; 46 47 document.write(html); 48 } 49 </script> 50 <!-- /Link list --> 33 <tr> 34 <td><label for="link_list">{#advanced_dlg.link_list}</label></td> 35 <td><select id="link_list" name="link_list" onchange="document.getElementById('href').value=this.options[this.selectedIndex].value;"></select></td> 36 </tr> 37 <tr> 38 <td><label id="targetlistlabel" for="targetlist">{#advanced_dlg.link_target}</label></td> 39 <td><select id="target_list" name="target_list"></select></td> 40 </tr> 51 41 <tr> 52 <td nowrap="nowrap"><label for="target">{$lang_insert_link_target}</label></td> 53 <td><select id="target" name="target" style="width: 200px"> 54 <option value="_self">{$lang_insert_link_target_same}</option> 55 <option value="_blank">{$lang_insert_link_target_blank}</option> 56 <script language="javascript"> 57 var html = ""; 58 var targets = tinyMCE.getParam('theme_advanced_link_targets', '').split(';'); 59 60 for (var i=0; i<targets.length; i++) { 61 var key, value; 62 63 if (targets[i] == "") 64 continue; 65 66 key = targets[i].split('=')[0]; 67 value = targets[i].split('=')[1]; 68 69 html += '<option value="' + value + '">' + key + '</option>'; 70 } 71 72 document.write(html); 73 </script> 74 </select></td> 42 <td nowrap="nowrap"><label for="linktitle">{#advanced_dlg.link_titlefield}</label></td> 43 <td><input id="linktitle" name="linktitle" type="text" value="" style="width: 200px" /></td> 75 44 </tr> 76 <tr> 77 <td nowrap="nowrap"><label for="linktitle">{$lang_theme_insert_link_titlefield}</label></td> 78 <td><input id="linktitle" name="linktitle" type="text" value="" style="width: 200px"></td> 79 </tr> 80 <tr id="styleSelectRow"> 81 <td><label for="styleSelect">{$lang_class_name}</label></td> 82 <td> 83 <select id="styleSelect" name="styleSelect"> 84 <option value="" selected>{$lang_theme_style_select}</option> 85 </select></td> 86 </tr> 45 <tr> 46 <td><label for="class_list">{#class_name}</label></td> 47 <td><select id="class_list" name="class_list"></select></td> 48 </tr> 87 49 </table> 88 50 </div> … … 90 52 91 53 <div class="mceActionPanel"> 92 <!-- WordPress: Buttons are reversed! -->93 54 <div style="float: left"> 94 <input type="button" id=" cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />55 <input type="button" id="insert" name="insert" value="{#insert}" onclick="LinkDialog.update();" /> 95 56 </div> 96 57 97 58 <div style="float: right"> 98 <input type=" submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertLink();" />59 <input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" /> 99 60 </div> 100 61 </div> -
trunk/wp-includes/js/tinymce/themes/advanced/source_editor.htm
r5577 r6632 2 2 <head> 3 3 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 4 <title>{ $lang_theme_code_title}</title>5 <script language="javascript"type="text/javascript" src="../../tiny_mce_popup.js"></script>6 <script language="javascript" type="text/javascript" src="jscripts/source_editor.js"></script>4 <title>{#advanced_dlg.code_title}</title> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 6 <script type="text/javascript" src="js/source_editor.js"></script> 7 7 <base target="_self" /> 8 8 </head> 9 <!-- WordPress: extra onload stuff is WP! --> 10 <body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');document.body.style.display='';document.getElementById('htmlSource').focus();" onresize="resizeInputs();" style="display: none"> 9 <body onresize="resizeInputs();" style="display:none; overflow:hidden;"> 11 10 <form name="source" onsubmit="saveContent();" action="#"> 12 <div style="float: left" class="title">{ $lang_theme_code_title}</div>11 <div style="float: left" class="title">{#advanced_dlg.code_title}</div> 13 12 14 13 <div id="wrapline" style="float: right"> 15 <input type="checkbox" name="wraped" id="wraped" onclick="toggleWordWrap(this);" class="wordWrapCode" /><label for="wraped">{ $lang_theme_code_wordwrap}</label>14 <input type="checkbox" name="wraped" id="wraped" onclick="toggleWordWrap(this);" class="wordWrapCode" /><label for="wraped">{#advanced_dlg.code_wordwrap}</label> 16 15 </div> 17 16 18 17 <br style="clear: both" /> 19 18 20 <textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,monospace; font-size: 12px " dir="ltr" wrap="off"></textarea>19 <textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,monospace; font-size: 12px;" dir="ltr" wrap="off"></textarea> 21 20 22 21 <div class="mceActionPanel"> 23 <!-- WordPress: reversed buttons! -->24 22 <div style="float: left"> 25 <input type="button" name=" cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />23 <input type="button" name="insert" value="{#update}" onclick="saveContent();" id="insert" /> 26 24 </div> 27 25 28 26 <div style="float: right"> 29 <input type=" submit" name="insert" value="{$lang_update}" onclick="saveContent();" id="insert" />27 <input type="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" /> 30 28 </div> 31 29 </div> -
trunk/wp-includes/js/tinymce/tiny_mce.js
r6568 r6632 1 1 2 /* file:jscripts/tiny_mce/classes/TinyMCE_Engine.class.js */ 3 4 function TinyMCE_Engine() { 5 var ua; 6 7 this.majorVersion = "2"; 8 this.minorVersion = "1.1.1"; 9 this.releaseDate = "2007-05-14"; 10 11 this.instances = []; 12 this.switchClassCache = []; 13 this.windowArgs = []; 14 this.loadedFiles = []; 15 this.pendingFiles = []; 16 this.loadingIndex = 0; 17 this.configs = []; 18 this.currentConfig = 0; 19 this.eventHandlers = []; 20 this.log = []; 21 this.undoLevels = []; 22 this.undoIndex = 0; 23 this.typingUndoIndex = -1; 24 this.settings = []; 25 26 // Browser check 27 ua = navigator.userAgent; 28 this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); 29 this.isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1); 30 this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1); 31 this.isMSIE7 = this.isMSIE && (ua.indexOf('MSIE 7') != -1); 32 this.isGecko = ua.indexOf('Gecko') != -1; // Will also be true on Safari 33 this.isSafari = ua.indexOf('Safari') != -1; 34 this.isOpera = window['opera'] && opera.buildNumber ? true : false; 35 this.isMac = ua.indexOf('Mac') != -1; 36 this.isNS7 = ua.indexOf('Netscape/7') != -1; 37 this.isNS71 = ua.indexOf('Netscape/7.1') != -1; 38 this.dialogCounter = 0; 39 this.plugins = []; 40 this.themes = []; 41 this.menus = []; 42 this.loadedPlugins = []; 43 this.buttonMap = []; 44 this.isLoaded = false; 45 46 // Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those 47 if (this.isOpera) { 48 this.isMSIE = true; 49 this.isGecko = false; 50 this.isSafari = false; 51 } 52 53 this.isIE = this.isMSIE; 54 this.isRealIE = this.isMSIE && !this.isOpera; 55 56 // TinyMCE editor id instance counter 57 this.idCounter = 0; 58 }; 59 60 TinyMCE_Engine.prototype = { 61 init : function(settings) { 62 var theme, nl, baseHREF = "", i, cssPath, entities, h, p, src, elements = [], head; 63 64 // IE 5.0x is no longer supported since 5.5, 6.0 and 7.0 now exists. We can't support old browsers forever, sorry. 65 if (this.isMSIE5_0) 2 /* file:jscripts/tiny_mce/classes/tinymce.js */ 3 4 var tinymce = { 5 majorVersion : '3', 6 minorVersion : '0rc2', 7 releaseDate : '2008-01-xx', 8 9 _init : function() { 10 var t = this, ua = navigator.userAgent, i, nl, n, base; 11 12 // Browser checks 13 t.isOpera = window.opera && opera.buildNumber; 14 t.isWebKit = /WebKit/.test(ua); 15 t.isOldWebKit = t.isWebKit && !window.getSelection().getRangeAt; 16 t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(navigator.appName); 17 t.isIE6 = t.isIE && /MSIE [56]/.test(ua); 18 t.isGecko = !t.isWebKit && /Gecko/.test(ua); 19 // t.isGecko3 = t.isGecko && /(Firefox|Minefield)\/[3-9]/.test(ua); 20 t.isMac = ua.indexOf('Mac') != -1; 21 22 // TinyMCE .NET webcontrol might be setting the values for TinyMCE 23 if (window.tinyMCEPreInit) { 24 t.suffix = tinyMCEPreInit.suffix; 25 t.baseURL = tinyMCEPreInit.base; 66 26 return; 67 68 this.settings = settings; 69 70 // Check if valid browser has execcommand support 71 if (typeof(document.execCommand) == 'undefined') 27 } 28 29 // Get suffix and base 30 t.suffix = ''; 31 32 // If base element found, add that infront of baseURL 33 nl = document.getElementsByTagName('base'); 34 for (i=0; i<nl.length; i++) { 35 if (nl[i].href) 36 base = nl[i].href; 37 } 38 39 function getBase(n) { 40 if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) { 41 if (/_(src|dev)\.js/g.test(n.src)) 42 t.suffix = '_src'; 43 44 t.baseURL = n.src.substring(0, n.src.lastIndexOf('/')); 45 46 // If path to script is relative and a base href was found add that one infront 47 if (base && t.baseURL.indexOf('://') == -1) 48 t.baseURL = base + t.baseURL; 49 50 return t.baseURL; 51 } 52 53 return null; 54 }; 55 56 // Check document 57 nl = document.getElementsByTagName('script'); 58 for (i=0; i<nl.length; i++) { 59 if (getBase(nl[i])) 60 return; 61 } 62 63 // Check head 64 n = document.getElementsByTagName('head')[0]; 65 if (n) { 66 nl = n.getElementsByTagName('script'); 67 for (i=0; i<nl.length; i++) { 68 if (getBase(nl[i])) 69 return; 70 } 71 } 72 73 return; 74 }, 75 76 is : function(o, t) { 77 var n = typeof(o); 78 79 if (!t) 80 return n != 'undefined'; 81 82 if (t == 'array' && (o instanceof Array)) 83 return true; 84 85 return n == t; 86 }, 87 88 // #if !jquery 89 90 each : function(o, cb, s) { 91 var n, l; 92 93 if (!o) 94 return 0; 95 96 s = s || o; 97 98 if (typeof(o.length) != 'undefined') { 99 // Indexed arrays, needed for Safari 100 for (n=0, l = o.length; n<l; n++) { 101 if (cb.call(s, o[n], n, o) === false) 102 return 0; 103 } 104 } else { 105 // Hashtables 106 for (n in o) { 107 if (o.hasOwnProperty(n)) { 108 if (cb.call(s, o[n], n, o) === false) 109 return 0; 110 } 111 } 112 } 113 114 return 1; 115 }, 116 117 map : function(a, f) { 118 var o = []; 119 120 tinymce.each(a, function(v) { 121 o.push(f(v)); 122 }); 123 124 return o; 125 }, 126 127 grep : function(a, f) { 128 var o = []; 129 130 tinymce.each(a, function(v) { 131 if (!f || f(v)) 132 o.push(v); 133 }); 134 135 return o; 136 }, 137 138 inArray : function(a, v) { 139 var i, l; 140 141 if (a) { 142 for (i = 0, l = a.length; i < l; i++) { 143 if (a[i] === v) 144 return i; 145 } 146 } 147 148 return -1; 149 }, 150 151 extend : function(o, e) { 152 var i, a = arguments; 153 154 for (i=1; i<a.length; i++) { 155 e = a[i]; 156 157 tinymce.each(e, function(v, n) { 158 if (typeof(v) !== 'undefined') 159 o[n] = v; 160 }); 161 } 162 163 return o; 164 }, 165 166 trim : function(s) { 167 return (s ? '' + s : '').replace(/^\s*|\s*$/g, ''); 168 }, 169 170 // #endif 171 172 create : function(s, p) { 173 var t = this, sp, ns, cn, scn, c, de = 0; 174 175 // Parse : <prefix> <class>:<super class> 176 s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s); 177 cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name 178 179 // Create namespace for new class 180 ns = t.createNS(s[3].replace(/\.\w+$/, '')); 181 182 // Class already exists 183 if (ns[cn]) 72 184 return; 73 185 74 // Get script base path 75 if (!tinyMCE.baseURL) { 76 // Search through head 77 head = document.getElementsByTagName('head')[0]; 78 79 if (head) { 80 for (i=0, nl = head.getElementsByTagName('script'); i<nl.length; i++) 81 elements.push(nl[i]); 82 } 83 84 // Search through rest of document 85 for (i=0, nl = document.getElementsByTagName('script'); i<nl.length; i++) 86 elements.push(nl[i]); 87 88 // If base element found, add that infront of baseURL 89 nl = document.getElementsByTagName('base'); 90 for (i=0; i<nl.length; i++) { 91 if (nl[i].href) 92 baseHREF = nl[i].href; 93 } 94 95 for (i=0; i<elements.length; i++) { 96 if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_dev.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip") != -1)) { 97 src = elements[i].src; 98 99 tinyMCE.srcMode = (src.indexOf('_src') != -1 || src.indexOf('_dev') != -1) ? '_src' : ''; 100 tinyMCE.gzipMode = src.indexOf('_gzip') != -1; 101 src = src.substring(0, src.lastIndexOf('/')); 102 103 if (settings.exec_mode == "src" || settings.exec_mode == "normal") 104 tinyMCE.srcMode = settings.exec_mode == "src" ? '_src' : ''; 105 106 // Force it absolute if page has a base href 107 if (baseHREF !== '' && src.indexOf('://') == -1) 108 tinyMCE.baseURL = baseHREF + src; 109 else 110 tinyMCE.baseURL = src; 111 112 break; 113 } 114 } 186 // Make pure static class 187 if (s[2] == 'static') { 188 ns[cn] = p; 189 190 if (this.onCreate) 191 this.onCreate(s[2], s[3], ns[cn]); 192 193 return; 115 194 } 116 195 117 // Get document base path 118 this.documentBasePath = document.location.href; 119 if (this.documentBasePath.indexOf('?') != -1) 120 this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.indexOf('?')); 121 this.documentURL = this.documentBasePath; 122 this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.lastIndexOf('/')); 123 124 // If not HTTP absolute 125 if (tinyMCE.baseURL.indexOf('://') == -1 && tinyMCE.baseURL.charAt(0) != '/') { 126 // If site absolute 127 tinyMCE.baseURL = this.documentBasePath + "/" + tinyMCE.baseURL; 196 // Create default constructor 197 if (!p[cn]) { 198 p[cn] = function() {}; 199 de = 1; 128 200 } 129 201 130 // Set default values on settings 131 this._def("mode", "none"); 132 this._def("theme", "advanced"); 133 this._def("plugins", "", true); 134 this._def("language", "en"); 135 this._def("docs_language", this.settings.language); 136 this._def("elements", ""); 137 this._def("textarea_trigger", "mce_editable"); 138 this._def("editor_selector", ""); 139 this._def("editor_deselector", "mceNoEditor"); 140 this._def("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[id|style|dir|class|align],-h2[id|style|dir|class|align],-h3[id|style|dir|class|align],-h4[id|style|dir|class|align],-h5[id|style|dir|class|align],-h6[id|style|dir|class|align],hr[class|style],-font[face|size|style|id|class|dir|color],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],cite[title|id|class|style|dir|lang],abbr[title|id|class|style|dir|lang],acronym[title|id|class|style|dir|lang],del[title|id|class|style|dir|lang|datetime|cite],ins[title|id|class|style|dir|lang|datetime|cite]"); 141 this._def("extended_valid_elements", ""); 142 this._def("invalid_elements", ""); 143 this._def("encoding", ""); 144 this._def("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE_Engine.prototype.convertURL")); 145 this._def("save_callback", ""); 146 this._def("force_br_newlines", false); 147 this._def("force_p_newlines", true); 148 this._def("add_form_submit_trigger", true); 149 this._def("relative_urls", true); 150 this._def("remove_script_host", true); 151 this._def("focus_alert", true); 152 this._def("document_base_url", this.documentURL); 153 this._def("visual", true); 154 this._def("visual_table_class", "mceVisualAid"); 155 this._def("setupcontent_callback", ""); 156 this._def("fix_content_duplication", true); 157 this._def("custom_undo_redo", true); 158 this._def("custom_undo_redo_levels", -1); 159 this._def("custom_undo_redo_keyboard_shortcuts", true); 160 this._def("custom_undo_redo_restore_selection", true); 161 this._def("custom_undo_redo_global", false); 162 this._def("verify_html", true); 163 this._def("apply_source_formatting", false); 164 this._def("directionality", "ltr"); 165 this._def("cleanup_on_startup", false); 166 this._def("inline_styles", false); 167 this._def("convert_newlines_to_brs", false); 168 this._def("auto_reset_designmode", true); 169 this._def("entities", "39,#39,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,34,quot,38,amp,60,lt,62,gt,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", true); 170 this._def("entity_encoding", "named"); 171 this._def("cleanup_callback", ""); 172 this._def("add_unload_trigger", true); 173 this._def("ask", false); 174 this._def("nowrap", false); 175 this._def("auto_resize", false); 176 this._def("auto_focus", false); 177 this._def("cleanup", true); 178 this._def("remove_linebreaks", true); 179 this._def("button_tile_map", false); 180 this._def("submit_patch", true); 181 this._def("browsers", "msie,safari,gecko,opera", true); 182 this._def("dialog_type", "window"); 183 this._def("accessibility_warnings", true); 184 this._def("accessibility_focus", true); 185 this._def("merge_styles_invalid_parents", ""); 186 this._def("force_hex_style_colors", true); 187 this._def("trim_span_elements", true); 188 this._def("convert_fonts_to_spans", false); 189 this._def("doctype", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'); 190 this._def("font_size_classes", ''); 191 this._def("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large', true); 192 this._def("event_elements", 'a,img', true); 193 this._def("convert_urls", true); 194 this._def("table_inline_editing", false); 195 this._def("object_resizing", true); 196 this._def("custom_shortcuts", true); 197 this._def("convert_on_click", false); 198 this._def("content_css", ''); 199 this._def("fix_list_elements", true); 200 this._def("fix_table_elements", false); 201 this._def("strict_loading_mode", document.contentType == 'application/xhtml+xml'); 202 this._def("hidden_tab_class", ''); 203 this._def("display_tab_class", ''); 204 this._def("gecko_spellcheck", false); 205 this._def("hide_selects_on_submit", true); 206 this._def("forced_root_block", false); 207 this._def("remove_trailing_nbsp", false); 208 209 // Force strict loading mode to false on non Gecko browsers 210 if (this.isMSIE && !this.isOpera) 211 this.settings.strict_loading_mode = false; 212 213 // Browser check IE 214 if (this.isMSIE && this.settings.browsers.indexOf('msie') == -1) 215 return; 216 217 // Browser check Gecko 218 if (this.isGecko && this.settings.browsers.indexOf('gecko') == -1) 219 return; 220 221 // Browser check Safari 222 if (this.isSafari && this.settings.browsers.indexOf('safari') == -1) 223 return; 224 225 // Browser check Opera 226 if (this.isOpera && this.settings.browsers.indexOf('opera') == -1) 227 return; 228 229 // If not super absolute make it so 230 baseHREF = tinyMCE.settings.document_base_url; 231 h = document.location.href; 232 p = h.indexOf('://'); 233 if (p > 0 && document.location.protocol != "file:") { 234 p = h.indexOf('/', p + 3); 235 h = h.substring(0, p); 236 237 if (baseHREF.indexOf('://') == -1) 238 baseHREF = h + baseHREF; 239 240 tinyMCE.settings.document_base_url = baseHREF; 241 tinyMCE.settings.document_base_prefix = h; 202 // Add constructor and methods 203 ns[cn] = p[cn]; 204 t.extend(ns[cn].prototype, p); 205 206 // Extend 207 if (s[5]) { 208 sp = t.resolve(s[5]).prototype; 209 scn = s[5].match(/\.(\w+)$/i)[1]; // Class name 210 211 // Extend constructor 212 c = ns[cn]; 213 if (de) { 214 // Add passthrough constructor 215 ns[cn] = function() { 216 return sp[scn].apply(this, arguments); 217 }; 218 } else { 219 // Add inherit constructor 220 ns[cn] = function() { 221 this.parent = sp[scn]; 222 return c.apply(this, arguments); 223 }; 224 } 225 ns[cn].prototype[cn] = ns[cn]; 226 227 // Add super methods 228 t.each(sp, function(f, n) { 229 if (n != scn) 230 ns[cn].prototype[n] = sp[n]; 231 }); 232 233 // Add overridden methods 234 t.each(p, function(f, n) { 235 // Extend methods if needed 236 if (sp[n]) { 237 ns[cn].prototype[n] = function() { 238 this.parent = sp[n]; 239 return f.apply(this, arguments); 240 }; 241 } else { 242 if (n != cn) 243 ns[cn].prototype[n] = f; 244 } 245 }); 242 246 } 243 247 244 // Trim away query part 245 if (baseHREF.indexOf('?') != -1) 246 baseHREF = baseHREF.substring(0, baseHREF.indexOf('?')); 247 248 this.settings.base_href = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/"; 249 250 theme = this.settings.theme; 251 this.inlineStrict = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment'; 252 this.inlineTransitional = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment'; 253 this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP'; 254 this.blockRegExp = new RegExp("^(" + this.blockElms + ")$", "i"); 255 this.posKeyCodes = [13,45,36,35,33,34,37,38,39,40]; 256 this.uniqueURL = 'javascript:void(091039730);'; // Make unique URL non real URL 257 this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>'; 258 this.callbacks = ['onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance']; 259 260 // Theme url 261 this.settings.theme_href = tinyMCE.baseURL + "/themes/" + theme; 262 263 if (!tinyMCE.isIE || tinyMCE.isOpera) 264 this.settings.force_br_newlines = false; 265 266 if (tinyMCE.getParam("popups_css", false)) { 267 cssPath = tinyMCE.getParam("popups_css", ""); 268 269 // Is relative 270 if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/') 271 this.settings.popups_css = this.documentBasePath + "/" + cssPath; 272 else 273 this.settings.popups_css = cssPath; 274 } else 275 this.settings.popups_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css"; 276 277 if (tinyMCE.getParam("editor_css", false)) { 278 cssPath = tinyMCE.getParam("editor_css", ""); 279 280 // Is relative 281 if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/') 282 this.settings.editor_css = this.documentBasePath + "/" + cssPath; 283 else 284 this.settings.editor_css = cssPath; 285 } else { 286 if (this.settings.editor_css !== '') 287 this.settings.editor_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css"; 288 } 289 290 // Only do this once 291 if (this.configs.length == 0) { 292 if (typeof(TinyMCECompressed) == "undefined") { 293 tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCE_Engine.prototype.onLoad); 294 295 if (tinyMCE.isRealIE) { 296 if (document.body) 297 tinyMCE.addEvent(document.body, "readystatechange", TinyMCE_Engine.prototype.onLoad); 298 else 299 tinyMCE.addEvent(document, "readystatechange", TinyMCE_Engine.prototype.onLoad); 300 } 301 302 tinyMCE.addEvent(window, "load", TinyMCE_Engine.prototype.onLoad); 303 tinyMCE._addUnloadEvents(); 304 } 305 } 306 307 this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings.theme + '/editor_template' + tinyMCE.srcMode + '.js'); 308 this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings.language + '.js'); 309 this.loadCSS(this.settings.editor_css); 310 311 // Add plugins 312 p = tinyMCE.getParam('plugins', '', true, ','); 313 if (p.length > 0) { 314 for (i=0; i<p.length; i++) { 315 if (p[i].charAt(0) != '-') 316 this.loadScript(tinyMCE.baseURL + '/plugins/' + p[i] + '/editor_plugin' + tinyMCE.srcMode + '.js'); 317 } 318 } 319 320 // Setup entities 321 if (tinyMCE.getParam('entity_encoding') == 'named') { 322 settings.cleanup_entities = []; 323 entities = tinyMCE.getParam('entities', '', true, ','); 324 for (i=0; i<entities.length; i+=2) 325 settings.cleanup_entities['c' + entities[i]] = entities[i+1]; 326 } 327 328 // Save away this config 329 settings.index = this.configs.length; 330 this.configs[this.configs.length] = settings; 331 332 // Start loading first one in chain 333 this.loadNextScript(); 334 335 // Force flicker free CSS backgrounds in IE 336 if (this.isIE && !this.isOpera) { 337 try { 338 document.execCommand('BackgroundImageCache', false, true); 339 } catch (e) { 340 // Ignore 341 } 342 } 343 344 // Setup XML encoding regexps 345 this.xmlEncodeRe = new RegExp('[<>&"]', 'g'); 248 // Add static methods 249 t.each(p['static'], function(f, n) { 250 ns[cn][n] = f; 251 }); 252 253 if (this.onCreate) 254 this.onCreate(s[2], s[3], ns[cn].prototype); 346 255 }, 347 256 348 _addUnloadEvents : function() { 349 var st = tinyMCE.settings.add_unload_trigger; 350 351 if (tinyMCE.isIE) { 352 if (st) { 353 tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler); 354 tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler); 355 } 356 } else { 357 if (st) 358 tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);}); 257 walk : function(o, f, n, s) { 258 s = s || this; 259 260 if (o) { 261 if (n) 262 o = o[n]; 263 264 tinymce.each(o, function(o, i) { 265 if (f.call(s, o, i, n) === false) 266 return false; 267 268 tinymce.walk(o, f, n, s); 269 }); 359 270 } 360 271 }, 361 272 362 _def : function(key, def_val, t) { 363 var v = tinyMCE.getParam(key, def_val); 364 365 v = t ? v.replace(/\s+/g, "") : v; 366 367 this.settings[key] = v; 273 createNS : function(n, o) { 274 var i, v; 275 276 o = o || window; 277 278 n = n.split('.'); 279 for (i=0; i<n.length; i++) { 280 v = n[i]; 281 282 if (!o[v]) 283 o[v] = {}; 284 285 o = o[v]; 286 } 287 288 return o; 368 289 }, 369 290 370 hasPlugin : function(n) { 371 return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; 291 resolve : function(n, o) { 292 var i, l; 293 294 o = o || window; 295 296 n = n.split('.'); 297 for (i=0, l = n.length; i<l; i++) { 298 o = o[n[i]]; 299 300 if (!o) 301 break; 302 } 303 304 return o; 372 305 }, 373 306 374 addPlugin : function(n, p) { 375 var op = this.plugins[n]; 376 377 // Use the previous plugin object base URL used when loading external plugins 378 p.baseURL = op ? op.baseURL : tinyMCE.baseURL + "/plugins/" + n; 379 this.plugins[n] = p; 380 381 this.loadNextScript(); 307 addUnload : function(f, s) { 308 var t = this, w = window, unload; 309 310 f = {func : f, scope : s || this}; 311 312 if (!t.unloads) { 313 unload = function() { 314 var li = t.unloads, o, n; 315 316 // Call unload handlers 317 for (n in li) { 318 o = li[n]; 319 320 if (o && o.func) 321 o.func.call(o.scope); 322 } 323 324 // Detach unload function 325 if (w.detachEvent) 326 w.detachEvent('onunload', unload); 327 else if (w.removeEventListener) 328 w.removeEventListener('unload', unload, false); 329 330 // Destroy references 331 o = li = w = unload = null; 332 333 // Run garbarge collector on IE 334 if (window.CollectGarbage) 335 window.CollectGarbage(); 336 }; 337 338 // Attach unload handler 339 if (w.attachEvent) 340 w.attachEvent('onunload', unload); 341 else if (w.addEventListener) 342 w.addEventListener('unload', unload, false); 343 344 // Setup initial unload handler array 345 t.unloads = [f]; 346 } else 347 t.unloads.push(f); 348 349 return f; 382 350 }, 383 351 384 setPluginBaseURL : function(n, u) { 385 var op = this.plugins[n]; 386 387 if (op) 388 op.baseURL = u; 389 else 390 this.plugins[n] = {baseURL : u}; 352 removeUnload : function(f) { 353 var u = this.unloads, r = null; 354 355 tinymce.each(u, function(o, i) { 356 if (o && o.func == f) { 357 u.splice(i, 1); 358 r = f; 359 return false; 360 } 361 }); 362 363 return r; 364 } 365 366 }; 367 368 // Required for GZip AJAX loading 369 window.tinymce = tinymce; 370 371 // Initialize the API 372 tinymce._init(); 373 374 /* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */ 375 376 377 /* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */ 378 379 380 /* file:jscripts/tiny_mce/classes/util/Dispatcher.js */ 381 382 tinymce.create('tinymce.util.Dispatcher', { 383 scope : null, 384 listeners : null, 385 386 Dispatcher : function(s) { 387 this.scope = s || this; 388 this.listeners = []; 391 389 }, 392 390 393 loadPlugin : function(n, u) { 394 u = u.indexOf('.js') != -1 ? u.substring(0, u.lastIndexOf('/')) : u; 395 u = u.charAt(u.length-1) == '/' ? u.substring(0, u.length-1) : u; 396 this.plugins[n] = {baseURL : u}; 397 this.loadScript(u + "/editor_plugin" + (tinyMCE.srcMode ? '_src' : '') + ".js"); 391 add : function(cb, s) { 392 this.listeners.push({cb : cb, scope : s || this.scope}); 393 394 return cb; 398 395 }, 399 396 400 hasTheme : function(n) { 401 return typeof(this.themes[n]) != "undefined" && this.themes[n] != null; 397 addToTop : function(cb, s) { 398 this.listeners.unshift({cb : cb, scope : s || this.scope}); 399 400 return cb; 402 401 }, 403 402 404 addTheme : function(n, t) { 405 this.themes[n] = t; 406 407 this.loadNextScript(); 403 remove : function(cb) { 404 var l = this.listeners, o = null; 405 406 tinymce.each(l, function(c, i) { 407 if (cb == c.cb) { 408 o = cb; 409 l.splice(i, 1); 410 return false; 411 } 412 }); 413 414 return o; 408 415 }, 409 416 410 addMenu : function(n, m) { 411 this.menus[n] = m; 412 }, 413 414 hasMenu : function(n) { 415 return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; 416 }, 417 418 loadScript : function(url) { 419 var i; 420 421 for (i=0; i<this.loadedFiles.length; i++) { 422 if (this.loadedFiles[i] == url) 417 dispatch : function() { 418 var s, a = arguments; 419 420 tinymce.each(this.listeners, function(c) { 421 return s = c.cb.apply(c.scope, a); 422 }); 423 424 return s; 425 } 426 427 }); 428 429 /* file:jscripts/tiny_mce/classes/util/URI.js */ 430 431 (function() { 432 var each = tinymce.each; 433 434 tinymce.create('tinymce.util.URI', { 435 URI : function(u, s) { 436 var t = this, o, a, b; 437 438 // Default settings 439 s = t.settings = s || {}; 440 441 // Strange app protocol or local anchor 442 if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) { 443 t.source = u; 423 444 return; 424 } 425 426 if (tinyMCE.settings.strict_loading_mode) 427 this.pendingFiles[this.pendingFiles.length] = url; 428 else 429 document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '"></script>'); 430 431 this.loadedFiles[this.loadedFiles.length] = url; 432 }, 433 434 loadNextScript : function() { 435 var d = document, se; 436 437 if (!tinyMCE.settings.strict_loading_mode) 438 return; 439 440 if (this.loadingIndex < this.pendingFiles.length) { 441 se = d.createElementNS('http://www.w3.org/1999/xhtml', 'script'); 442 se.setAttribute('language', 'javascript'); 443 se.setAttribute('type', 'text/javascript'); 444 se.setAttribute('src', this.pendingFiles[this.loadingIndex++]); 445 446 d.getElementsByTagName("head")[0].appendChild(se); 447 } else 448 this.loadingIndex = -1; // Done with loading 449 }, 450 451 loadCSS : function(url) { 452 var ar = url.replace(/\s+/, '').split(','); 453 var lflen = 0, csslen = 0, skip = false; 454 var x = 0, i = 0, nl, le; 455 456 for (x = 0,csslen = ar.length; x<csslen; x++) { 457 if (ar[x] != null && ar[x] != 'null' && ar[x].length > 0) { 458 /* Make sure it doesn't exist. */ 459 for (i=0, lflen=this.loadedFiles.length; i<lflen; i++) { 460 if (this.loadedFiles[i] == ar[x]) { 461 skip = true; 445 } 446 447 // Absolute path with no host, fake host and protocol 448 if (u.indexOf('/') === 0 && u.indexOf('//') !== 0) 449 u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u; 450 451 // Relative path 452 if (u.indexOf('://') === -1 && u.indexOf('//') !== 0) 453 u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u); 454 455 // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri) 456 u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something 457 u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u); 458 each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) { 459 var s = u[i]; 460 461 // Zope 3 workaround, they use @@something 462 if (s) 463 s = s.replace(/\(mce_at\)/g, '@@'); 464 465 t[v] = s; 466 }); 467 468 if (b = s.base_uri) { 469 if (!t.protocol) 470 t.protocol = b.protocol; 471 472 if (!t.userInfo) 473 t.userInfo = b.userInfo; 474 475 if (!t.port && t.host == 'mce_host') 476 t.port = b.port; 477 478 if (!t.host || t.host == 'mce_host') 479 t.host = b.host; 480 481 t.source = ''; 482 } 483 484 //t.path = t.path || '/'; 485 }, 486 487 setPath : function(p) { 488 var t = this; 489 490 p = /^(.*?)\/?(\w+)?$/.exec(p); 491 492 // Update path parts 493 t.path = p[0]; 494 t.directory = p[1]; 495 t.file = p[2]; 496 497 // Rebuild source 498 t.source = ''; 499 t.getURI(); 500 }, 501 502 toRelative : function(u) { 503 var t = this, o; 504 505 u = new tinymce.util.URI(u, {base_uri : t}); 506 507 // Not on same domain/port or protocol 508 if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol) 509 return u.getURI(); 510 511 o = t.toRelPath(t.path, u.path); 512 513 // Add query 514 if (u.query) 515 o += '?' + u.query; 516 517 // Add anchor 518 if (u.anchor) 519 o += '#' + u.anchor; 520 521 return o; 522 }, 523 524 toAbsolute : function(u, nh) { 525 var u = new tinymce.util.URI(u, {base_uri : this}); 526 527 return u.getURI(this.host == u.host ? nh : 0); 528 }, 529 530 toRelPath : function(base, path) { 531 var items, bp = 0, out = '', i; 532 533 // Split the paths 534 base = base.substring(0, base.lastIndexOf('/')); 535 base = base.split('/'); 536 items = path.split('/'); 537 538 if (base.length >= items.length) { 539 for (i = 0; i < base.length; i++) { 540 if (i >= items.length || base[i] != items[i]) { 541 bp = i + 1; 462 542 break; 463 543 } 464 544 } 465 466 if (!skip) { 467 if (tinyMCE.settings.strict_loading_mode) { 468 nl = document.getElementsByTagName("head"); 469 470 le = document.createElement('link'); 471 le.setAttribute('href', ar[x]); 472 le.setAttribute('rel', 'stylesheet'); 473 le.setAttribute('type', 'text/css'); 474 475 nl[0].appendChild(le); 476 } else 477 document.write('<link href="' + ar[x] + '" rel="stylesheet" type="text/css" />'); 478 479 this.loadedFiles[this.loadedFiles.length] = ar[x]; 480 } 481 } 482 } 483 }, 484 485 importCSS : function(doc, css) { 486 var css_ary = css.replace(/\s+/, '').split(','); 487 var csslen, elm, headArr, x, css_file; 488 489 for (x = 0, csslen = css_ary.length; x<csslen; x++) { 490 css_file = css_ary[x]; 491 492 if (css_file != null && css_file != 'null' && css_file.length > 0) { 493 // Is relative, make absolute 494 if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/') 495 css_file = this.documentBasePath + "/" + css_file; 496 497 if (typeof(doc.createStyleSheet) == "undefined") { 498 elm = doc.createElement("link"); 499 500 elm.rel = "stylesheet"; 501 elm.href = css_file; 502 503 if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0) 504 headArr[0].appendChild(elm); 505 } else 506 doc.createStyleSheet(css_file); 507 } 508 } 509 }, 510 511 confirmAdd : function(e, settings) { 512 var elm = tinyMCE.isIE ? event.srcElement : e.target; 513 var elementId = elm.name ? elm.name : elm.id; 514 515 tinyMCE.settings = settings; 516 517 if (tinyMCE.settings.convert_on_click || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang.lang_edit_confirm))) 518 tinyMCE.addMCEControl(elm, elementId); 519 520 elm.setAttribute('mce_noask', 'true'); 521 }, 522 523 updateContent : function(form_element_name) { 524 var formElement, n, inst, doc; 525 526 // Find MCE instance linked to given form element and copy it's value 527 formElement = document.getElementById(form_element_name); 528 for (n in tinyMCE.instances) { 529 inst = tinyMCE.instances[n]; 530 531 if (!tinyMCE.isInstance(inst)) 532 continue; 533 534 inst.switchSettings(); 535 536 if (inst.formElement == formElement) { 537 doc = inst.getDoc(); 538 539 tinyMCE._setHTML(doc, inst.formElement.value); 540 541 if (!tinyMCE.isIE) 542 doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid); 543 } 544 } 545 }, 546 547 addMCEControl : function(replace_element, form_element_name, target_document) { 548 var id = "mce_editor_" + tinyMCE.idCounter++; 549 var inst = new TinyMCE_Control(tinyMCE.settings); 550 551 inst.editorId = id; 552 this.instances[id] = inst; 553 554 inst._onAdd(replace_element, form_element_name, target_document); 555 }, 556 557 removeInstance : function(ti) { 558 var t = [], n, i; 559 560 // Remove from instances 561 for (n in tinyMCE.instances) { 562 i = tinyMCE.instances[n]; 563 564 if (tinyMCE.isInstance(i) && ti != i) 565 t[n] = i; 566 } 567 568 tinyMCE.instances = t; 569 570 // Remove from global undo/redo 571 n = []; 572 t = tinyMCE.undoLevels; 573 574 for (i=0; i<t.length; i++) { 575 if (t[i] != ti) 576 n.push(t[i]); 577 } 578 579 tinyMCE.undoLevels = n; 580 tinyMCE.undoIndex = n.length; 581 582 // Dispatch remove instance call 583 tinyMCE.dispatchCallback(ti, 'remove_instance_callback', 'removeInstance', ti); 584 585 return ti; 586 }, 587 588 removeMCEControl : function(editor_id) { 589 var inst = tinyMCE.getInstanceById(editor_id), h, re, ot, tn; 590 591 if (inst) { 592 inst.switchSettings(); 593 594 editor_id = inst.editorId; 595 h = tinyMCE.getContent(editor_id); 596 597 this.removeInstance(inst); 598 599 tinyMCE.selectedElement = null; 600 tinyMCE.selectedInstance = null; 601 602 // Remove element 603 re = document.getElementById(editor_id + "_parent"); 604 ot = inst.oldTargetElement; 605 tn = ot.nodeName.toLowerCase(); 606 607 if (tn == "textarea" || tn == "input") { 608 re.parentNode.removeChild(re); 609 ot.style.display = "inline"; 610 ot.value = h; 611 } else { 612 ot.innerHTML = h; 613 ot.style.display = 'block'; 614 re.parentNode.insertBefore(ot, re); 615 re.parentNode.removeChild(re); 616 } 617 } 618 }, 619 620 triggerSave : function(skip_cleanup, skip_callback) { 621 var inst, n; 622 623 // Default to false 624 if (typeof(skip_cleanup) == "undefined") 625 skip_cleanup = false; 626 627 // Default to false 628 if (typeof(skip_callback) == "undefined") 629 skip_callback = false; 630 631 // Cleanup and set all form fields 632 for (n in tinyMCE.instances) { 633 inst = tinyMCE.instances[n]; 634 635 if (!tinyMCE.isInstance(inst)) 636 continue; 637 638 inst.triggerSave(skip_cleanup, skip_callback); 639 } 640 }, 641 642 resetForm : function(form_index) { 643 var i, inst, n, formObj = document.forms[form_index]; 644 645 for (n in tinyMCE.instances) { 646 inst = tinyMCE.instances[n]; 647 648 if (!tinyMCE.isInstance(inst)) 649 continue; 650 651 inst.switchSettings(); 652 653 for (i=0; i<formObj.elements.length; i++) { 654 if (inst.formTargetElementId == formObj.elements[i].name) 655 inst.getBody().innerHTML = inst.startContent; 656 } 657 } 658 }, 659 660 execInstanceCommand : function(editor_id, command, user_interface, value, focus) { 661 var inst = tinyMCE.getInstanceById(editor_id), r; 662 663 if (inst) { 664 r = inst.selection.getRng(); 665 666 if (typeof(focus) == "undefined") 667 focus = true; 668 669 // IE bug lost focus on images in absolute divs Bug #1534575 670 if (focus && (!r || !r.item)) 671 inst.contentWindow.focus(); 672 673 // Reset design mode if lost 674 inst.autoResetDesignMode(); 675 676 this.selectedElement = inst.getFocusElement(); 677 inst.select(); 678 tinyMCE.execCommand(command, user_interface, value); 679 680 // Cancel event so it doesn't call onbeforeonunlaod 681 if (tinyMCE.isIE && window.event != null) 682 tinyMCE.cancelEvent(window.event); 683 } 684 }, 685 686 execCommand : function(command, user_interface, value) { 687 var inst = tinyMCE.selectedInstance, n, pe, te; 688 689 // Default input 690 user_interface = user_interface ? user_interface : false; 691 value = value ? value : null; 692 693 if (inst) 694 inst.switchSettings(); 695 696 switch (command) { 697 case "Undo": 698 if (this.getParam('custom_undo_redo_global')) { 699 if (this.undoIndex > 0) { 700 tinyMCE.nextUndoRedoAction = 'Undo'; 701 inst = this.undoLevels[--this.undoIndex]; 702 inst.select(); 703 704 if (!tinyMCE.nextUndoRedoInstanceId) 705 inst.execCommand('Undo'); 706 } 707 } else 708 inst.execCommand('Undo'); 709 return true; 710 711 case "Redo": 712 if (this.getParam('custom_undo_redo_global')) { 713 if (this.undoIndex <= this.undoLevels.length - 1) { 714 tinyMCE.nextUndoRedoAction = 'Redo'; 715 inst = this.undoLevels[this.undoIndex++]; 716 inst.select(); 717 718 if (!tinyMCE.nextUndoRedoInstanceId) 719 inst.execCommand('Redo'); 720 } 721 } else 722 inst.execCommand('Redo'); 723 724 return true; 725 726 case 'mceFocus': 727 inst = tinyMCE.getInstanceById(value); 728 729 if (inst) 730 inst.getWin().focus(); 731 return; 732 733 case "mceAddControl": 734 case "mceAddEditor": 735 tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); 736 return; 737 738 case "mceAddFrameControl": 739 tinyMCE.addMCEControl(tinyMCE._getElementById(value.element, value.document), value.element, value.document); 740 return; 741 742 case "mceRemoveControl": 743 case "mceRemoveEditor": 744 tinyMCE.removeMCEControl(value); 745 return; 746 747 case "mceToggleEditor": 748 inst = tinyMCE.getInstanceById(value); 749 750 if (inst) { 751 pe = document.getElementById(inst.editorId + '_parent'); 752 te = inst.oldTargetElement; 753 754 if (typeof(inst.enabled) == 'undefined') 755 inst.enabled = true; 756 757 inst.enabled = !inst.enabled; 758 759 if (!inst.enabled) { 760 pe.style.display = 'none'; 761 762 if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT') 763 te.value = inst.getHTML(); 764 else 765 te.innerHTML = inst.getHTML(); 766 767 te.style.display = inst.oldTargetDisplay; 768 tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst); 769 } else { 770 pe.style.display = 'block'; 771 te.style.display = 'none'; 772 773 if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT') 774 inst.setHTML(te.value); 775 else 776 inst.setHTML(te.innerHTML); 777 778 inst.useCSS = false; 779 tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst); 780 } 781 } else 782 tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); 783 784 return; 785 786 case "mceResetDesignMode": 787 // Resets the designmode state of the editors in Gecko 788 if (tinyMCE.isGecko) { 789 for (n in tinyMCE.instances) { 790 if (!tinyMCE.isInstance(tinyMCE.instances[n])) 791 continue; 792 793 try { 794 tinyMCE.instances[n].getDoc().designMode = "off"; 795 tinyMCE.instances[n].getDoc().designMode = "on"; 796 tinyMCE.instances[n].useCSS = false; 797 } catch (e) { 798 // Ignore any errors 799 } 800 } 801 } 802 803 return; 804 } 805 806 if (inst) { 807 inst.execCommand(command, user_interface, value); 808 } else if (tinyMCE.settings.focus_alert) 809 alert(tinyMCELang.lang_focus_alert); 810 }, 811 812 _createIFrame : function(replace_element, doc, win) { 813 var iframe, id = replace_element.getAttribute("id"); 814 var aw, ah; 815 816 if (typeof(doc) == "undefined") 817 doc = document; 818 819 if (typeof(win) == "undefined") 820 win = window; 821 822 iframe = doc.createElement("iframe"); 823 824 aw = "" + tinyMCE.settings.area_width; 825 ah = "" + tinyMCE.settings.area_height; 826 827 if (aw.indexOf('%') == -1) { 828 aw = parseInt(aw); 829 aw = (isNaN(aw) || aw < 0) ? 300 : aw; 830 aw = aw + "px"; 831 } 832 833 if (ah.indexOf('%') == -1) { 834 ah = parseInt(ah); 835 ah = (isNaN(ah) || ah < 0) ? 240 : ah; 836 ah = ah + "px"; 837 } 838 839 iframe.setAttribute("id", id); 840 iframe.setAttribute("name", id); 841 iframe.setAttribute("class", "mceEditorIframe"); 842 iframe.setAttribute("border", "0"); 843 iframe.setAttribute("frameBorder", "0"); 844 iframe.setAttribute("marginWidth", "0"); 845 iframe.setAttribute("marginHeight", "0"); 846 iframe.setAttribute("leftMargin", "0"); 847 iframe.setAttribute("topMargin", "0"); 848 iframe.setAttribute("width", aw); 849 iframe.setAttribute("height", ah); 850 iframe.setAttribute("allowtransparency", "true"); 851 iframe.className = 'mceEditorIframe'; 852 853 if (tinyMCE.settings.auto_resize) 854 iframe.setAttribute("scrolling", "no"); 855 856 // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs 857 if (tinyMCE.isRealIE) 858 iframe.setAttribute("src", this.settings.default_document); 859 860 iframe.style.width = aw; 861 iframe.style.height = ah; 862 863 // Ugly hack for Gecko problem in strict mode 864 if (tinyMCE.settings.strict_loading_mode) 865 iframe.style.marginBottom = '-5px'; 866 867 // MSIE 5.0 issue 868 if (tinyMCE.isRealIE) 869 replace_element.outerHTML = iframe.outerHTML; 870 else 871 replace_element.parentNode.replaceChild(iframe, replace_element); 872 873 if (tinyMCE.isRealIE) 874 return win.frames[id]; 875 else 876 return iframe; 877 }, 878 879 setupContent : function(editor_id) { 880 var inst = tinyMCE.instances[editor_id], i, doc = inst.getDoc(), head = doc.getElementsByTagName('head').item(0); 881 var content = inst.startContent, contentElement, body; 882 883 // HTML values get XML encoded in strict mode 884 if (tinyMCE.settings.strict_loading_mode) { 885 content = content.replace(/</g, '<'); 886 content = content.replace(/>/g, '>'); 887 content = content.replace(/"/g, '"'); 888 content = content.replace(/&/g, '&'); 889 } 890 891 tinyMCE.selectedInstance = inst; 892 inst.switchSettings(); 893 894 // Not loaded correctly hit it again, Mozilla bug #997860 895 if (!tinyMCE.isIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") { 896 // This part will remove the designMode status 897 // Failes first time in Firefox 1.5b2 on Mac 898 try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {} 899 window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000); 900 return; 901 } 902 903 // Wait for it to load 904 if (!head || !doc.body) { 905 window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10); 906 return; 907 } 908 909 // Import theme specific content CSS the user specific 910 tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings.theme + "/css/editor_content.css"); 911 tinyMCE.importCSS(inst.getDoc(), inst.settings.content_css); 912 tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst); 913 914 // Setup keyboard shortcuts 915 if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) { 916 inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo'); 917 inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo'); 918 } 919 920 // BlockFormat shortcuts keys 921 for (i=1; i<=6; i++) 922 inst.addShortcut('ctrl', '' + i, '', 'FormatBlock', false, '<h' + i + '>'); 923 924 inst.addShortcut('ctrl', '7', '', 'FormatBlock', false, '<p>'); 925 inst.addShortcut('ctrl', '8', '', 'FormatBlock', false, '<div>'); 926 inst.addShortcut('ctrl', '9', '', 'FormatBlock', false, '<address>'); 927 928 // Add default shortcuts for gecko 929 if (tinyMCE.isGecko) { 930 inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold'); 931 inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic'); 932 inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline'); 933 } 934 935 // Setup span styles 936 if (tinyMCE.getParam("convert_fonts_to_spans")) 937 inst.getBody().setAttribute('id', 'mceSpanFonts'); 938 939 if (tinyMCE.settings.nowrap) 940 doc.body.style.whiteSpace = "nowrap"; 941 942 doc.body.dir = this.settings.directionality; 943 doc.editorId = editor_id; 944 945 // Add on document element in Mozilla 946 if (!tinyMCE.isIE) 947 doc.documentElement.editorId = editor_id; 948 949 inst.setBaseHREF(tinyMCE.settings.base_href); 950 951 // Replace new line characters to BRs 952 if (tinyMCE.settings.convert_newlines_to_brs) { 953 content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi"); 954 content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi"); 955 content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi"); 956 } 957 958 // Open closed anchors 959 // content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>'); 960 961 // Call custom cleanup code 962 content = tinyMCE.storeAwayURLs(content); 963 content = tinyMCE._customCleanup(inst, "insert_to_editor", content); 964 965 if (tinyMCE.isIE) { 966 // Ugly!!! 967 window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500); 968 969 if (tinyMCE.settings.force_br_newlines) 970 doc.styleSheets[0].addRule("p", "margin: 0;"); 971 972 body = inst.getBody(); 973 body.editorId = editor_id; 974 } 975 976 content = tinyMCE.cleanupHTMLCode(content); 977 978 // Fix for bug #958637 979 if (!tinyMCE.isIE) { 980 contentElement = inst.getDoc().createElement("body"); 981 doc = inst.getDoc(); 982 983 contentElement.innerHTML = content; 984 985 if (tinyMCE.settings.cleanup_on_startup) 986 tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement)); 987 else 988 tinyMCE.setInnerHTML(inst.getBody(), content); 989 990 tinyMCE.convertAllRelativeURLs(inst.getBody()); 991 } else { 992 if (tinyMCE.settings.cleanup_on_startup) { 993 tinyMCE._setHTML(inst.getDoc(), content); 994 995 // Produces permission denied error in MSIE 5.5 996 try { 997 tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody())); 998 } catch(e) { 999 // Ignore 1000 } 1001 } else 1002 tinyMCE._setHTML(inst.getDoc(), content); 1003 } 1004 1005 // Fix for bug #957681 1006 //inst.getDoc().designMode = inst.getDoc().designMode; 1007 1008 tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings.visual, inst); 1009 tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc()); 1010 1011 // Re-add design mode on mozilla 1012 if (!tinyMCE.isIE) 1013 tinyMCE.addEventHandlers(inst); 1014 1015 // Add blur handler 1016 if (tinyMCE.isIE) { 1017 tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch); 1018 tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953 1019 1020 // Workaround for drag drop/copy paste base href bug 1021 if (!tinyMCE.isOpera) { 1022 tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove); 1023 tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch); 1024 tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch); 1025 } 1026 } 1027 1028 // Trigger node change, this call locks buttons for tables and so forth 1029 inst.select(); 1030 tinyMCE.selectedElement = inst.contentWindow.document.body; 1031 1032 // Call custom DOM cleanup 1033 tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody()); 1034 tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody()); 1035 tinyMCE._setEventsEnabled(inst.getBody(), false); 1036 tinyMCE.cleanupAnchors(inst.getDoc()); 1037 1038 if (tinyMCE.getParam("convert_fonts_to_spans")) 1039 tinyMCE.convertSpansToFonts(inst.getDoc()); 1040 1041 inst.startContent = tinyMCE.trim(inst.getBody().innerHTML); 1042 inst.undoRedo.add({ content : inst.startContent }); 1043 1044 // Cleanup any mess left from storyAwayURLs 1045 if (tinyMCE.isGecko) { 1046 // Remove mce_src from textnodes and comments 1047 tinyMCE.selectNodes(inst.getBody(), function(n) { 1048 if (n.nodeType == 3 || n.nodeType == 8) 1049 n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); 1050 1051 return false; 1052 }); 1053 } 1054 1055 // Remove Gecko spellchecking 1056 if (tinyMCE.isGecko) 1057 inst.getBody().spellcheck = tinyMCE.getParam("gecko_spellcheck"); 1058 1059 // Cleanup any mess left from storyAwayURLs 1060 tinyMCE._removeInternal(inst.getBody()); 1061 1062 inst.select(); 1063 tinyMCE.triggerNodeChange(false, true); 1064 }, 1065 1066 storeAwayURLs : function(s) { 1067 // Remove all mce_src, mce_href and replace them with new ones 1068 // s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); 1069 // s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); 1070 1071 if (!s.match(/(mce_src|mce_href)/gi, s)) { 1072 s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"'); 1073 s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"'); 1074 } 1075 1076 return s; 1077 }, 1078 1079 _removeInternal : function(n) { 1080 if (tinyMCE.isGecko) { 1081 // Remove mce_src from textnodes and comments 1082 tinyMCE.selectNodes(n, function(n) { 1083 if (n.nodeType == 3 || n.nodeType == 8) 1084 n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); 1085 1086 return false; 1087 }); 1088 } 1089 }, 1090 1091 removeTinyMCEFormElements : function(form_obj) { 1092 var i, elementId; 1093 1094 // Skip form element removal 1095 if (!tinyMCE.getParam('hide_selects_on_submit')) 1096 return; 1097 1098 // Check if form is valid 1099 if (typeof(form_obj) == "undefined" || form_obj == null) 1100 return; 1101 1102 // If not a form, find the form 1103 if (form_obj.nodeName != "FORM") { 1104 if (form_obj.form) 1105 form_obj = form_obj.form; 1106 else 1107 form_obj = tinyMCE.getParentElement(form_obj, "form"); 1108 } 1109 1110 // Still nothing 1111 if (form_obj == null) 1112 return; 1113 1114 // Disable all UI form elements that TinyMCE created 1115 for (i=0; i<form_obj.elements.length; i++) { 1116 elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id; 1117 1118 if (elementId.indexOf('mce_editor_') == 0) 1119 form_obj.elements[i].disabled = true; 1120 } 1121 }, 1122 1123 handleEvent : function(e) { 1124 var inst = tinyMCE.selectedInstance, i, elm, keys; 1125 1126 // Remove odd, error 1127 if (typeof(tinyMCE) == "undefined") 1128 return true; 1129 1130 //tinyMCE.debug(e.type + " " + e.target.nodeName + " " + (e.relatedTarget ? e.relatedTarget.nodeName : "")); 1131 1132 if (tinyMCE.executeCallback(tinyMCE.selectedInstance, 'handle_event_callback', 'handleEvent', e)) 1133 return false; 1134 1135 switch (e.type) { 1136 case "beforedeactivate": // Was added due to bug #1439953 1137 case "blur": 1138 if (tinyMCE.selectedInstance) 1139 tinyMCE.selectedInstance.execCommand('mceEndTyping'); 1140 1141 tinyMCE.hideMenus(); 1142 1143 return; 1144 1145 // Workaround for drag drop/copy paste base href bug 1146 case "drop": 1147 case "beforepaste": 1148 if (tinyMCE.selectedInstance) 1149 tinyMCE.selectedInstance.setBaseHREF(null); 1150 1151 // Fixes odd MSIE bug where drag/droping elements in a iframe with height 100% breaks 1152 // This logic forces the width/height to be in pixels while the user is drag/dropping 1153 if (tinyMCE.isRealIE) { 1154 var ife = tinyMCE.selectedInstance.iframeElement; 1155 1156 /*if (ife.style.width.indexOf('%') != -1) { 1157 ife._oldWidth = ife.width.height; 1158 ife.style.width = ife.clientWidth; 1159 }*/ 1160 1161 if (ife.style.height.indexOf('%') != -1) { 1162 ife._oldHeight = ife.style.height; 1163 ife.style.height = ife.clientHeight; 1164 } 1165 } 1166 1167 window.setTimeout("tinyMCE.selectedInstance.setBaseHREF(tinyMCE.settings.base_href);tinyMCE._resetIframeHeight();", 1); 1168 return; 1169 1170 case "submit": 1171 tinyMCE.formSubmit(tinyMCE.isMSIE ? window.event.srcElement : e.target); 1172 return; 1173 1174 case "reset": 1175 var formObj = tinyMCE.isIE ? window.event.srcElement : e.target; 1176 1177 for (i=0; i<document.forms.length; i++) { 1178 if (document.forms[i] == formObj) 1179 window.setTimeout('tinyMCE.resetForm(' + i + ');', 10); 1180 } 1181 1182 return; 1183 1184 case "keypress": 1185 if (inst && inst.handleShortcut(e)) 1186 return false; 1187 1188 if (e.target.editorId) { 1189 tinyMCE.instances[e.target.editorId].select(); 1190 } else { 1191 if (e.target.ownerDocument.editorId) 1192 tinyMCE.instances[e.target.ownerDocument.editorId].select(); 1193 } 1194 1195 if (tinyMCE.selectedInstance) 1196 tinyMCE.selectedInstance.switchSettings(); 1197 1198 // Insert P element 1199 if ((tinyMCE.isGecko || tinyMCE.isOpera || tinyMCE.isSafari) && tinyMCE.settings.force_p_newlines && e.keyCode == 13 && !e.shiftKey) { 1200 // Insert P element instead of BR 1201 if (TinyMCE_ForceParagraphs._insertPara(tinyMCE.selectedInstance, e)) { 1202 // Cancel event 1203 tinyMCE.execCommand("mceAddUndoLevel"); 1204 return tinyMCE.cancelEvent(e); 1205 } 1206 } 1207 1208 // Handle backspace 1209 if ((tinyMCE.isGecko && !tinyMCE.isSafari) && tinyMCE.settings.force_p_newlines && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { 1210 // Insert P element instead of BR 1211 if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) { 1212 // Cancel event 1213 tinyMCE.execCommand("mceAddUndoLevel"); 1214 return tinyMCE.cancelEvent(e); 1215 } 1216 } 1217 1218 // Return key pressed 1219 if (tinyMCE.isIE && tinyMCE.settings.force_br_newlines && e.keyCode == 13) { 1220 if (e.target.editorId) 1221 tinyMCE.instances[e.target.editorId].select(); 1222 1223 if (tinyMCE.selectedInstance) { 1224 var sel = tinyMCE.selectedInstance.getDoc().selection; 1225 var rng = sel.createRange(); 1226 1227 if (tinyMCE.getParentElement(rng.parentElement(), "li") != null) 1228 return false; 1229 1230 // Cancel event 1231 e.returnValue = false; 1232 e.cancelBubble = true; 1233 1234 // Insert BR element 1235 rng.pasteHTML("<br />"); 1236 rng.collapse(false); 1237 rng.select(); 1238 1239 tinyMCE.execCommand("mceAddUndoLevel"); 1240 tinyMCE.triggerNodeChange(false); 1241 return false; 1242 } 1243 } 1244 1245 // Backspace or delete 1246 if (e.keyCode == 8 || e.keyCode == 46) { 1247 tinyMCE.selectedElement = e.target; 1248 tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a"); 1249 tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img"); 1250 tinyMCE.triggerNodeChange(false); 1251 } 1252 1253 return false; 1254 1255 case "keyup": 1256 case "keydown": 1257 tinyMCE.hideMenus(); 1258 tinyMCE.hasMouseMoved = false; 1259 1260 if (inst && inst.handleShortcut(e)) 1261 return false; 1262 1263 inst._fixRootBlocks(); 1264 1265 if (inst.settings.remove_trailing_nbsp) 1266 inst._fixTrailingNbsp(); 1267 1268 if (e.target.editorId) 1269 tinyMCE.instances[e.target.editorId].select(); 1270 1271 if (tinyMCE.selectedInstance) 1272 tinyMCE.selectedInstance.switchSettings(); 1273 1274 inst = tinyMCE.selectedInstance; 1275 1276 // Handle backspace 1277 if (tinyMCE.isGecko && tinyMCE.settings.force_p_newlines && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { 1278 // Insert P element instead of BR 1279 if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) { 1280 // Cancel event 1281 tinyMCE.execCommand("mceAddUndoLevel"); 1282 e.preventDefault(); 1283 return false; 1284 } 1285 } 1286 1287 tinyMCE.selectedElement = null; 1288 tinyMCE.selectedNode = null; 1289 elm = tinyMCE.selectedInstance.getFocusElement(); 1290 tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a"); 1291 tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img"); 1292 tinyMCE.selectedElement = elm; 1293 1294 // Update visualaids on tabs 1295 if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9) 1296 tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings.visual, tinyMCE.selectedInstance); 1297 1298 // Fix empty elements on return/enter, check where enter occured 1299 if (tinyMCE.isIE && e.type == "keydown" && e.keyCode == 13) 1300 tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement(); 1301 1302 // Fix empty elements on return/enter 1303 if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) { 1304 elm = tinyMCE.enterKeyElement; 1305 if (elm) { 1306 var re = new RegExp('^HR|IMG|BR$','g'); // Skip these 1307 var dre = new RegExp('^H[1-6]$','g'); // Add double on these 1308 1309 if (!elm.hasChildNodes() && !re.test(elm.nodeName)) { 1310 if (dre.test(elm.nodeName)) 1311 elm.innerHTML = " "; 1312 else 1313 elm.innerHTML = " "; 1314 } 1315 } 1316 } 1317 1318 // Check if it's a position key 1319 keys = tinyMCE.posKeyCodes; 1320 var posKey = false; 1321 for (i=0; i<keys.length; i++) { 1322 if (keys[i] == e.keyCode) { 1323 posKey = true; 545 } 546 547 if (base.length < items.length) { 548 for (i = 0; i < items.length; i++) { 549 if (i >= base.length || base[i] != items[i]) { 550 bp = i + 1; 1324 551 break; 1325 552 } 1326 553 } 1327 1328 // MSIE custom key handling 1329 if (tinyMCE.isIE && tinyMCE.settings.custom_undo_redo) { 1330 keys = [8, 46]; // Backspace,Delete 1331 1332 for (i=0; i<keys.length; i++) { 1333 if (keys[i] == e.keyCode) { 1334 if (e.type == "keyup") 1335 tinyMCE.triggerNodeChange(false); 1336 } 1337 } 1338 } 1339 1340 // If Ctrl key 1341 if (e.keyCode == 17) 1342 return true; 1343 1344 // Handle Undo/Redo when typing content 1345 1346 if (tinyMCE.isGecko) { 1347 // Start typing (not a position key or ctrl key, but ctrl+x and ctrl+p is ok) 1348 if (!posKey && e.type == "keyup" && !e.ctrlKey || (e.ctrlKey && (e.keyCode == 86 || e.keyCode == 88))) 1349 tinyMCE.execCommand("mceStartTyping"); 1350 } else { 1351 // IE seems to be working better with this setting 1352 if (!posKey && e.type == "keyup") 1353 tinyMCE.execCommand("mceStartTyping"); 1354 } 1355 1356 // Store undo bookmark 1357 if (e.type == "keydown" && (posKey || e.ctrlKey) && inst) 1358 inst.undoBookmark = inst.selection.getBookmark(); 1359 1360 // End typing (position key) or some Ctrl event 1361 if (e.type == "keyup" && (posKey || e.ctrlKey)) 1362 tinyMCE.execCommand("mceEndTyping"); 1363 1364 if (posKey && e.type == "keyup") 1365 tinyMCE.triggerNodeChange(false); 1366 1367 if (tinyMCE.isIE && e.ctrlKey) 1368 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); 1369 break; 1370 1371 case "mousedown": 1372 case "mouseup": 1373 case "click": 1374 case "dblclick": 1375 case "focus": 1376 tinyMCE.hideMenus(); 1377 1378 if (tinyMCE.selectedInstance) { 1379 tinyMCE.selectedInstance.switchSettings(); 1380 tinyMCE.selectedInstance.isFocused = true; 1381 } 1382 1383 // Check instance event trigged on 1384 var targetBody = tinyMCE.getParentElement(e.target, "html"); 1385 for (var instanceName in tinyMCE.instances) { 1386 if (!tinyMCE.isInstance(tinyMCE.instances[instanceName])) 1387 continue; 1388 1389 inst = tinyMCE.instances[instanceName]; 1390 1391 // Reset design mode if lost (on everything just in case) 1392 inst.autoResetDesignMode(); 1393 1394 // Use HTML element since users might click outside of body element 1395 if (inst.getBody().parentNode == targetBody) { 1396 inst.select(); 1397 tinyMCE.selectedElement = e.target; 1398 tinyMCE.linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a"); 1399 tinyMCE.imgElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "img"); 1400 break; 1401 } 1402 } 1403 1404 // Add first bookmark location 1405 if (!tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark && (e.type == "mouseup" || e.type == "dblclick")) 1406 tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark = tinyMCE.selectedInstance.selection.getBookmark(); 1407 1408 // Reset selected node 1409 if (e.type != "focus") 1410 tinyMCE.selectedNode = null; 1411 1412 tinyMCE.triggerNodeChange(false); 1413 tinyMCE.execCommand("mceEndTyping"); 1414 1415 if (e.type == "mouseup") 1416 tinyMCE.execCommand("mceAddUndoLevel"); 1417 1418 // Just in case 1419 if (!tinyMCE.selectedInstance && e.target.editorId) 1420 tinyMCE.instances[e.target.editorId].select(); 1421 1422 return false; 554 } 555 556 if (bp == 1) 557 return path; 558 559 for (i = 0; i < base.length - (bp - 1); i++) 560 out += "../"; 561 562 for (i = bp - 1; i < items.length; i++) { 563 if (i != bp - 1) 564 out += "/" + items[i]; 565 else 566 out += items[i]; 567 } 568 569 return out; 570 }, 571 572 toAbsPath : function(base, path) { 573 var i, nb = 0, o = []; 574 575 // Split paths 576 base = base.split('/'); 577 path = path.split('/'); 578 579 // Remove empty chunks 580 each(base, function(k) { 581 if (k) 582 o.push(k); 583 }); 584 585 base = o; 586 587 // Merge relURLParts chunks 588 for (i = path.length - 1, o = []; i >= 0; i--) { 589 // Ignore empty or . 590 if (path[i].length == 0 || path[i] == ".") 591 continue; 592 593 // Is parent 594 if (path[i] == '..') { 595 nb++; 596 continue; 597 } 598 599 // Move up 600 if (nb > 0) { 601 nb--; 602 continue; 603 } 604 605 o.push(path[i]); 606 } 607 608 i = base.length - nb; 609 610 // If /a/b/c or / 611 if (i <= 0) 612 return '/' + o.reverse().join('/'); 613 614 return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/'); 615 }, 616 617 getURI : function(nh) { 618 var s, t = this; 619 620 // Rebuild source 621 if (!t.source || nh) { 622 s = ''; 623 624 if (!nh) { 625 if (t.protocol) 626 s += t.protocol + '://'; 627 628 if (t.userInfo) 629 s += t.userInfo + '@'; 630 631 if (t.host) 632 s += t.host; 633 634 if (t.port) 635 s += ':' + t.port; 636 } 637 638 if (t.path) 639 s += t.path; 640 641 if (t.query) 642 s += '?' + t.query; 643 644 if (t.anchor) 645 s += '#' + t.anchor; 646 647 t.source = s; 648 } 649 650 return t.source; 1423 651 } 652 653 }); 654 })(); 655 656 /* file:jscripts/tiny_mce/classes/util/Cookie.js */ 657 658 (function() { 659 var each = tinymce.each; 660 661 tinymce.create('static tinymce.util.Cookie', { 662 getHash : function(n) { 663 var v = this.get(n), h; 664 665 if (v) { 666 each(v.split('&'), function(v) { 667 v = v.split('='); 668 h = h || {}; 669 h[unescape(v[0])] = unescape(v[1]); 670 }); 671 } 672 673 return h; 674 }, 675 676 setHash : function(n, v, e, p, d, s) { 677 var o = ''; 678 679 each(v, function(v, k) { 680 o += (!o ? '' : '&') + escape(k) + '=' + escape(v); 681 }); 682 683 this.set(n, o, e, p, d, s); 684 }, 685 686 get : function(n) { 687 var c = document.cookie, e, p = n + "=", b; 688 689 // Strict mode 690 if (!c) 691 return; 692 693 b = c.indexOf("; " + p); 694 695 if (b == -1) { 696 b = c.indexOf(p); 697 698 if (b != 0) 699 return null; 700 } else 701 b += 2; 702 703 e = c.indexOf(";", b); 704 705 if (e == -1) 706 e = c.length; 707 708 return unescape(c.substring(b + p.length, e)); 709 }, 710 711 set : function(n, v, e, p, d, s) { 712 document.cookie = n + "=" + escape(v) + 713 ((e) ? "; expires=" + e.toGMTString() : "") + 714 ((p) ? "; path=" + escape(p) : "") + 715 ((d) ? "; domain=" + d : "") + 716 ((s) ? "; secure" : ""); 717 }, 718 719 remove : function(n, p) { 720 var d = new Date(); 721 722 d.setTime(d.getTime() - 1000); 723 724 this.set(n, '', d, p, d); 725 } 726 727 }); 728 })(); 729 730 /* file:jscripts/tiny_mce/classes/util/JSON.js */ 731 732 tinymce.create('static tinymce.util.JSON', { 733 serialize : function(o) { 734 var i, v, s = tinymce.util.JSON.serialize, t; 735 736 if (o == null) 737 return 'null'; 738 739 t = typeof o; 740 741 if (t == 'string') { 742 v = '\bb\tt\nn\ff\rr\""\'\'\\\\'; 743 744 return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'])/g, function(a, b) { 745 i = v.indexOf(b); 746 747 if (i + 1) 748 return '\\' + v.charAt(i + 1); 749 750 a = b.charCodeAt().toString(16); 751 752 return '\\u' + '0000'.substring(a.length) + a; 753 }) + '"'; 754 } 755 756 if (t == 'object') { 757 if (o instanceof Array) { 758 for (i=0, v = '['; i<o.length; i++) 759 v += (i > 0 ? ',' : '') + s(o[i]); 760 761 return v + ']'; 762 } 763 764 v = '{'; 765 766 for (i in o) 767 v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : ''; 768 769 return v + '}'; 770 } 771 772 return '' + o; 1424 773 }, 1425 774 1426 getButtonHTML : function(id, lang, img, cmd, ui, val) { 1427 var h = '', m, x, io = ''; 1428 1429 cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; 1430 1431 if (typeof(ui) != "undefined" && ui != null) 1432 cmd += ',' + ui; 1433 1434 if (typeof(val) != "undefined" && val != null) 1435 cmd += ",'" + val + "'"; 1436 1437 cmd += ');'; 1438 1439 // Patch for IE7 bug with hover out not restoring correctly 1440 if (tinyMCE.isRealIE) 1441 io = 'onmouseover="tinyMCE.lastHover = this;"'; 1442 1443 // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled 1444 if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = this.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { 1445 // Tiled button 1446 x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); 1447 h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceTiledButton mceButtonNormal" target="_self">'; 1448 h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" alt="{$'+lang+'}" title="{$' + lang + '}" />'; 1449 h += '</a>'; 1450 } else { 1451 // Normal button 1452 h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceButtonNormal" target="_self">'; 1453 h += '<img src="' + img + '" alt="{$'+lang+'}" title="{$' + lang + '}" />'; 1454 h += '</a>'; 1455 } 1456 1457 return h; 1458 }, 1459 1460 getMenuButtonHTML : function(id, lang, img, mcmd, cmd, ui, val) { 1461 var h = '', m, x; 1462 1463 mcmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + mcmd + '\');'; 1464 cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; 1465 1466 if (typeof(ui) != "undefined" && ui != null) 1467 cmd += ',' + ui; 1468 1469 if (typeof(val) != "undefined" && val != null) 1470 cmd += ",'" + val + "'"; 1471 1472 cmd += ');'; 1473 1474 // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled 1475 if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { 1476 x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); 1477 1478 if (tinyMCE.isRealIE) 1479 h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">'; 1480 else 1481 h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton">'; 1482 1483 h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceTiledButton mceMenuButtonNormal" target="_self">'; 1484 h += '<img src="{$themeurl}/images/spacer.gif" style="width: 20px; height: 20px; background-position: ' + x + 'px 0" title="{$' + lang + '}" /></a>'; 1485 h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />'; 1486 h += '</a></span>'; 1487 } else { 1488 if (tinyMCE.isRealIE) 1489 h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">'; 1490 else 1491 h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton">'; 1492 1493 h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceMenuButtonNormal" target="_self">'; 1494 h += '<img src="' + img + '" title="{$' + lang + '}" /></a>'; 1495 h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />'; 1496 h += '</a></span>'; 1497 } 1498 1499 return h; 1500 }, 1501 1502 _menuButtonEvent : function(e, o) { 1503 if (o.className == 'mceMenuButtonFocus') 1504 return; 1505 1506 if (e == 'over') 1507 o.className = o.className + ' mceMenuHover'; 1508 else 1509 o.className = o.className.replace(/\s.*$/, ''); 1510 }, 1511 1512 addButtonMap : function(m) { 1513 var i, a = m.replace(/\s+/, '').split(','); 1514 1515 for (i=0; i<a.length; i++) 1516 this.buttonMap[a[i]] = i; 1517 }, 1518 1519 formSubmit : function(f, p) { 1520 var n, inst, found = false; 1521 1522 if (f.form) 1523 f = f.form; 1524 1525 // Is it a form that has a TinyMCE instance 1526 for (n in tinyMCE.instances) { 1527 inst = tinyMCE.instances[n]; 1528 1529 if (!tinyMCE.isInstance(inst)) 1530 continue; 1531 1532 if (inst.formElement) { 1533 if (f == inst.formElement.form) { 1534 found = true; 1535 inst.isNotDirty = true; 1536 } 1537 } 1538 } 1539 1540 // Is valid 1541 if (found) { 1542 tinyMCE.removeTinyMCEFormElements(f); 1543 tinyMCE.triggerSave(); 1544 } 1545 1546 // Is it patched 1547 if (f.mceOldSubmit && p) 1548 f.mceOldSubmit(); 1549 }, 1550 1551 submitPatch : function() { 1552 tinyMCE.formSubmit(this, true); 1553 }, 1554 1555 onLoad : function() { 1556 var r, i, c, mode, trigger, elements, element, settings, elementId, elm; 1557 var selector, deselector, elementRefAr, form; 1558 1559 // Wait for everything to be loaded first 1560 if (tinyMCE.settings.strict_loading_mode && this.loadingIndex != -1) { 1561 window.setTimeout('tinyMCE.onLoad();', 1); 1562 return; 1563 } 1564 1565 if (tinyMCE.isRealIE && window.event.type == "readystatechange" && document.readyState != "complete") 1566 return true; 1567 1568 if (tinyMCE.isLoaded) 1569 return true; 1570 1571 tinyMCE.isLoaded = true; 1572 1573 // IE produces JS error if TinyMCE is placed in a frame 1574 // It seems to have something to do with the selection not beeing 1575 // correctly initialized in IE so this hack solves the problem 1576 if (tinyMCE.isRealIE && document.body && window.location.href != window.top.location.href) { 1577 r = document.body.createTextRange(); 1578 r.collapse(true); 1579 r.select(); 1580 } 1581 1582 tinyMCE.dispatchCallback(null, 'onpageload', 'onPageLoad'); 1583 1584 for (c=0; c<tinyMCE.configs.length; c++) { 1585 tinyMCE.settings = tinyMCE.configs[c]; 1586 1587 selector = tinyMCE.getParam("editor_selector"); 1588 deselector = tinyMCE.getParam("editor_deselector"); 1589 elementRefAr = []; 1590 1591 // Add submit triggers 1592 if (document.forms && tinyMCE.settings.add_form_submit_trigger && !tinyMCE.submitTriggers) { 1593 for (i=0; i<document.forms.length; i++) { 1594 form = document.forms[i]; 1595 1596 tinyMCE.addEvent(form, "submit", TinyMCE_Engine.prototype.handleEvent); 1597 tinyMCE.addEvent(form, "reset", TinyMCE_Engine.prototype.handleEvent); 1598 tinyMCE.submitTriggers = true; // Do it only once 1599 1600 // Patch the form.submit function 1601 if (tinyMCE.settings.submit_patch) { 1602 try { 1603 form.mceOldSubmit = form.submit; 1604 form.submit = TinyMCE_Engine.prototype.submitPatch; 1605 } catch (e) { 1606 // Do nothing 1607 } 1608 } 1609 } 1610 } 1611 1612 // Add editor instances based on mode 1613 mode = tinyMCE.settings.mode; 1614 switch (mode) { 1615 case "exact": 1616 elements = tinyMCE.getParam('elements', '', true, ','); 1617 1618 for (i=0; i<elements.length; i++) { 1619 element = tinyMCE._getElementById(elements[i]); 1620 trigger = element ? element.getAttribute(tinyMCE.settings.textarea_trigger) : ""; 1621 1622 if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(element, "class"))) 1623 continue; 1624 1625 if (trigger == "false") 1626 continue; 1627 1628 if ((tinyMCE.settings.ask || tinyMCE.settings.convert_on_click) && element) { 1629 elementRefAr[elementRefAr.length] = element; 1630 continue; 1631 } 1632 1633 if (element) 1634 tinyMCE.addMCEControl(element, elements[i]); 1635 } 1636 break; 1637 1638 case "specific_textareas": 1639 case "textareas": 1640 elements = document.getElementsByTagName("textarea"); 1641 1642 for (i=0; i<elements.length; i++) { 1643 elm = elements.item(i); 1644 trigger = elm.getAttribute(tinyMCE.settings.textarea_trigger); 1645 1646 if (selector !== '' && !new RegExp('\\b' + selector + '\\b').test(tinyMCE.getAttrib(elm, "class"))) 1647 continue; 1648 1649 if (selector !== '') 1650 trigger = selector !== '' ? "true" : ""; 1651 1652 if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(elm, "class"))) 1653 continue; 1654 1655 if ((mode == "specific_textareas" && trigger == "true") || (mode == "textareas" && trigger != "false")) 1656 elementRefAr[elementRefAr.length] = elm; 1657 } 1658 break; 1659 } 1660 1661 for (i=0; i<elementRefAr.length; i++) { 1662 element = elementRefAr[i]; 1663 elementId = element.name ? element.name : element.id; 1664 1665 if (tinyMCE.settings.ask || tinyMCE.settings.convert_on_click) { 1666 // Focus breaks in Mozilla 1667 if (tinyMCE.isGecko) { 1668 settings = tinyMCE.settings; 1669 1670 tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);}); 1671 1672 if (element.nodeName != "TEXTAREA" && element.nodeName != "INPUT") 1673 tinyMCE.addEvent(element, "click", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);}); 1674 // tinyMCE.addEvent(element, "mouseover", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);}); 1675 } else { 1676 settings = tinyMCE.settings; 1677 1678 tinyMCE.addEvent(element, "focus", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); }); 1679 tinyMCE.addEvent(element, "click", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); }); 1680 // tinyMCE.addEvent(element, "mouseenter", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); }); 1681 } 1682 } else 1683 tinyMCE.addMCEControl(element, elementId); 1684 } 1685 1686 // Handle auto focus 1687 if (tinyMCE.settings.auto_focus) { 1688 window.setTimeout(function () { 1689 var inst = tinyMCE.getInstanceById(tinyMCE.settings.auto_focus); 1690 inst.selection.selectNode(inst.getBody(), true, true); 1691 inst.contentWindow.focus(); 1692 }, 100); 1693 } 1694 1695 tinyMCE.dispatchCallback(null, 'oninit', 'onInit'); 1696 } 1697 }, 1698 1699 isInstance : function(o) { 1700 return o != null && typeof(o) == "object" && o.isTinyMCE_Control; 1701 }, 1702 1703 getParam : function(name, default_value, strip_whitespace, split_chr) { 1704 var i, outArray, value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name]; 1705 1706 // Fix bool values 1707 if (value == "true" || value == "false") 1708 return (value == "true"); 1709 1710 if (strip_whitespace) 1711 value = tinyMCE.regexpReplace(value, "[ \t\r\n]", ""); 1712 1713 if (typeof(split_chr) != "undefined" && split_chr != null) { 1714 value = value.split(split_chr); 1715 outArray = []; 1716 1717 for (i=0; i<value.length; i++) { 1718 if (value[i] && value[i] !== '') 1719 outArray[outArray.length] = value[i]; 1720 } 1721 1722 value = outArray; 1723 } 1724 1725 return value; 1726 }, 1727 1728 getLang : function(name, default_value, parse_entities, va) { 1729 var v = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name], n; 1730 1731 if (parse_entities) 1732 v = tinyMCE.entityDecode(v); 1733 1734 if (va) { 1735 for (n in va) 1736 v = this.replaceVar(v, n, va[n]); 1737 } 1738 1739 return v; 1740 }, 1741 1742 entityDecode : function(s) { 1743 var e = document.createElement("div"); 1744 1745 e.innerHTML = s; 1746 1747 return !e.firstChild ? s : e.firstChild.nodeValue; 1748 }, 1749 1750 addToLang : function(prefix, ar) { 1751 var k; 1752 1753 for (k in ar) { 1754 if (typeof(ar[k]) == 'function') 1755 continue; 1756 1757 tinyMCELang[(k.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix !== '' ? (prefix + "_") : '') + k] = ar[k]; 1758 } 1759 1760 this.loadNextScript(); 1761 }, 1762 1763 triggerNodeChange : function(focus, setup_content) { 1764 var elm, inst, editorId, undoIndex = -1, undoLevels = -1, doc, anySelection = false, st; 1765 1766 if (tinyMCE.selectedInstance) { 1767 inst = tinyMCE.selectedInstance; 1768 elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement(); 1769 1770 /* if (elm == inst.lastTriggerEl) 1771 return; 1772 1773 inst.lastTriggerEl = elm;*/ 1774 1775 editorId = inst.editorId; 1776 st = inst.selection.getSelectedText(); 1777 1778 if (tinyMCE.settings.auto_resize) 1779 inst.resizeToContent(); 1780 1781 if (setup_content && tinyMCE.isGecko && inst.isHidden()) 1782 elm = inst.getBody(); 1783 1784 inst.switchSettings(); 1785 1786 if (tinyMCE.selectedElement) 1787 anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (st && st.length > 0); 1788 1789 if (tinyMCE.settings.custom_undo_redo) { 1790 undoIndex = inst.undoRedo.undoIndex; 1791 undoLevels = inst.undoRedo.undoLevels.length; 1792 } 1793 1794 tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content); 1795 } 1796 1797 if (this.selectedInstance && (typeof(focus) == "undefined" || focus)) 1798 this.selectedInstance.contentWindow.focus(); 1799 }, 1800 1801 _customCleanup : function(inst, type, content) { 1802 var pl, po, i, customCleanup; 1803 1804 // Call custom cleanup 1805 customCleanup = tinyMCE.settings.cleanup_callback; 1806 if (customCleanup != '') 1807 content = tinyMCE.resolveDots(tinyMCE.settings.cleanup_callback, window)(type, content, inst); 1808 1809 // Trigger theme cleanup 1810 po = tinyMCE.themes[tinyMCE.settings.theme]; 1811 if (po && po.cleanup) 1812 content = po.cleanup(type, content, inst); 1813 1814 // Trigger plugin cleanups 1815 pl = inst.plugins; 1816 for (i=0; i<pl.length; i++) { 1817 po = tinyMCE.plugins[pl[i]]; 1818 1819 if (po && po.cleanup) 1820 content = po.cleanup(type, content, inst); 1821 } 1822 1823 return content; 1824 }, 1825 1826 setContent : function(h) { 1827 if (tinyMCE.selectedInstance) { 1828 tinyMCE.selectedInstance.execCommand('mceSetContent', false, h); 1829 tinyMCE.selectedInstance.repaint(); 1830 } 1831 }, 1832 1833 importThemeLanguagePack : function(name) { 1834 if (typeof(name) == "undefined") 1835 name = tinyMCE.settings.theme; 1836 1837 tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings.language + '.js'); 1838 }, 1839 1840 importPluginLanguagePack : function(name) { 1841 var b = tinyMCE.baseURL + '/plugins/' + name; 1842 1843 if (this.plugins[name]) 1844 b = this.plugins[name].baseURL; 1845 1846 tinyMCE.loadScript(b + '/langs/' + tinyMCE.settings.language + '.js'); 1847 }, 1848 1849 applyTemplate : function(h, ag) { 1850 return h.replace(new RegExp('\\{\\$([a-z0-9_]+)\\}', 'gi'), function(m, s) { 1851 if (s.indexOf('lang_') == 0 && tinyMCELang[s]) 1852 return tinyMCELang[s]; 1853 1854 if (ag && ag[s]) 1855 return ag[s]; 1856 1857 if (tinyMCE.settings[s]) 1858 return tinyMCE.settings[s]; 1859 1860 if (m == 'themeurl') 1861 return tinyMCE.themeURL; 1862 1863 return m; 1864 }); 1865 }, 1866 1867 replaceVar : function(h, r, v) { 1868 return h.replace(new RegExp('{\\\$' + r + '}', 'g'), v); 1869 }, 1870 1871 openWindow : function(template, args) { 1872 var html, width, height, x, y, resizable, scrollbars, url, name, win, modal, features; 1873 1874 args = !args ? {} : args; 1875 1876 args.mce_template_file = template.file; 1877 args.mce_width = template.width; 1878 args.mce_height = template.height; 1879 tinyMCE.windowArgs = args; 1880 1881 html = template.html; 1882 if (!(width = parseInt(template.width))) 1883 width = 320; 1884 1885 if (!(height = parseInt(template.height))) 1886 height = 200; 1887 1888 // Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!! 1889 if (tinyMCE.isIE) 1890 height += 40; 1891 else 1892 height += 20; 1893 1894 x = parseInt(screen.width / 2.0) - (width / 2.0); 1895 y = parseInt(screen.height / 2.0) - (height / 2.0); 1896 1897 resizable = (args && args.resizable) ? args.resizable : "no"; 1898 scrollbars = (args && args.scrollbars) ? args.scrollbars : "no"; 1899 1900 if (template.file.charAt(0) != '/' && template.file.indexOf('://') == -1) 1901 url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template.file; 1902 else 1903 url = template.file; 1904 1905 // Replace all args as variables in URL 1906 for (name in args) { 1907 if (typeof(args[name]) == 'function') 1908 continue; 1909 1910 url = tinyMCE.replaceVar(url, name, escape(args[name])); 1911 } 1912 1913 if (html) { 1914 html = tinyMCE.replaceVar(html, "css", this.settings.popups_css); 1915 html = tinyMCE.applyTemplate(html, args); 1916 1917 win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable); 1918 if (win == null) { 1919 alert(tinyMCELang.lang_popup_blocked); 1920 return; 1921 } 1922 1923 win.document.write(html); 1924 win.document.close(); 1925 win.resizeTo(width, height); 1926 win.focus(); 1927 } else { 1928 if ((tinyMCE.isRealIE) && resizable != 'yes' && tinyMCE.settings.dialog_type == "modal") { 1929 height += 10; 1930 1931 features = "resizable:" + resizable + ";scroll:" + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:" + width + "px;dialogHeight:" + height + "px;"; 1932 1933 window.showModalDialog(url, window, features); 1934 } else { 1935 modal = (resizable == "yes") ? "no" : "yes"; 1936 1937 if (tinyMCE.isGecko && tinyMCE.isMac) 1938 modal = "no"; 1939 1940 if (template.close_previous != "no") 1941 try {tinyMCE.lastWindow.close();} catch (ex) {} 1942 1943 win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable); 1944 if (win == null) { 1945 alert(tinyMCELang.lang_popup_blocked); 1946 return; 1947 } 1948 1949 if (template.close_previous != "no") 1950 tinyMCE.lastWindow = win; 1951 1952 try { 1953 win.resizeTo(width, height); 1954 } catch(e) { 1955 // Ignore 1956 } 1957 1958 // Make it bigger if statusbar is forced 1959 if (tinyMCE.isGecko) { 1960 if (win.document.defaultView.statusbar.visible) 1961 win.resizeBy(0, tinyMCE.isMac ? 10 : 24); 1962 } 1963 1964 win.focus(); 1965 } 1966 } 1967 }, 1968 1969 closeWindow : function(win) { 1970 win.close(); 1971 }, 1972 1973 getVisualAidClass : function(class_name, state) { 1974 var i, classNames, ar, className, aidClass = tinyMCE.settings.visual_table_class; 1975 1976 if (typeof(state) == "undefined") 1977 state = tinyMCE.settings.visual; 1978 1979 // Split 1980 classNames = []; 1981 ar = class_name.split(' '); 1982 for (i=0; i<ar.length; i++) { 1983 if (ar[i] == aidClass) 1984 ar[i] = ""; 1985 1986 if (ar[i] !== '') 1987 classNames[classNames.length] = ar[i]; 1988 } 1989 1990 if (state) 1991 classNames[classNames.length] = aidClass; 1992 1993 // Glue 1994 className = ""; 1995 for (i=0; i<classNames.length; i++) { 1996 if (i > 0) 1997 className += " "; 1998 1999 className += classNames[i]; 2000 } 2001 2002 return className; 2003 }, 2004 2005 handleVisualAid : function(el, deep, state, inst, skip_dispatch) { 2006 var i, x, y, tableElement, anchorName, oldW, oldH, bo, cn; 2007 2008 if (!el) 2009 return; 2010 2011 if (!skip_dispatch) 2012 tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst); 2013 2014 tableElement = null; 2015 2016 switch (el.nodeName) { 2017 case "TABLE": 2018 oldW = el.style.width; 2019 oldH = el.style.height; 2020 bo = tinyMCE.getAttrib(el, "border"); 2021 2022 bo = bo == '' || bo == "0" ? true : false; 2023 2024 tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo)); 2025 2026 el.style.width = oldW; 2027 el.style.height = oldH; 2028 2029 for (y=0; y<el.rows.length; y++) { 2030 for (x=0; x<el.rows[y].cells.length; x++) { 2031 cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo); 2032 tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn); 2033 } 2034 } 2035 2036 break; 2037 2038 case "A": 2039 anchorName = tinyMCE.getAttrib(el, "name"); 2040 2041 if (anchorName !== '' && state) { 2042 el.title = anchorName; 2043 tinyMCE.addCSSClass(el, 'mceItemAnchor'); 2044 } else if (anchorName !== '' && !state) 2045 el.className = ''; 2046 2047 break; 2048 } 2049 2050 if (deep && el.hasChildNodes()) { 2051 for (i=0; i<el.childNodes.length; i++) 2052 tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst, true); 2053 } 2054 }, 2055 2056 fixGeckoBaseHREFBug : function(m, e, h) { 2057 var xsrc, xhref; 2058 2059 if (tinyMCE.isGecko) { 2060 if (m == 1) { 2061 h = h.replace(/\ssrc=/gi, " mce_tsrc="); 2062 h = h.replace(/\shref=/gi, " mce_thref="); 2063 2064 return h; 2065 } else { 2066 // Why bother if there is no src or href broken 2067 if (!new RegExp('(src|href)=', 'g').test(h)) 2068 return h; 2069 2070 // Restore src and href that gets messed up by Gecko 2071 tinyMCE.selectElements(e, 'A,IMG,SELECT,AREA,IFRAME,BASE,INPUT,SCRIPT,EMBED,OBJECT,LINK', function (n) { 2072 xsrc = tinyMCE.getAttrib(n, "mce_tsrc"); 2073 xhref = tinyMCE.getAttrib(n, "mce_thref"); 2074 2075 if (xsrc !== '') { 2076 try { 2077 n.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, xsrc); 2078 } catch (e) { 2079 // Ignore, Firefox cast exception if local file wasn't found 2080 } 2081 2082 n.removeAttribute("mce_tsrc"); 2083 } 2084 2085 if (xhref !== '') { 2086 try { 2087 n.href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, xhref); 2088 } catch (e) { 2089 // Ignore, Firefox cast exception if local file wasn't found 2090 } 2091 2092 n.removeAttribute("mce_thref"); 2093 } 2094 2095 return false; 2096 }); 2097 2098 // Restore text/comment nodes 2099 tinyMCE.selectNodes(e, function(n) { 2100 if (n.nodeType == 3 || n.nodeType == 8) { 2101 n.nodeValue = n.nodeValue.replace(/\smce_tsrc=/gi, " src="); 2102 n.nodeValue = n.nodeValue.replace(/\smce_thref=/gi, " href="); 2103 } 2104 2105 return false; 2106 }); 2107 } 2108 } 2109 2110 return h; 2111 }, 2112 2113 _setHTML : function(doc, html_content) { 2114 var i, html, paras, node; 2115 2116 // Force closed anchors open 2117 //html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>'); 2118 2119 html_content = tinyMCE.cleanupHTMLCode(html_content); 2120 2121 // Try innerHTML if it fails use pasteHTML in MSIE 775 parse : function(s) { 2122 776 try { 2123 tinyMCE.setInnerHTML(doc.body, html_content); 2124 } catch (e) { 2125 if (this.isMSIE) 2126 doc.body.createTextRange().pasteHTML(html_content); 2127 } 2128 2129 // Content duplication bug fix 2130 if (tinyMCE.isIE && tinyMCE.settings.fix_content_duplication) { 2131 // Remove P elements in P elements 2132 paras = doc.getElementsByTagName("P"); 2133 for (i=0; i<paras.length; i++) { 2134 node = paras[i]; 2135 2136 while ((node = node.parentNode) != null) { 2137 if (node.nodeName == "P") 2138 node.outerHTML = node.innerHTML; 2139 } 2140 } 2141 2142 // Content duplication bug fix (Seems to be word crap) 2143 html = doc.body.innerHTML; 2144 2145 // Always set the htmlText output 2146 tinyMCE.setInnerHTML(doc.body, html); 2147 } 2148 2149 tinyMCE.cleanupAnchors(doc); 2150 2151 if (tinyMCE.getParam("convert_fonts_to_spans")) 2152 tinyMCE.convertSpansToFonts(doc); 2153 }, 2154 2155 getEditorId : function(form_element) { 2156 var inst = this.getInstanceById(form_element); 2157 2158 if (!inst) 2159 return null; 2160 2161 return inst.editorId; 2162 }, 2163 2164 getInstanceById : function(editor_id) { 2165 var inst = this.instances[editor_id], n; 2166 2167 if (!inst) { 2168 for (n in tinyMCE.instances) { 2169 inst = tinyMCE.instances[n]; 2170 2171 if (!tinyMCE.isInstance(inst)) 2172 continue; 2173 2174 if (inst.formTargetElementId == editor_id) 2175 return inst; 2176 } 2177 } else 2178 return inst; 2179 2180 return null; 2181 }, 2182 2183 queryInstanceCommandValue : function(editor_id, command) { 2184 var inst = tinyMCE.getInstanceById(editor_id); 2185 2186 if (inst) 2187 return inst.queryCommandValue(command); 2188 2189 return false; 2190 }, 2191 2192 queryInstanceCommandState : function(editor_id, command) { 2193 var inst = tinyMCE.getInstanceById(editor_id); 2194 2195 if (inst) 2196 return inst.queryCommandState(command); 2197 2198 return null; 2199 }, 2200 2201 setWindowArg : function(n, v) { 2202 this.windowArgs[n] = v; 2203 }, 2204 2205 getWindowArg : function(n, d) { 2206 return (typeof(this.windowArgs[n]) == "undefined") ? d : this.windowArgs[n]; 2207 }, 2208 2209 getCSSClasses : function(editor_id, doc) { 2210 var i, c, x, rule, styles, rules, csses, selectorText, inst = tinyMCE.getInstanceById(editor_id); 2211 var cssClass, addClass, p; 2212 2213 if (!inst) 2214 inst = tinyMCE.selectedInstance; 2215 2216 if (!inst) 2217 return []; 2218 2219 if (!doc) 2220 doc = inst.getDoc(); 2221 2222 // Is cached, use that 2223 if (inst && inst.cssClasses.length > 0) 2224 return inst.cssClasses; 2225 2226 if (!doc) 2227 return; 2228 2229 styles = doc.styleSheets; 2230 2231 if (styles && styles.length > 0) { 2232 for (x=0; x<styles.length; x++) { 2233 csses = null; 2234 2235 try { 2236 csses = tinyMCE.isIE ? doc.styleSheets(x).rules : styles[x].cssRules; 2237 } catch(e) { 2238 // Just ignore any errors I know this is ugly!! 2239 } 2240 2241 if (!csses) 2242 return []; 2243 2244 for (i=0; i<csses.length; i++) { 2245 selectorText = csses[i].selectorText; 2246 2247 // Can be multiple rules per selector 2248 if (selectorText) { 2249 rules = selectorText.split(','); 2250 for (c=0; c<rules.length; c++) { 2251 rule = rules[c]; 2252 2253 // Strip spaces between selectors 2254 while (rule.indexOf(' ') == 0) 2255 rule = rule.substring(1); 2256 2257 // Invalid rule 2258 if (rule.indexOf(' ') != -1 || rule.indexOf(':') != -1 || rule.indexOf('mceItem') != -1) 2259 continue; 2260 2261 if (rule.indexOf(tinyMCE.settings.visual_table_class) != -1 || rule.indexOf('mceEditable') != -1 || rule.indexOf('mceNonEditable') != -1) 2262 continue; 2263 2264 // Is class rule 2265 if (rule.indexOf('.') != -1) { 2266 cssClass = rule.substring(rule.indexOf('.') + 1); 2267 addClass = true; 2268 2269 for (p=0; p<inst.cssClasses.length && addClass; p++) { 2270 if (inst.cssClasses[p] == cssClass) 2271 addClass = false; 2272 } 2273 2274 if (addClass) 2275 inst.cssClasses[inst.cssClasses.length] = cssClass; 2276 } 2277 } 2278 } 2279 } 2280 } 2281 } 2282 2283 return inst.cssClasses; 2284 }, 2285 2286 regexpReplace : function(in_str, reg_exp, replace_str, opts) { 2287 var re; 2288 2289 if (in_str == null) 2290 return in_str; 2291 2292 if (typeof(opts) == "undefined") 2293 opts = 'g'; 2294 2295 re = new RegExp(reg_exp, opts); 2296 2297 return in_str.replace(re, replace_str); 2298 }, 2299 2300 trim : function(s) { 2301 return s.replace(/^\s*|\s*$/g, ""); 2302 }, 2303 2304 cleanupEventStr : function(s) { 2305 s = "" + s; 2306 s = s.replace('function anonymous()\n{\n', ''); 2307 s = s.replace('\n}', ''); 2308 s = s.replace(/^return true;/gi, ''); // Remove event blocker 2309 2310 return s; 2311 }, 2312 2313 getControlHTML : function(c) { 2314 var i, l, n, o, v, rtl = tinyMCE.getLang('lang_dir') == 'rtl'; 2315 2316 l = tinyMCE.plugins; 2317 for (n in l) { 2318 o = l[n]; 2319 2320 if (o.getControlHTML && (v = o.getControlHTML(c)) !== '') { 2321 if (rtl) 2322 return '<span dir="rtl">' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + '</span>'; 2323 2324 return tinyMCE.replaceVar(v, "pluginurl", o.baseURL); 2325 } 2326 } 2327 2328 o = tinyMCE.themes[tinyMCE.settings.theme]; 2329 if (o.getControlHTML && (v = o.getControlHTML(c)) !== '') { 2330 if (rtl) 2331 return '<span dir="rtl">' + v + '</span>'; 2332 2333 return v; 2334 } 2335 2336 return ''; 2337 }, 2338 2339 evalFunc : function(f, idx, a, o) { 2340 o = !o ? window : o; 2341 f = typeof(f) == 'function' ? f : o[f]; 2342 2343 return f.apply(o, Array.prototype.slice.call(a, idx)); 2344 }, 2345 2346 dispatchCallback : function(i, p, n) { 2347 return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments); 2348 }, 2349 2350 executeCallback : function(i, p, n) { 2351 return this.callFunc(i, p, n, 1, this.executeCallback.arguments); 2352 }, 2353 2354 execCommandCallback : function(i, p, n) { 2355 return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments); 2356 }, 2357 2358 callFunc : function(ins, p, n, m, a) { 2359 var l, i, on, o, s, v; 2360 2361 s = m == 2; 2362 2363 l = tinyMCE.getParam(p, ''); 2364 2365 if (l !== '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0) 2366 return true; 2367 2368 if (ins != null) { 2369 for (i=0, l = ins.plugins; i<l.length; i++) { 2370 o = tinyMCE.plugins[l[i]]; 2371 2372 if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0) 2373 return true; 2374 } 2375 } 2376 2377 l = tinyMCE.themes; 2378 for (on in l) { 2379 o = l[on]; 2380 2381 if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0) 2382 return true; 2383 } 2384 2385 return false; 2386 }, 2387 2388 resolveDots : function(s, o) { 2389 var i; 2390 2391 if (typeof(s) == 'string') { 2392 for (i=0, s=s.split('.'); i<s.length; i++) 2393 o = o[s[i]]; 2394 } else 2395 o = s; 2396 2397 return o; 2398 }, 2399 2400 xmlEncode : function(s) { 2401 return s ? ('' + s).replace(this.xmlEncodeRe, function (c, b) { 2402 switch (c) { 2403 case '&': 2404 return '&'; 2405 2406 case '"': 2407 return '"'; 2408 2409 case '<': 2410 return '<'; 2411 2412 case '>': 2413 return '>'; 2414 } 2415 2416 return c; 2417 }) : s; 2418 }, 2419 2420 add : function(c, m) { 2421 var n; 2422 2423 for (n in m) 2424 c.prototype[n] = m[n]; 2425 }, 2426 2427 extend : function(p, np) { 2428 var o = {}, n; 2429 2430 o.parent = p; 2431 2432 for (n in p) 2433 o[n] = p[n]; 2434 2435 for (n in np) 2436 o[n] = np[n]; 2437 2438 return o; 2439 }, 2440 2441 hideMenus : function() { 2442 var e = tinyMCE.lastSelectedMenuBtn; 2443 2444 if (tinyMCE.lastMenu) { 2445 tinyMCE.lastMenu.hide(); 2446 tinyMCE.lastMenu = null; 2447 } 2448 2449 if (e) { 2450 tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass); 2451 tinyMCE.lastSelectedMenuBtn = null; 2452 } 2453 } 2454 2455 }; 2456 2457 // Global instances 2458 var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors 2459 var tinyMCE = new TinyMCE_Engine(); 2460 var tinyMCELang = {}; 2461 2462 /* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */ 2463 2464 function TinyMCE_Control(settings) { 2465 var t, i, tos, fu, p, x, fn, fu, pn, s = settings; 2466 2467 this.undoRedoLevel = true; 2468 this.isTinyMCE_Control = true; 2469 2470 // Default settings 2471 this.enabled = true; 2472 this.settings = s; 2473 this.settings.theme = tinyMCE.getParam("theme", "default"); 2474 this.settings.width = tinyMCE.getParam("width", -1); 2475 this.settings.height = tinyMCE.getParam("height", -1); 2476 this.selection = new TinyMCE_Selection(this); 2477 this.undoRedo = new TinyMCE_UndoRedo(this); 2478 this.cleanup = new TinyMCE_Cleanup(); 2479 this.shortcuts = []; 2480 this.hasMouseMoved = false; 2481 this.foreColor = this.backColor = "#999999"; 2482 this.data = {}; 2483 this.cssClasses = []; 2484 2485 this.cleanup.init({ 2486 valid_elements : s.valid_elements, 2487 extended_valid_elements : s.extended_valid_elements, 2488 valid_child_elements : s.valid_child_elements, 2489 entities : s.entities, 2490 entity_encoding : s.entity_encoding, 2491 debug : s.cleanup_debug, 2492 indent : s.apply_source_formatting, 2493 invalid_elements : s.invalid_elements, 2494 verify_html : s.verify_html, 2495 fix_content_duplication : s.fix_content_duplication, 2496 convert_fonts_to_spans : s.convert_fonts_to_spans 2497 }); 2498 2499 // Wrap old theme 2500 t = this.settings.theme; 2501 if (!tinyMCE.hasTheme(t)) { 2502 fn = tinyMCE.callbacks; 2503 tos = {}; 2504 2505 for (i=0; i<fn.length; i++) { 2506 if ((fu = window['TinyMCE_' + t + "_" + fn[i]])) 2507 tos[fn[i]] = fu; 2508 } 2509 2510 tinyMCE.addTheme(t, tos); 2511 } 2512 2513 // Wrap old plugins 2514 this.plugins = []; 2515 p = tinyMCE.getParam('plugins', '', true, ','); 2516 if (p.length > 0) { 2517 for (i=0; i<p.length; i++) { 2518 pn = p[i]; 2519 2520 if (pn.charAt(0) == '-') 2521 pn = pn.substring(1); 2522 2523 if (!tinyMCE.hasPlugin(pn)) { 2524 fn = tinyMCE.callbacks; 2525 tos = {}; 2526 2527 for (x=0; x<fn.length; x++) { 2528 if ((fu = window['TinyMCE_' + pn + "_" + fn[x]])) 2529 tos[fn[x]] = fu; 2530 } 2531 2532 tinyMCE.addPlugin(pn, tos); 2533 } 2534 2535 this.plugins[this.plugins.length] = pn; 2536 } 2537 } 2538 }; 2539 2540 TinyMCE_Control.prototype = { 2541 selection : null, 2542 2543 settings : null, 2544 2545 cleanup : null, 2546 2547 getData : function(na) { 2548 var o = this.data[na]; 2549 2550 if (!o) 2551 o = this.data[na] = {}; 2552 2553 return o; 2554 }, 2555 2556 hasPlugin : function(n) { 2557 var i; 2558 2559 for (i=0; i<this.plugins.length; i++) { 2560 if (this.plugins[i] == n) 2561 return true; 2562 } 2563 2564 return false; 2565 }, 2566 2567 addPlugin : function(n, p) { 2568 if (!this.hasPlugin(n)) { 2569 tinyMCE.addPlugin(n, p); 2570 this.plugins[this.plugins.length] = n; 2571 } 2572 }, 2573 2574 repaint : function() { 2575 var s, b, ex; 2576 2577 if (tinyMCE.isRealIE) 2578 return; 2579 2580 try { 2581 s = this.selection; 2582 b = s.getBookmark(true); 2583 this.getBody().style.display = 'none'; 2584 this.getDoc().execCommand('selectall', false, null); 2585 this.getSel().collapseToStart(); 2586 this.getBody().style.display = 'block'; 2587 s.moveToBookmark(b); 777 return eval('(' + s + ')'); 2588 778 } catch (ex) { 2589 779 // Ignore 2590 780 } 2591 }, 2592 2593 switchSettings : function() { 2594 if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings.index) { 2595 tinyMCE.settings = this.settings; 2596 tinyMCE.currentConfig = this.settings.index; 781 } 782 783 }); 784 785 /* file:jscripts/tiny_mce/classes/util/XHR.js */ 786 787 tinymce.create('static tinymce.util.XHR', { 788 send : function(o) { 789 var x, t, w = window, c = 0; 790 791 // Default settings 792 o.scope = o.scope || this; 793 o.success_scope = o.success_scope || o.scope; 794 o.error_scope = o.error_scope || o.scope; 795 o.async = o.async === false ? false : true; 796 o.data = o.data || ''; 797 798 function get(s) { 799 x = 0; 800 801 try { 802 x = new ActiveXObject(s); 803 } catch (ex) { 804 } 805 806 return x; 807 }; 808 809 x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP'); 810 811 if (x) { 812 if (x.overrideMimeType) 813 x.overrideMimeType(o.content_type); 814 815 x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async); 816 817 if (o.content_type) 818 x.setRequestHeader('Content-Type', o.content_type); 819 820 x.send(o.data); 821 822 // Wait for response, onReadyStateChange can not be used since it leaks memory in IE 823 t = w.setInterval(function() { 824 if (x.readyState == 4 || c++ > 10000) { 825 w.clearInterval(t); 826 827 if (o.success && c < 10000 && x.status == 200) 828 o.success.call(o.success_scope, '' + x.responseText, x, o); 829 else if (o.error) 830 o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o); 831 832 x = null; 833 } 834 }, 10); 2597 835 } 2598 }, 2599 2600 select : function() { 2601 var oldInst = tinyMCE.selectedInstance; 2602 2603 if (oldInst != this) { 2604 if (oldInst) 2605 oldInst.execCommand('mceEndTyping'); 2606 2607 tinyMCE.dispatchCallback(this, 'select_instance_callback', 'selectInstance', this, oldInst); 2608 tinyMCE.selectedInstance = this; 836 2609 837 } 2610 }, 2611 2612 getBody : function() { 2613 return this.contentBody ? this.contentBody : this.getDoc().body; 2614 }, 2615 2616 getDoc : function() { 2617 // return this.contentDocument ? this.contentDocument : this.contentWindow.document; // Removed due to IE 5.5 ? 2618 return this.contentWindow.document; 2619 }, 2620 2621 getWin : function() { 2622 return this.contentWindow; 2623 }, 2624 2625 getContainerWin : function() { 2626 return this.containerWindow ? this.containerWindow : window; 2627 }, 2628 2629 getViewPort : function() { 2630 return tinyMCE.getViewPort(this.getWin()); 2631 }, 2632 2633 getParentNode : function(n, f) { 2634 return tinyMCE.getParentNode(n, f, this.getBody()); 2635 }, 2636 2637 getParentElement : function(n, na, f) { 2638 return tinyMCE.getParentElement(n, na, f, this.getBody()); 2639 }, 2640 2641 getParentBlockElement : function(n) { 2642 return tinyMCE.getParentBlockElement(n, this.getBody()); 2643 }, 2644 2645 resizeToContent : function() { 2646 var d = this.getDoc(), b = d.body, de = d.documentElement; 2647 2648 this.iframeElement.style.height = (tinyMCE.isRealIE) ? b.scrollHeight : de.offsetHeight + 'px'; 2649 }, 2650 2651 addShortcut : function(m, k, d, cmd, ui, va) { 2652 var n = typeof(k) == "number", ie = tinyMCE.isIE, c, sc, i, scl = this.shortcuts; 2653 2654 if (!tinyMCE.getParam('custom_shortcuts')) 2655 return false; 2656 2657 m = m.toLowerCase(); 2658 k = ie && !n ? k.toUpperCase() : k; 2659 c = n ? null : k.charCodeAt(0); 2660 d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d; 2661 2662 sc = { 2663 alt : m.indexOf('alt') != -1, 2664 ctrl : m.indexOf('ctrl') != -1, 2665 shift : m.indexOf('shift') != -1, 2666 charCode : c, 2667 keyCode : n ? k : (ie ? c : null), 2668 desc : d, 2669 cmd : cmd, 2670 ui : ui, 2671 val : va 2672 }; 2673 2674 for (i=0; i<scl.length; i++) { 2675 if (sc.alt == scl[i].alt && sc.ctrl == scl[i].ctrl && sc.shift == scl[i].shift 2676 && sc.charCode == scl[i].charCode && sc.keyCode == scl[i].keyCode) { 2677 return false; 838 }); 839 840 /* file:jscripts/tiny_mce/classes/util/JSONRequest.js */ 841 842 (function() { 843 var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR; 844 845 tinymce.create('tinymce.util.JSONRequest', { 846 JSONRequest : function(s) { 847 this.settings = extend({ 848 }, s); 849 this.count = 0; 850 }, 851 852 send : function(o) { 853 var ecb = o.error, scb = o.success; 854 855 o = extend(this.settings, o); 856 857 o.success = function(c, x) { 858 c = JSON.parse(c); 859 860 if (typeof(c) == 'undefined') { 861 c = { 862 error : 'JSON Parse error.' 863 }; 864 } 865 866 if (c.error) 867 ecb.call(o.error_scope || o.scope, c.error, x); 868 else 869 scb.call(o.success_scope || o.scope, c.result); 870 }; 871 872 o.error = function(ty, x) { 873 ecb.call(o.error_scope || o.scope, ty, x); 874 }; 875 876 o.data = JSON.serialize({ 877 id : o.id || 'c' + (this.count++), 878 method : o.method, 879 params : o.params 880 }); 881 882 XHR.send(o); 883 }, 884 885 'static' : { 886 sendRPC : function(o) { 887 return new tinymce.util.JSONRequest().send(o); 2678 888 } 2679 889 } 2680 890 2681 scl[scl.length] = sc; 2682 2683 return true; 2684 }, 2685 2686 handleShortcut : function(e) { 2687 var i, s, o; 2688 2689 // Normal key press, then ignore it 2690 if (!e.altKey && !e.ctrlKey) 2691 return false; 2692 2693 s = this.shortcuts; 2694 2695 for (i=0; i<s.length; i++) { 2696 o = s[i]; 2697 2698 if (o.alt == e.altKey && o.ctrl == e.ctrlKey && (o.keyCode == e.keyCode || o.charCode == e.charCode)) { 2699 if (o.cmd && (e.type == "keydown" || (e.type == "keypress" && !tinyMCE.isOpera))) 2700 tinyMCE.execCommand(o.cmd, o.ui, o.val); 2701 2702 tinyMCE.cancelEvent(e); 2703 return true; 2704 } 2705 } 2706 2707 return false; 2708 }, 2709 2710 autoResetDesignMode : function() { 2711 // Add fix for tab/style.display none/block problems in Gecko 2712 if (!tinyMCE.isIE && this.isHidden() && tinyMCE.getParam('auto_reset_designmode')) 2713 eval('try { this.getDoc().designMode = "On"; this.useCSS = false; } catch(e) {}'); 2714 }, 2715 2716 isHidden : function() { 2717 var s; 2718 2719 if (tinyMCE.isIE) 2720 return false; 2721 2722 s = this.getSel(); 2723 2724 // Weird, wheres that cursor selection? 2725 return (!s || !s.rangeCount || s.rangeCount == 0); 2726 }, 2727 2728 isDirty : function() { 2729 // Is content modified and not in a submit procedure 2730 return tinyMCE.trim(this.startContent) != tinyMCE.trim(this.getBody().innerHTML) && !this.isNotDirty; 2731 }, 2732 2733 _mergeElements : function(scmd, pa, ch, override) { 2734 var st, stc, className, n; 2735 2736 if (scmd == "removeformat") { 2737 pa.className = ""; 2738 pa.style.cssText = ""; 2739 ch.className = ""; 2740 ch.style.cssText = ""; 2741 return; 2742 } 2743 2744 st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style")); 2745 stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style")); 2746 className = tinyMCE.getAttrib(pa, "class"); 2747 2748 // Removed class adding due to bug #1478272 2749 className = tinyMCE.getAttrib(ch, "class"); 2750 2751 if (override) { 2752 for (n in st) { 2753 if (typeof(st[n]) == 'function') 2754 continue; 2755 2756 stc[n] = st[n]; 2757 } 2758 } else { 2759 for (n in stc) { 2760 if (typeof(stc[n]) == 'function') 2761 continue; 2762 2763 st[n] = stc[n]; 2764 } 2765 } 2766 2767 tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st)); 2768 tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className)); 2769 ch.className = ""; 2770 ch.style.cssText = ""; 2771 ch.removeAttribute("class"); 2772 ch.removeAttribute("style"); 2773 }, 2774 2775 _fixRootBlocks : function() { 2776 var rb, b, ne, be, nx, bm; 2777 2778 rb = tinyMCE.getParam('forced_root_block'); 2779 if (!rb) 2780 return; 2781 2782 b = this.getBody(); 2783 ne = b.firstChild; 2784 2785 while (ne) { 2786 nx = ne.nextSibling; 2787 2788 // If text node or inline element wrap it in a block element 2789 if (ne.nodeType == 3 || !tinyMCE.blockRegExp.test(ne.nodeName)) { 2790 if (!bm) 2791 bm = this.selection.getBookmark(); 2792 2793 if (!be) { 2794 be = this.getDoc().createElement(rb); 2795 be.appendChild(ne.cloneNode(true)); 2796 b.replaceChild(be, ne); 2797 } else { 2798 be.appendChild(ne.cloneNode(true)); 2799 b.removeChild(ne); 2800 } 2801 } else 2802 be = null; 2803 2804 ne = nx; 2805 } 2806 2807 if (bm) 2808 this.selection.moveToBookmark(bm); 2809 }, 2810 2811 _fixTrailingNbsp : function() { 2812 var s = this.selection, e = s.getFocusElement(), bm, v; 2813 2814 if (e && tinyMCE.blockRegExp.test(e.nodeName) && e.firstChild) { 2815 v = e.firstChild.nodeValue; 2816 2817 if (v && v.length > 1 && /(^\u00a0|\u00a0$)/.test(v)) { 2818 e.firstChild.nodeValue = v.replace(/(^\u00a0|\u00a0$)/, ''); 2819 s.selectNode(e.firstChild, true, false, false); // Select and collapse 2820 } 2821 } 2822 }, 2823 2824 _setUseCSS : function(b) { 2825 var d = this.getDoc(); 2826 2827 try {d.execCommand("useCSS", false, !b);} catch (ex) {} 2828 try {d.execCommand("styleWithCSS", false, b);} catch (ex) {} 2829 2830 if (!tinyMCE.getParam("table_inline_editing")) 2831 try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {} 2832 2833 if (!tinyMCE.getParam("object_resizing")) 2834 try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {} 2835 }, 2836 2837 execCommand : function(command, user_interface, value) { 2838 var i, x, z, align, img, div, doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement(); 2839 2840 // Is not a undo specific command 2841 if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) 2842 this.undoBookmark = null; 2843 2844 // Mozilla issue 2845 if (!tinyMCE.isIE && !this.useCSS) { 2846 this._setUseCSS(false); 2847 this.useCSS = true; 2848 } 2849 2850 //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value); 2851 this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks 2852 2853 // Don't dispatch key commands 2854 if (!/mceStartTyping|mceEndTyping/.test(command)) { 2855 if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value)) 2856 return; 2857 } 2858 2859 // Fix align on images 2860 if (focusElm && focusElm.nodeName == "IMG") { 2861 align = focusElm.getAttribute('align'); 2862 img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm; 2863 2864 switch (command) { 2865 case "JustifyLeft": 2866 if (align == 'left') 2867 img.removeAttribute('align'); 2868 else 2869 img.setAttribute('align', 'left'); 2870 2871 // Remove the div 2872 div = focusElm.parentNode; 2873 if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) 2874 div.parentNode.replaceChild(img, div); 2875 2876 this.selection.selectNode(img); 2877 this.repaint(); 2878 tinyMCE.triggerNodeChange(); 2879 return; 2880 2881 case "JustifyCenter": 2882 img.removeAttribute('align'); 2883 2884 // Is centered 2885 div = tinyMCE.getParentElement(focusElm, "div"); 2886 if (div && div.style.textAlign == "center") { 2887 // Remove div 2888 if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) 2889 div.parentNode.replaceChild(img, div); 2890 } else { 2891 // Add div 2892 div = this.getDoc().createElement("div"); 2893 div.style.textAlign = 'center'; 2894 div.appendChild(img); 2895 focusElm.parentNode.replaceChild(div, focusElm); 891 }); 892 }()); 893 /* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */ 894 895 (function() { 896 // Shorten names 897 var each = tinymce.each, is = tinymce.is; 898 var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE; 899 900 tinymce.create('tinymce.dom.DOMUtils', { 901 doc : null, 902 root : null, 903 files : null, 904 listeners : {}, 905 pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/, 906 cache : {}, 907 idPattern : /^#[\w]+$/, 908 elmPattern : /^[\w_*]+$/, 909 elmClassPattern : /^([\w_]*)\.([\w_]+)$/, 910 911 DOMUtils : function(d, s) { 912 var t = this; 913 914 t.doc = d; 915 t.files = {}; 916 t.cssFlicker = false; 917 t.counter = 0; 918 t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 919 920 this.settings = s = tinymce.extend({ 921 keep_values : false, 922 hex_colors : 1 923 }, s); 924 925 // Fix IE6SP2 flicker and check it failed for pre SP2 926 if (tinymce.isIE6) { 927 try { 928 d.execCommand('BackgroundImageCache', false, true); 929 } catch (e) { 930 t.cssFlicker = true; 931 } 932 } 933 934 tinymce.addUnload(function() { 935 t.doc = t.root = null; 936 }); 937 }, 938 939 getRoot : function() { 940 var t = this, s = t.settings; 941 942 return (s && t.get(s.root_element)) || t.doc.body; 943 }, 944 945 getViewPort : function(w) { 946 var d, b; 947 948 w = !w ? window : w; 949 d = w.document; 950 b = this.boxModel ? d.documentElement : d.body; 951 952 // Returns viewport size excluding scrollbars 953 return { 954 x : w.pageXOffset || b.scrollLeft, 955 y : w.pageYOffset || b.scrollTop, 956 w : w.innerWidth || b.clientWidth, 957 h : w.innerHeight || b.clientHeight 958 }; 959 }, 960 961 getRect : function(e) { 962 var p, t = this, w, h; 963 964 e = t.get(e); 965 p = t.getPos(e); 966 w = t.getStyle(e, 'width'); 967 h = t.getStyle(e, 'height'); 968 969 // Non pixel value, then force offset/clientWidth 970 if (w.indexOf('px') === -1) 971 w = 0; 972 973 // Non pixel value, then force offset/clientWidth 974 if (h.indexOf('px') === -1) 975 h = 0; 976 977 return { 978 x : p.x, 979 y : p.y, 980 w : parseInt(w) || e.offsetWidth || e.clientWidth, 981 h : parseInt(h) || e.offsetHeight || e.clientHeight 982 }; 983 }, 984 985 getParent : function(n, f, r) { 986 var na, se = this.settings; 987 988 n = this.get(n); 989 990 if (se.strict_root) 991 r = r || this.getRoot(); 992 993 // Wrap node name as func 994 if (is(f, 'string')) { 995 na = f.toUpperCase(); 996 997 f = function(n) { 998 var s = false; 999 1000 // Any element 1001 if (n.nodeType == 1 && na === '*') { 1002 s = true; 1003 return false; 2896 1004 } 2897 1005 2898 this.selection.selectNode(img); 2899 this.repaint(); 2900 tinyMCE.triggerNodeChange(); 2901 return; 2902 2903 case "JustifyRight": 2904 if (align == 'right') 2905 img.removeAttribute('align'); 2906 else 2907 img.setAttribute('align', 'right'); 2908 2909 // Remove the div 2910 div = focusElm.parentNode; 2911 if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) 2912 div.parentNode.replaceChild(img, div); 2913 2914 this.selection.selectNode(img); 2915 this.repaint(); 2916 tinyMCE.triggerNodeChange(); 2917 return; 2918 } 2919 } 2920 2921 if (tinyMCE.settings.force_br_newlines) { 2922 var alignValue = ""; 2923 2924 if (doc.selection.type != "Control") { 2925 switch (command) { 2926 case "JustifyLeft": 2927 alignValue = "left"; 2928 break; 2929 2930 case "JustifyCenter": 2931 alignValue = "center"; 2932 break; 2933 2934 case "JustifyFull": 2935 alignValue = "justify"; 2936 break; 2937 2938 case "JustifyRight": 2939 alignValue = "right"; 2940 break; 2941 } 2942 2943 if (alignValue !== '') { 2944 var rng = doc.selection.createRange(); 2945 2946 if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null) 2947 divElm.setAttribute("align", alignValue); 2948 else if (rng.pasteHTML && rng.htmlText.length > 0) 2949 rng.pasteHTML('<div align="' + alignValue + '">' + rng.htmlText + "</div>"); 2950 2951 tinyMCE.triggerNodeChange(); 2952 return; 2953 } 2954 } 2955 } 2956 2957 switch (command) { 2958 case "mceRepaint": 2959 this.repaint(); 2960 return true; 2961 2962 case "unlink": 2963 // Unlink if caret is inside link 2964 if (tinyMCE.isGecko && this.getSel().isCollapsed) { 2965 focusElm = tinyMCE.getParentElement(focusElm, 'A'); 2966 2967 if (focusElm) 2968 this.selection.selectNode(focusElm, false); 2969 } 2970 2971 this.getDoc().execCommand(command, user_interface, value); 2972 2973 tinyMCE.isGecko && this.getSel().collapseToEnd(); 2974 2975 tinyMCE.triggerNodeChange(); 2976 2977 return true; 2978 2979 case "InsertUnorderedList": 2980 case "InsertOrderedList": 2981 this.getDoc().execCommand(command, user_interface, value); 2982 tinyMCE.triggerNodeChange(); 2983 break; 2984 2985 case "Strikethrough": 2986 this.getDoc().execCommand(command, user_interface, value); 2987 tinyMCE.triggerNodeChange(); 2988 break; 2989 2990 case "mceSelectNode": 2991 this.selection.selectNode(value); 2992 tinyMCE.triggerNodeChange(); 2993 tinyMCE.selectedNode = value; 2994 break; 2995 2996 case "FormatBlock": 2997 if (value == null || value == '') { 2998 var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp"); 2999 3000 if (elm) 3001 this.execCommand("mceRemoveNode", false, elm); 3002 } else { 3003 if (!this.cleanup.isValid(value)) 3004 return true; 3005 3006 if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) 3007 value = value.replace(/[^a-z]/gi, ''); 3008 3009 if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) { 3010 var b = this.selection.getBookmark(); 3011 this.getDoc().execCommand("FormatBlock", false, '<p>'); 3012 tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value); 3013 this.selection.moveToBookmark(b); 3014 } else 3015 this.getDoc().execCommand("FormatBlock", false, value); 3016 } 3017 3018 tinyMCE.triggerNodeChange(); 3019 3020 break; 3021 3022 case "mceRemoveNode": 3023 if (!value) 3024 value = tinyMCE.getParentElement(this.getFocusElement()); 3025 3026 if (tinyMCE.isIE) { 3027 value.outerHTML = value.innerHTML; 3028 } else { 3029 var rng = value.ownerDocument.createRange(); 3030 rng.setStartBefore(value); 3031 rng.setEndAfter(value); 3032 rng.deleteContents(); 3033 rng.insertNode(rng.createContextualFragment(value.innerHTML)); 3034 } 3035 3036 tinyMCE.triggerNodeChange(); 3037 3038 break; 3039 3040 case "mceSelectNodeDepth": 3041 var parentNode = this.getFocusElement(); 3042 for (i=0; parentNode; i++) { 3043 if (parentNode.nodeName.toLowerCase() == "body") 3044 break; 3045 3046 if (parentNode.nodeName.toLowerCase() == "#text") { 3047 i--; 3048 parentNode = parentNode.parentNode; 3049 continue; 3050 } 3051 3052 if (i == value) { 3053 this.selection.selectNode(parentNode, false); 3054 tinyMCE.triggerNodeChange(); 3055 tinyMCE.selectedNode = parentNode; 3056 return; 3057 } 3058 3059 parentNode = parentNode.parentNode; 3060 } 3061 3062 break; 3063 3064 case "mceSetStyleInfo": 3065 case "SetStyleInfo": 3066 var rng = this.getRng(); 3067 var sel = this.getSel(); 3068 var scmd = value.command; 3069 var sname = value.name; 3070 var svalue = value.value == null ? '' : value.value; 3071 //var svalue = value['value'] == null ? '' : value['value']; 3072 var wrapper = value.wrapper ? value.wrapper : "span"; 3073 var parentElm = null; 3074 var invalidRe = new RegExp("^BODY|HTML$", "g"); 3075 var invalidParentsRe = tinyMCE.settings.merge_styles_invalid_parents !== '' ? new RegExp(tinyMCE.settings.merge_styles_invalid_parents, "gi") : null; 3076 3077 // Whole element selected check 3078 if (tinyMCE.isIE) { 3079 // Control range 3080 if (rng.item) 3081 parentElm = rng.item(0); 3082 else { 3083 var pelm = rng.parentElement(); 3084 var prng = doc.selection.createRange(); 3085 prng.moveToElementText(pelm); 3086 3087 if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) { 3088 if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName)) 3089 parentElm = pelm; 1006 each(na.split(','), function(v) { 1007 if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName == v)) { 1008 s = true; 1009 return false; // Break loop 3090 1010 } 3091 } 3092 } else { 3093 var felm = this.getFocusElement(); 3094 if (sel.isCollapsed || (new RegExp('td|tr|tbody|table|img', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode)) 3095 parentElm = felm; 3096 } 3097 3098 // Whole element selected 3099 if (parentElm && !invalidRe.test(parentElm.nodeName)) { 3100 if (scmd == "setstyle") 3101 tinyMCE.setStyleAttrib(parentElm, sname, svalue); 3102 3103 if (scmd == "setattrib") 3104 tinyMCE.setAttrib(parentElm, sname, svalue); 3105 3106 if (scmd == "removeformat") { 3107 parentElm.style.cssText = ''; 3108 tinyMCE.setAttrib(parentElm, 'class', ''); 3109 } 3110 3111 // Remove style/attribs from all children 3112 var ch = tinyMCE.getNodeTree(parentElm, [], 1); 3113 for (z=0; z<ch.length; z++) { 3114 if (ch[z] == parentElm) 3115 continue; 3116 3117 if (scmd == "setstyle") 3118 tinyMCE.setStyleAttrib(ch[z], sname, ''); 3119 3120 if (scmd == "setattrib") 3121 tinyMCE.setAttrib(ch[z], sname, ''); 3122 3123 if (scmd == "removeformat") { 3124 ch[z].style.cssText = ''; 3125 tinyMCE.setAttrib(ch[z], 'class', ''); 3126 } 3127 } 3128 } else { 3129 this._setUseCSS(false); // Bug in FF when running in fullscreen 3130 doc.execCommand("FontName", false, "#mce_temp_font#"); 3131 var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#"); 3132 3133 // Change them all 3134 for (x=0; x<elementArray.length; x++) { 3135 elm = elementArray[x]; 3136 if (elm) { 3137 var spanElm = doc.createElement(wrapper); 3138 3139 if (scmd == "setstyle") 3140 tinyMCE.setStyleAttrib(spanElm, sname, svalue); 3141 3142 if (scmd == "setattrib") 3143 tinyMCE.setAttrib(spanElm, sname, svalue); 3144 3145 if (scmd == "removeformat") { 3146 spanElm.style.cssText = ''; 3147 tinyMCE.setAttrib(spanElm, 'class', ''); 3148 } 3149 3150 if (elm.hasChildNodes()) { 3151 for (i=0; i<elm.childNodes.length; i++) 3152 spanElm.appendChild(elm.childNodes[i].cloneNode(true)); 3153 } 3154 3155 spanElm.setAttribute("mce_new", "true"); 3156 elm.parentNode.replaceChild(spanElm, elm); 3157 3158 // Remove style/attribs from all children 3159 var ch = tinyMCE.getNodeTree(spanElm, [], 1); 3160 for (z=0; z<ch.length; z++) { 3161 if (ch[z] == spanElm) 3162 continue; 3163 3164 if (scmd == "setstyle") 3165 tinyMCE.setStyleAttrib(ch[z], sname, ''); 3166 3167 if (scmd == "setattrib") 3168 tinyMCE.setAttrib(ch[z], sname, ''); 3169 3170 if (scmd == "removeformat") { 3171 ch[z].style.cssText = ''; 3172 tinyMCE.setAttrib(ch[z], 'class', ''); 3173 } 3174 } 3175 } 3176 } 3177 } 3178 3179 // Cleaup wrappers 3180 var nodes = doc.getElementsByTagName(wrapper); 3181 for (i=nodes.length-1; i>=0; i--) { 3182 var elm = nodes[i]; 3183 var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true"; 3184 3185 elm.removeAttribute("mce_new"); 3186 3187 // Is only child a element 3188 if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) { 3189 //tinyMCE.debug("merge1" + isNew); 3190 this._mergeElements(scmd, elm, elm.childNodes[0], isNew); 3191 continue; 3192 } 3193 3194 // Is I the only child 3195 if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) { 3196 //tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName); 3197 if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName)) 3198 this._mergeElements(scmd, elm.parentNode, elm, false); 3199 } 3200 } 3201 3202 // Remove empty wrappers 3203 var nodes = doc.getElementsByTagName(wrapper); 3204 for (i=nodes.length-1; i>=0; i--) { 3205 var elm = nodes[i], isEmpty = true; 3206 3207 // Check if it has any attribs 3208 var tmp = doc.createElement("body"); 3209 tmp.appendChild(elm.cloneNode(false)); 3210 3211 // Is empty span, remove it 3212 tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), ''); 3213 //tinyMCE.debug(tmp.innerHTML); 3214 if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) { 3215 for (x=0; x<elm.childNodes.length; x++) { 3216 if (elm.parentNode != null) 3217 elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm); 3218 } 3219 3220 elm.parentNode.removeChild(elm); 3221 } 3222 } 3223 3224 // Re add the visual aids 3225 if (scmd == "removeformat") 3226 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); 3227 3228 tinyMCE.triggerNodeChange(); 3229 3230 break; 3231 3232 case "FontName": 3233 if (value == null) { 3234 var s = this.getSel(); 3235 3236 // Find font and select it 3237 if (tinyMCE.isGecko && s.isCollapsed) { 3238 var f = tinyMCE.getParentElement(this.getFocusElement(), "font"); 3239 3240 if (f != null) 3241 this.selection.selectNode(f, false); 3242 } 3243 3244 // Remove format 3245 this.getDoc().execCommand("RemoveFormat", false, null); 3246 3247 // Collapse range if font was found 3248 if (f != null && tinyMCE.isGecko) { 3249 var r = this.getRng().cloneRange(); 3250 r.collapse(true); 3251 s.removeAllRanges(); 3252 s.addRange(r); 3253 } 3254 } else 3255 this.getDoc().execCommand('FontName', false, value); 3256 3257 if (tinyMCE.isGecko) 3258 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); 3259 3260 return; 3261 3262 case "FontSize": 3263 this.getDoc().execCommand('FontSize', false, value); 3264 3265 if (tinyMCE.isGecko) 3266 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); 3267 3268 return; 3269 3270 case "forecolor": 3271 value = value == null ? this.foreColor : value; 3272 value = tinyMCE.trim(value); 3273 value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value; 3274 3275 this.foreColor = value; 3276 this.getDoc().execCommand('forecolor', false, value); 3277 break; 3278 3279 case "HiliteColor": 3280 value = value == null ? this.backColor : value; 3281 value = tinyMCE.trim(value); 3282 value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value; 3283 this.backColor = value; 3284 3285 if (tinyMCE.isGecko) { 3286 this._setUseCSS(true); 3287 this.getDoc().execCommand('hilitecolor', false, value); 3288 this._setUseCSS(false); 3289 } else 3290 this.getDoc().execCommand('BackColor', false, value); 3291 break; 3292 3293 case "Cut": 3294 case "Copy": 3295 case "Paste": 3296 var cmdFailed = false; 3297 3298 // Try executing command 3299 eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}'); 3300 3301 if (tinyMCE.isOpera && cmdFailed) 3302 alert('Currently not supported by your browser, use keyboard shortcuts instead.'); 3303 3304 // Alert error in gecko if command failed 3305 if (tinyMCE.isGecko && cmdFailed) { 3306 // Confirm more info 3307 if (confirm(tinyMCE.entityDecode(tinyMCE.getLang('lang_clipboard_msg')))) 3308 window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal'); 3309 3310 return; 3311 } else 3312 tinyMCE.triggerNodeChange(); 3313 break; 3314 3315 case "mceSetContent": 3316 if (!value) 3317 value = ""; 3318 3319 // Call custom cleanup code 3320 value = tinyMCE.storeAwayURLs(value); 3321 value = tinyMCE._customCleanup(this, "insert_to_editor", value); 3322 3323 if (this.getBody().nodeName == 'BODY') 3324 tinyMCE._setHTML(doc, value); 3325 else 3326 this.getBody().innerHTML = value; 3327 3328 tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, doc, this.settings, this.getBody(), false, false, false, true)); 3329 tinyMCE.convertAllRelativeURLs(this.getBody()); 3330 3331 // Cleanup any mess left from storyAwayURLs 3332 tinyMCE._removeInternal(this.getBody()); 3333 3334 // When editing always use fonts internaly 3335 if (tinyMCE.getParam("convert_fonts_to_spans")) 3336 tinyMCE.convertSpansToFonts(doc); 3337 3338 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); 3339 tinyMCE._setEventsEnabled(this.getBody(), false); 3340 this._addBogusBR(); 3341 3342 return true; 3343 3344 case "mceCleanup": 3345 var b = this.selection.getBookmark(); 3346 tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML); 3347 tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid)); 3348 tinyMCE.convertAllRelativeURLs(doc.body); 3349 3350 // When editing always use fonts internaly 3351 if (tinyMCE.getParam("convert_fonts_to_spans")) 3352 tinyMCE.convertSpansToFonts(doc); 3353 3354 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); 3355 tinyMCE._setEventsEnabled(this.getBody(), false); 3356 this._addBogusBR(); 3357 this.repaint(); 3358 this.selection.moveToBookmark(b); 3359 tinyMCE.triggerNodeChange(); 3360 break; 3361 3362 case "mceReplaceContent": 3363 // Force empty string 3364 if (!value) 3365 value = ''; 3366 3367 this.getWin().focus(); 3368 3369 var selectedText = ""; 3370 3371 if (tinyMCE.isIE) { 3372 var rng = doc.selection.createRange(); 3373 selectedText = rng.text; 3374 } else 3375 selectedText = this.getSel().toString(); 3376 3377 if (selectedText.length > 0) { 3378 value = tinyMCE.replaceVar(value, "selection", selectedText); 3379 tinyMCE.execCommand('mceInsertContent', false, value); 3380 } 3381 3382 this._addBogusBR(); 3383 tinyMCE.triggerNodeChange(); 3384 break; 3385 3386 case "mceSetAttribute": 3387 if (typeof(value) == 'object') { 3388 var targetElms = (typeof(value.targets) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value.targets; 3389 var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms); 3390 3391 if (targetNode) { 3392 targetNode.setAttribute(value.name, value.value); 3393 tinyMCE.triggerNodeChange(); 3394 } 3395 } 3396 break; 3397 3398 case "mceSetCSSClass": 3399 this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value}); 3400 break; 3401 3402 case "mceInsertRawHTML": 3403 var key = 'tiny_mce_marker'; 3404 3405 this.execCommand('mceBeginUndoLevel'); 3406 3407 // Insert marker key 3408 this.execCommand('mceInsertContent', false, key); 3409 3410 // Store away scroll pos 3411 var scrollX = this.getBody().scrollLeft + this.getDoc().documentElement.scrollLeft; 3412 var scrollY = this.getBody().scrollTop + this.getDoc().documentElement.scrollTop; 3413 3414 // Find marker and replace with RAW HTML 3415 var html = this.getBody().innerHTML; 3416 if ((pos = html.indexOf(key)) != -1) 3417 tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length)); 3418 3419 // Restore scoll pos 3420 this.contentWindow.scrollTo(scrollX, scrollY); 3421 3422 this.execCommand('mceEndUndoLevel'); 3423 3424 break; 3425 3426 case "mceInsertContent": 3427 // Force empty string 3428 if (!value) 3429 value = ''; 3430 3431 var insertHTMLFailed = false; 3432 3433 // Removed since it produced problems in IE 3434 // this.getWin().focus(); 3435 3436 if (tinyMCE.isGecko || tinyMCE.isOpera) { 3437 try { 3438 // Is plain text or HTML, &, etc will be encoded wrong in FF 3439 if (value.indexOf('<') == -1 && !value.match(/(&| |<|>)/g)) { 3440 var r = this.getRng(); 3441 var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value)); 3442 var s = this.getSel(); 3443 var r2 = r.cloneRange(); 3444 3445 // Insert text at cursor position 3446 s.removeAllRanges(); 3447 r.deleteContents(); 3448 r.insertNode(n); 3449 3450 // Move the cursor to the end of text 3451 r2.selectNode(n); 3452 r2.collapse(false); 3453 s.removeAllRanges(); 3454 s.addRange(r2); 3455 } else { 3456 value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value); 3457 this.getDoc().execCommand('inserthtml', false, value); 3458 tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); 3459 } 3460 } catch (ex) { 3461 insertHTMLFailed = true; 3462 } 3463 3464 if (!insertHTMLFailed) { 3465 tinyMCE.triggerNodeChange(); 3466 return; 3467 } 3468 } 3469 3470 if (!tinyMCE.isIE) { 3471 var isHTML = value.indexOf('<') != -1; 3472 var sel = this.getSel(); 3473 var rng = this.getRng(); 3474 3475 if (isHTML) { 3476 if (tinyMCE.isSafari) { 3477 var tmpRng = this.getDoc().createRange(); 3478 3479 tmpRng.setStart(this.getBody(), 0); 3480 tmpRng.setEnd(this.getBody(), 0); 3481 3482 value = tmpRng.createContextualFragment(value); 3483 } else 3484 value = rng.createContextualFragment(value); 3485 } else { 3486 // Setup text node 3487 value = doc.createTextNode(tinyMCE.entityDecode(value)); 3488 } 3489 3490 // Insert plain text in Safari 3491 if (tinyMCE.isSafari && !isHTML) { 3492 this.execCommand('InsertText', false, value.nodeValue); 3493 tinyMCE.triggerNodeChange(); 3494 return true; 3495 } else if (tinyMCE.isSafari && isHTML) { 3496 rng.deleteContents(); 3497 rng.insertNode(value); 3498 tinyMCE.triggerNodeChange(); 3499 return true; 3500 } 3501 3502 rng.deleteContents(); 3503 3504 // If target node is text do special treatment, (Mozilla 1.3 fix) 3505 if (rng.startContainer.nodeType == 3) { 3506 var node = rng.startContainer.splitText(rng.startOffset); 3507 node.parentNode.insertBefore(value, node); 3508 } else 3509 rng.insertNode(value); 3510 3511 if (!isHTML) { 3512 // Removes weird selection trails 3513 sel.selectAllChildren(doc.body); 3514 sel.removeAllRanges(); 3515 3516 // Move cursor to end of content 3517 var rng = doc.createRange(); 3518 3519 rng.selectNode(value); 3520 rng.collapse(false); 3521 3522 sel.addRange(rng); 3523 } else 3524 rng.collapse(false); 3525 3526 tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); 3527 } else { 3528 var rng = doc.selection.createRange(), tmpRng = null; 3529 var c = value.indexOf('<!--') != -1; 3530 3531 // Fix comment bug, add tag before comments 3532 if (c) 3533 value = tinyMCE.uniqueTag + value; 3534 3535 // tmpRng = rng.duplicate(); // Store away range (Fixes Undo bookmark bug in IE) 3536 3537 if (rng.item) 3538 rng.item(0).outerHTML = value; 3539 else 3540 rng.pasteHTML(value); 3541 3542 //if (tmpRng) 3543 // tmpRng.select(); // Restore range (Fixes Undo bookmark bug in IE) 3544 3545 // Remove unique tag 3546 if (c) { 3547 var e = this.getDoc().getElementById('mceTMPElement'); 3548 e.parentNode.removeChild(e); 3549 } 3550 } 3551 3552 tinyMCE.execCommand("mceAddUndoLevel"); 3553 tinyMCE.triggerNodeChange(); 3554 break; 3555 3556 case "mceStartTyping": 3557 if (tinyMCE.settings.custom_undo_redo && this.undoRedo.typingUndoIndex == -1) { 3558 this.undoRedo.typingUndoIndex = this.undoRedo.undoIndex; 3559 tinyMCE.typingUndoIndex = tinyMCE.undoIndex; 3560 this.execCommand('mceAddUndoLevel'); 3561 } 3562 break; 3563 3564 case "mceEndTyping": 3565 if (tinyMCE.settings.custom_undo_redo && this.undoRedo.typingUndoIndex != -1) { 3566 this.execCommand('mceAddUndoLevel'); 3567 this.undoRedo.typingUndoIndex = -1; 3568 } 3569 3570 tinyMCE.typingUndoIndex = -1; 3571 break; 3572 3573 case "mceBeginUndoLevel": 3574 this.undoRedoLevel = false; 3575 break; 3576 3577 case "mceEndUndoLevel": 3578 this.undoRedoLevel = true; 3579 this.execCommand('mceAddUndoLevel'); 3580 break; 3581 3582 case "mceAddUndoLevel": 3583 if (tinyMCE.settings.custom_undo_redo && this.undoRedoLevel) { 3584 if (this.undoRedo.add()) 3585 tinyMCE.triggerNodeChange(false); 3586 } 3587 break; 3588 3589 case "Undo": 3590 if (tinyMCE.settings.custom_undo_redo) { 3591 tinyMCE.execCommand("mceEndTyping"); 3592 this.undoRedo.undo(); 3593 tinyMCE.triggerNodeChange(); 3594 } else 3595 this.getDoc().execCommand(command, user_interface, value); 3596 break; 3597 3598 case "Redo": 3599 if (tinyMCE.settings.custom_undo_redo) { 3600 tinyMCE.execCommand("mceEndTyping"); 3601 this.undoRedo.redo(); 3602 tinyMCE.triggerNodeChange(); 3603 } else 3604 this.getDoc().execCommand(command, user_interface, value); 3605 break; 3606 3607 case "mceToggleVisualAid": 3608 this.visualAid = !this.visualAid; 3609 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); 3610 tinyMCE.triggerNodeChange(); 3611 break; 3612 3613 case "Indent": 3614 this.getDoc().execCommand(command, user_interface, value); 3615 tinyMCE.triggerNodeChange(); 3616 3617 if (tinyMCE.isIE) { 3618 var n = tinyMCE.getParentElement(this.getFocusElement(), "blockquote"); 3619 do { 3620 if (n && n.nodeName == "BLOCKQUOTE") { 3621 n.removeAttribute("dir"); 3622 n.removeAttribute("style"); 3623 } 3624 } while (n != null && (n = n.parentNode) != null); 3625 } 3626 break; 3627 3628 case "RemoveFormat": 3629 case "removeformat": 3630 var text = this.selection.getSelectedText(); 3631 3632 if (tinyMCE.isOpera) { 3633 this.getDoc().execCommand("RemoveFormat", false, null); 3634 return; 3635 } 3636 3637 if (tinyMCE.isIE) { 3638 try { 3639 var rng = doc.selection.createRange(); 3640 rng.execCommand("RemoveFormat", false, null); 3641 } catch (e) { 3642 // Do nothing 3643 } 3644 3645 this.execCommand("mceSetStyleInfo", false, {command : "removeformat"}); 3646 } else { 3647 this.getDoc().execCommand(command, user_interface, value); 3648 3649 this.execCommand("mceSetStyleInfo", false, {command : "removeformat"}); 3650 } 3651 3652 // Remove class 3653 if (text.length == 0) 3654 this.execCommand("mceSetCSSClass", false, ""); 3655 3656 tinyMCE.triggerNodeChange(); 3657 break; 3658 3659 default: 3660 this.getDoc().execCommand(command, user_interface, value); 3661 3662 if (tinyMCE.isGecko) 3663 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); 3664 else 3665 tinyMCE.triggerNodeChange(); 3666 } 3667 3668 // Add undo level after modification 3669 if (command != "mceAddUndoLevel" && command != "Undo" && command != "Redo" && command != "mceStartTyping" && command != "mceEndTyping") 3670 tinyMCE.execCommand("mceAddUndoLevel"); 3671 }, 3672 3673 queryCommandValue : function(c) { 3674 try { 3675 return this.getDoc().queryCommandValue(c); 3676 } catch (e) { 1011 }); 1012 1013 return s; 1014 }; 1015 } 1016 1017 while (n) { 1018 if (n == r) 1019 return null; 1020 1021 if (f(n)) 1022 return n; 1023 1024 n = n.parentNode; 1025 } 1026 3677 1027 return null; 3678 } 3679 }, 3680 3681 queryCommandState : function(c) { 3682 return this.getDoc().queryCommandState(c); 3683 }, 3684 3685 _addBogusBR : function() { 3686 var b = this.getBody(); 3687 3688 if (tinyMCE.isGecko && !b.hasChildNodes()) 3689 b.innerHTML = '<br _moz_editor_bogus_node="TRUE" />'; 3690 }, 3691 3692 _onAdd : function(replace_element, form_element_name, target_document) { 3693 var hc, th, tos, editorTemplate, targetDoc, deltaWidth, deltaHeight, html, rng, fragment; 3694 var dynamicIFrame, tElm, doc, parentElm; 3695 3696 th = this.settings.theme; 3697 tos = tinyMCE.themes[th]; 3698 3699 targetDoc = target_document ? target_document : document; 3700 3701 this.targetDoc = targetDoc; 3702 3703 tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings.theme; 3704 this.settings.themeurl = tinyMCE.themeURL; 3705 3706 if (!replace_element) { 3707 alert("Error: Could not find the target element."); 3708 return false; 3709 } 3710 3711 if (tos.getEditorTemplate) 3712 editorTemplate = tos.getEditorTemplate(this.settings, this.editorId); 3713 3714 deltaWidth = editorTemplate.delta_width ? editorTemplate.delta_width : 0; 3715 deltaHeight = editorTemplate.delta_height ? editorTemplate.delta_height : 0; 3716 html = '<span id="' + this.editorId + '_parent" class="mceEditorContainer">' + editorTemplate.html; 3717 3718 html = tinyMCE.replaceVar(html, "editor_id", this.editorId); 3719 3720 if (!this.settings.default_document) 3721 this.settings.default_document = tinyMCE.baseURL + "/blank.htm"; 3722 3723 this.settings.old_width = this.settings.width; 3724 this.settings.old_height = this.settings.height; 3725 3726 // Set default width, height 3727 if (this.settings.width == -1) 3728 this.settings.width = replace_element.offsetWidth; 3729 3730 if (this.settings.height == -1) 3731 this.settings.height = replace_element.offsetHeight; 3732 3733 // Try the style width 3734 if (this.settings.width == 0) 3735 this.settings.width = replace_element.style.width; 3736 3737 // Try the style height 3738 if (this.settings.height == 0) 3739 this.settings.height = replace_element.style.height; 3740 3741 // If no width/height then default to 320x240, better than nothing 3742 if (this.settings.width == 0) 3743 this.settings.width = 320; 3744 3745 if (this.settings.height == 0) 3746 this.settings.height = 240; 3747 3748 this.settings.area_width = parseInt(this.settings.width); 3749 this.settings.area_height = parseInt(this.settings.height); 3750 this.settings.area_width += deltaWidth; 3751 this.settings.area_height += deltaHeight; 3752 this.settings.width_style = "" + this.settings.width; 3753 this.settings.height_style = "" + this.settings.height; 3754 3755 // Special % handling 3756 if (("" + this.settings.width).indexOf('%') != -1) 3757 this.settings.area_width = "100%"; 3758 else 3759 this.settings.width_style += 'px'; 3760 3761 if (("" + this.settings.height).indexOf('%') != -1) 3762 this.settings.area_height = "100%"; 3763 else 3764 this.settings.height_style += 'px'; 3765 3766 if (("" + replace_element.style.width).indexOf('%') != -1) { 3767 this.settings.width = replace_element.style.width; 3768 this.settings.area_width = "100%"; 3769 this.settings.width_style = "100%"; 3770 } 3771 3772 if (("" + replace_element.style.height).indexOf('%') != -1) { 3773 this.settings.height = replace_element.style.height; 3774 this.settings.area_height = "100%"; 3775 this.settings.height_style = "100%"; 3776 } 3777 3778 html = tinyMCE.applyTemplate(html); 3779 3780 this.settings.width = this.settings.old_width; 3781 this.settings.height = this.settings.old_height; 3782 3783 this.visualAid = this.settings.visual; 3784 this.formTargetElementId = form_element_name; 3785 3786 // Get replace_element contents 3787 if (replace_element.nodeName == "TEXTAREA" || replace_element.nodeName == "INPUT") 3788 this.startContent = replace_element.value; 3789 else 3790 this.startContent = replace_element.innerHTML; 3791 3792 // If not text area or input 3793 if (replace_element.nodeName != "TEXTAREA" && replace_element.nodeName != "INPUT") { 3794 this.oldTargetElement = replace_element; 3795 3796 // Debug mode 3797 hc = '<input type="hidden" id="' + form_element_name + '" name="' + form_element_name + '" />'; 3798 this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline'); 3799 this.oldTargetElement.style.display = "none"; 3800 3801 html += '</span>'; 3802 3803 if (tinyMCE.isGecko) 3804 html = hc + html; 3805 else 3806 html += hc; 3807 3808 // Output HTML and set editable 3809 if (tinyMCE.isGecko) { 3810 rng = replace_element.ownerDocument.createRange(); 3811 rng.setStartBefore(replace_element); 3812 3813 fragment = rng.createContextualFragment(html); 3814 tinyMCE.insertAfter(fragment, replace_element); 3815 } else 3816 replace_element.insertAdjacentHTML("beforeBegin", html); 3817 } else { 3818 html += '</span>'; 3819 3820 // Just hide the textarea element 3821 this.oldTargetElement = replace_element; 3822 3823 this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline'); 3824 this.oldTargetElement.style.display = "none"; 3825 3826 // Output HTML and set editable 3827 if (tinyMCE.isGecko) { 3828 rng = replace_element.ownerDocument.createRange(); 3829 rng.setStartBefore(replace_element); 3830 3831 fragment = rng.createContextualFragment(html); 3832 tinyMCE.insertAfter(fragment, replace_element); 3833 } else 3834 replace_element.insertAdjacentHTML("beforeBegin", html); 3835 } 3836 3837 // Setup iframe 3838 dynamicIFrame = false; 3839 tElm = targetDoc.getElementById(this.editorId); 3840 3841 if (!tinyMCE.isIE) { 3842 // Node case is preserved in XML strict mode 3843 if (tElm && (tElm.nodeName == "SPAN" || tElm.nodeName == "span")) { 3844 tElm = tinyMCE._createIFrame(tElm, targetDoc); 3845 dynamicIFrame = true; 3846 } 3847 3848 this.targetElement = tElm; 3849 this.iframeElement = tElm; 3850 this.contentDocument = tElm.contentDocument; 3851 this.contentWindow = tElm.contentWindow; 3852 3853 //this.getDoc().designMode = "on"; 3854 } else { 3855 if (tElm && tElm.nodeName == "SPAN") 3856 tElm = tinyMCE._createIFrame(tElm, targetDoc, targetDoc.parentWindow); 3857 else 3858 tElm = targetDoc.frames[this.editorId]; 3859 3860 this.targetElement = tElm; 3861 this.iframeElement = targetDoc.getElementById(this.editorId); 3862 3863 if (tinyMCE.isOpera) { 3864 this.contentDocument = this.iframeElement.contentDocument; 3865 this.contentWindow = this.iframeElement.contentWindow; 3866 dynamicIFrame = true; 3867 } else { 3868 this.contentDocument = tElm.window.document; 3869 this.contentWindow = tElm.window; 3870 } 3871 3872 this.getDoc().designMode = "on"; 3873 } 3874 3875 // Setup base HTML 3876 doc = this.contentDocument; 3877 if (dynamicIFrame) { 3878 html = tinyMCE.getParam('doctype') + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + tinyMCE.settings.base_href + '" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>blank_page</title></head><body class="mceContentBody"></body></html>'; 3879 3880 try { 3881 if (!this.isHidden()) 3882 this.getDoc().designMode = "on"; 3883 3884 doc.open(); 3885 doc.write(html); 3886 doc.close(); 3887 } catch (e) { 3888 // Failed Mozilla 1.3 3889 this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm"; 3890 } 3891 } 3892 3893 // This timeout is needed in MSIE 5.5 for some odd reason 3894 // it seems that the document.frames isn't initialized yet? 3895 if (tinyMCE.isIE) 3896 window.setTimeout("tinyMCE.addEventHandlers(tinyMCE.instances[\"" + this.editorId + "\"]);", 1); 3897 3898 // Setup element references 3899 parentElm = this.targetDoc.getElementById(this.editorId + '_parent'); 3900 this.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling; 3901 3902 tinyMCE.setupContent(this.editorId, true); 3903 3904 return true; 3905 }, 3906 3907 setBaseHREF : function(u) { 3908 var h, b, d, nl; 3909 3910 d = this.getDoc(); 3911 nl = d.getElementsByTagName("base"); 3912 b = nl.length > 0 ? nl[0] : null; 3913 3914 if (!b) { 3915 nl = d.getElementsByTagName("head"); 3916 h = nl.length > 0 ? nl[0] : null; 3917 3918 b = d.createElement("base"); 3919 b.setAttribute('href', u); 3920 h.appendChild(b); 3921 } else { 3922 if (u == '' || u == null) 3923 b.parentNode.removeChild(b); 3924 else 3925 b.setAttribute('href', u); 3926 } 3927 }, 3928 3929 getHTML : function(r) { 3930 var h, d = this.getDoc(), b = this.getBody(); 3931 3932 if (r) 3933 return b.innerHTML; 3934 3935 h = tinyMCE._cleanupHTML(this, d, this.settings, b, false, true, false, true); 3936 3937 if (tinyMCE.getParam("convert_fonts_to_spans")) 3938 tinyMCE.convertSpansToFonts(d); 3939 3940 return h; 3941 }, 3942 3943 setHTML : function(h) { 3944 this.execCommand('mceSetContent', false, h); 3945 this.repaint(); 3946 }, 3947 3948 getFocusElement : function() { 3949 return this.selection.getFocusElement(); 3950 }, 3951 3952 getSel : function() { 3953 return this.selection.getSel(); 3954 }, 3955 3956 getRng : function() { 3957 return this.selection.getRng(); 3958 }, 3959 3960 triggerSave : function(skip_cleanup, skip_callback) { 3961 var e, nl = [], i, s, content, htm; 3962 3963 if (!this.enabled) 3964 return; 3965 3966 this.switchSettings(); 3967 s = tinyMCE.settings; 3968 3969 // Force hidden tabs visible while serializing 3970 if (tinyMCE.isRealIE) { 3971 e = this.iframeElement; 3972 3973 do { 3974 if (e.style && e.style.display == 'none') { 3975 e.style.display = 'block'; 3976 nl[nl.length] = {elm : e, type : 'style'}; 3977 } 3978 3979 if (e.style && s.hidden_tab_class.length > 0 && e.className.indexOf(s.hidden_tab_class) != -1) { 3980 e.className = s.display_tab_class; 3981 nl[nl.length] = {elm : e, type : 'class'}; 3982 } 3983 } while ((e = e.parentNode) != null) 3984 } 3985 3986 tinyMCE.settings.preformatted = false; 3987 3988 // Default to false 3989 if (typeof(skip_cleanup) == "undefined") 3990 skip_cleanup = false; 3991 3992 // Default to false 3993 if (typeof(skip_callback) == "undefined") 3994 skip_callback = false; 3995 3996 tinyMCE._setHTML(this.getDoc(), this.getBody().innerHTML); 3997 3998 // Remove visual aids when cleanup is disabled 3999 if (this.settings.cleanup == false) { 4000 tinyMCE.handleVisualAid(this.getBody(), true, false, this); 4001 tinyMCE._setEventsEnabled(this.getBody(), true); 4002 } 4003 4004 tinyMCE._customCleanup(this, "submit_content_dom", this.contentWindow.document.body); 4005 htm = skip_cleanup ? this.getBody().innerHTML : tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true); 4006 htm = tinyMCE._customCleanup(this, "submit_content", htm); 4007 4008 if (!skip_callback && tinyMCE.settings.save_callback !== '') 4009 content = tinyMCE.resolveDots(tinyMCE.settings.save_callback, window)(this.formTargetElementId,htm,this.getBody()); 4010 4011 // Use callback content if available 4012 if ((typeof(content) != "undefined") && content != null) 4013 htm = content; 4014 4015 // Replace some weird entities (Bug: #1056343) 4016 htm = tinyMCE.regexpReplace(htm, "(", "(", "gi"); 4017 htm = tinyMCE.regexpReplace(htm, ")", ")", "gi"); 4018 htm = tinyMCE.regexpReplace(htm, ";", ";", "gi"); 4019 htm = tinyMCE.regexpReplace(htm, """, """, "gi"); 4020 htm = tinyMCE.regexpReplace(htm, "^", "^", "gi"); 4021 4022 if (this.formElement) 4023 this.formElement.value = htm; 4024 4025 if (tinyMCE.isSafari && this.formElement) 4026 this.formElement.innerText = htm; 4027 4028 // Hide them again (tabs in MSIE) 4029 for (i=0; i<nl.length; i++) { 4030 if (nl[i].type == 'style') 4031 nl[i].elm.style.display = 'none'; 4032 else 4033 nl[i].elm.className = s.hidden_tab_class; 4034 } 4035 } 4036 4037 }; 4038 4039 /* file:jscripts/tiny_mce/classes/TinyMCE_Cleanup.class.js */ 4040 4041 tinyMCE.add(TinyMCE_Engine, { 4042 cleanupHTMLCode : function(s) { 4043 s = s.replace(new RegExp('<p \\/>', 'gi'), '<p> </p>'); 4044 s = s.replace(new RegExp('<p>\\s*<\\/p>', 'gi'), '<p> </p>'); 4045 4046 // Fix close BR elements 4047 s = s.replace(new RegExp('<br>\\s*<\\/br>', 'gi'), '<br />'); 4048 4049 // Open closed tags like <b/> to <b></b> 4050 s = s.replace(new RegExp('<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|font|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\\\|>]*)\\/>', 'gi'), '<$1$2$3></$1$2>'); 4051 4052 // Remove trailing space <b > to <b> 4053 s = s.replace(new RegExp('\\s+></', 'gi'), '></'); 4054 4055 // Close tags <img></img> to <img/> 4056 s = s.replace(new RegExp('<(img|br|hr)([^>]*)><\\/(img|br|hr)>', 'gi'), '<$1$2 />'); 4057 4058 // Weird MSIE bug, <p><hr /></p> breaks runtime? 4059 if (tinyMCE.isIE) 4060 s = s.replace(new RegExp('<p><hr \\/><\\/p>', 'gi'), "<hr>"); 4061 4062 // Weird tags will make IE error #bug: 1538495 4063 if (tinyMCE.isIE) 4064 s = s.replace(/<!(\s*)\/>/g, ''); 4065 4066 // Convert relative anchors to absolute URLs ex: #something to file.htm#something 4067 // Removed: Since local document anchors should never be forced absolute example edit.php?id=something 4068 //if (tinyMCE.getParam('convert_urls')) 4069 // s = s.replace(new RegExp('(href=\"{0,1})(\\s*#)', 'gi'), '$1' + tinyMCE.settings.document_base_url + "#"); 4070 4071 return s; 4072 }, 4073 4074 parseStyle : function(str) { 4075 var ar = [], st, i, re, pa; 4076 4077 if (str == null) 4078 return ar; 4079 4080 st = str.split(';'); 4081 4082 tinyMCE.clearArray(ar); 4083 4084 for (i=0; i<st.length; i++) { 4085 if (st[i] == '') 4086 continue; 4087 4088 re = new RegExp('^\\s*([^:]*):\\s*(.*)\\s*$'); 4089 pa = st[i].replace(re, '$1||$2').split('||'); 4090 //tinyMCE.debug(str, pa[0] + "=" + pa[1], st[i].replace(re, '$1||$2')); 4091 if (pa.length == 2) 4092 ar[pa[0].toLowerCase()] = pa[1]; 4093 } 4094 4095 return ar; 4096 }, 4097 4098 compressStyle : function(ar, pr, sf, res) { 4099 var box = [], i, a; 4100 4101 box[0] = ar[pr + '-top' + sf]; 4102 box[1] = ar[pr + '-left' + sf]; 4103 box[2] = ar[pr + '-right' + sf]; 4104 box[3] = ar[pr + '-bottom' + sf]; 4105 4106 for (i=0; i<box.length; i++) { 4107 if (box[i] == null) 4108 return; 4109 4110 for (a=0; a<box.length; a++) { 4111 if (box[a] != box[i]) 4112 return; 4113 } 4114 } 4115 4116 // They are all the same 4117 ar[res] = box[0]; 4118 ar[pr + '-top' + sf] = null; 4119 ar[pr + '-left' + sf] = null; 4120 ar[pr + '-right' + sf] = null; 4121 ar[pr + '-bottom' + sf] = null; 4122 }, 4123 4124 serializeStyle : function(ar) { 4125 var str = "", key, val, m; 4126 4127 // Compress box 4128 tinyMCE.compressStyle(ar, "border", "", "border"); 4129 tinyMCE.compressStyle(ar, "border", "-width", "border-width"); 4130 tinyMCE.compressStyle(ar, "border", "-color", "border-color"); 4131 tinyMCE.compressStyle(ar, "border", "-style", "border-style"); 4132 tinyMCE.compressStyle(ar, "padding", "", "padding"); 4133 tinyMCE.compressStyle(ar, "margin", "", "margin"); 4134 4135 for (key in ar) { 4136 val = ar[key]; 4137 4138 if (typeof(val) == 'function') 4139 continue; 4140 4141 if (key.indexOf('mso-') == 0) 4142 continue; 4143 4144 if (val != null && val !== '') { 4145 val = '' + val; // Force string 4146 4147 // Fix style URL 4148 val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')"); 4149 4150 // Convert URL 4151 if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) { 4152 m = new RegExp("url\\('(.*?)'\\)").exec(val); 4153 4154 if (m.length > 1) 4155 val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')"; 4156 } 4157 4158 // Force HEX colors 4159 if (tinyMCE.getParam("force_hex_style_colors")) 4160 val = tinyMCE.convertRGBToHex(val, true); 4161 4162 val = val.replace(/\"/g, '\''); 4163 4164 if (val != "url('')") 4165 str += key.toLowerCase() + ": " + val + "; "; 4166 } 4167 } 4168 4169 if (new RegExp('; $').test(str)) 4170 str = str.substring(0, str.length - 2); 4171 4172 return str; 4173 }, 4174 4175 convertRGBToHex : function(s, k) { 4176 var re, rgb; 4177 4178 if (s.toLowerCase().indexOf('rgb') != -1) { 4179 re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi"); 4180 rgb = s.replace(re, "$1,$2,$3,$4,$5").split(','); 4181 4182 if (rgb.length == 5) { 4183 r = parseInt(rgb[1]).toString(16); 4184 g = parseInt(rgb[2]).toString(16); 4185 b = parseInt(rgb[3]).toString(16); 4186 4187 r = r.length == 1 ? '0' + r : r; 4188 g = g.length == 1 ? '0' + g : g; 4189 b = b.length == 1 ? '0' + b : b; 4190 4191 s = "#" + r + g + b; 4192 4193 if (k) 4194 s = rgb[0] + s + rgb[4]; 4195 } 4196 } 4197 4198 return s; 4199 }, 4200 4201 convertHexToRGB : function(s) { 4202 if (s.indexOf('#') != -1) { 4203 s = s.replace(new RegExp('[^0-9A-F]', 'gi'), ''); 4204 return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")"; 4205 } 4206 4207 return s; 4208 }, 4209 4210 convertSpansToFonts : function(doc) { 4211 var s, i, size, fSize, x, fFace, fColor, sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(','); 4212 4213 s = tinyMCE.selectElements(doc, 'span,font'); 4214 for (i=0; i<s.length; i++) { 4215 size = tinyMCE.trim(s[i].style.fontSize).toLowerCase(); 4216 fSize = 0; 4217 4218 for (x=0; x<sizes.length; x++) { 4219 if (sizes[x] == size) { 4220 fSize = x + 1; 4221 break; 4222 } 4223 } 4224 4225 if (fSize > 0) { 4226 tinyMCE.setAttrib(s[i], 'size', fSize); 4227 s[i].style.fontSize = ''; 4228 } 4229 4230 fFace = s[i].style.fontFamily; 4231 if (fFace != null && fFace !== '') { 4232 tinyMCE.setAttrib(s[i], 'face', fFace); 4233 s[i].style.fontFamily = ''; 4234 } 4235 4236 fColor = s[i].style.color; 4237 if (fColor != null && fColor !== '') { 4238 tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor)); 4239 s[i].style.color = ''; 4240 } 4241 } 4242 }, 4243 4244 convertFontsToSpans : function(doc) { 4245 var fsClasses, s, i, fSize, fFace, fColor, sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(','); 4246 4247 fsClasses = tinyMCE.getParam('font_size_classes'); 4248 if (fsClasses !== '') 4249 fsClasses = fsClasses.replace(/\s+/, '').split(','); 4250 else 4251 fsClasses = null; 4252 4253 s = tinyMCE.selectElements(doc, 'span,font'); 4254 for (i=0; i<s.length; i++) { 4255 fSize = tinyMCE.getAttrib(s[i], 'size'); 4256 fFace = tinyMCE.getAttrib(s[i], 'face'); 4257 fColor = tinyMCE.getAttrib(s[i], 'color'); 4258 4259 if (fSize !== '') { 4260 fSize = parseInt(fSize); 4261 4262 if (fSize > 0 && fSize < 8) { 4263 if (fsClasses != null) 4264 tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]); 4265 else 4266 s[i].style.fontSize = sizes[fSize-1]; 4267 } 4268 4269 s[i].removeAttribute('size'); 4270 } 4271 4272 if (fFace !== '') { 4273 s[i].style.fontFamily = fFace; 4274 s[i].removeAttribute('face'); 4275 } 4276 4277 if (fColor !== '') { 4278 s[i].style.color = fColor; 4279 s[i].removeAttribute('color'); 4280 } 4281 } 4282 }, 4283 4284 cleanupAnchors : function(doc) { 4285 var i, cn, x, an = doc.getElementsByTagName("a"); 4286 4287 // Loops backwards due to bug #1467987 4288 for (i=an.length-1; i>=0; i--) { 4289 if (tinyMCE.getAttrib(an[i], "name") !== '' && tinyMCE.getAttrib(an[i], "href") == '') { 4290 cn = an[i].childNodes; 4291 4292 for (x=cn.length-1; x>=0; x--) 4293 tinyMCE.insertAfter(cn[x], an[i]); 4294 } 4295 } 4296 }, 4297 4298 getContent : function(editor_id) { 4299 if (typeof(editor_id) != "undefined") 4300 tinyMCE.getInstanceById(editor_id).select(); 4301 4302 if (tinyMCE.selectedInstance) 4303 return tinyMCE.selectedInstance.getHTML(); 4304 4305 return null; 4306 }, 4307 4308 _fixListElements : function(d) { 4309 var nl, x, a = ['ol', 'ul'], i, n, p, r = new RegExp('^(OL|UL)$'), np; 4310 4311 for (x=0; x<a.length; x++) { 4312 nl = d.getElementsByTagName(a[x]); 4313 4314 for (i=0; i<nl.length; i++) { 4315 n = nl[i]; 4316 p = n.parentNode; 4317 4318 if (r.test(p.nodeName)) { 4319 np = tinyMCE.prevNode(n, 'LI'); 4320 4321 if (!np) { 4322 np = d.createElement('li'); 4323 np.innerHTML = ' '; 4324 np.appendChild(n); 4325 p.insertBefore(np, p.firstChild); 4326 } else 4327 np.appendChild(n); 4328 } 4329 } 4330 } 4331 }, 4332 4333 _fixTables : function(d) { 4334 var nl, i, n, p, np, x, t; 4335 4336 nl = d.getElementsByTagName('table'); 4337 for (i=0; i<nl.length; i++) { 4338 n = nl[i]; 4339 4340 if ((p = tinyMCE.getParentElement(n, 'p,h1,h2,h3,h4,h5,h6')) != null) { 4341 np = p.cloneNode(false); 4342 np.removeAttribute('id'); 4343 4344 t = n; 4345 4346 while ((n = n.nextSibling)) 4347 np.appendChild(n); 4348 4349 tinyMCE.insertAfter(np, p); 4350 tinyMCE.insertAfter(t, p); 4351 } 4352 } 4353 }, 4354 4355 _cleanupHTML : function(inst, doc, config, elm, visual, on_save, on_submit, inn) { 4356 var h, d, t1, t2, t3, t4, t5, c, s, nb; 4357 4358 if (!tinyMCE.getParam('cleanup')) 4359 return elm.innerHTML; 4360 4361 on_save = typeof(on_save) == 'undefined' ? false : on_save; 4362 4363 c = inst.cleanup; 4364 s = inst.settings; 4365 d = c.settings.debug; 4366 4367 if (d) 4368 t1 = new Date().getTime(); 4369 4370 inst._fixRootBlocks(); 4371 4372 if (tinyMCE.getParam("convert_fonts_to_spans")) 4373 tinyMCE.convertFontsToSpans(doc); 4374 4375 if (tinyMCE.getParam("fix_list_elements")) 4376 tinyMCE._fixListElements(doc); 4377 4378 if (tinyMCE.getParam("fix_table_elements")) 4379 tinyMCE._fixTables(doc); 4380 4381 // Call custom cleanup code 4382 tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body); 4383 4384 if (d) 4385 t2 = new Date().getTime(); 4386 4387 c.settings.on_save = on_save; 4388 4389 c.idCount = 0; 4390 c.serializationId = new Date().getTime().toString(32); // Unique ID needed for the content duplication bug 4391 c.serializedNodes = []; 4392 c.sourceIndex = -1; 4393 4394 if (s.cleanup_serializer == "xml") 4395 h = c.serializeNodeAsXML(elm, inn); 4396 else 4397 h = c.serializeNodeAsHTML(elm, inn); 4398 4399 if (d) 4400 t3 = new Date().getTime(); 4401 4402 // Post processing 4403 nb = tinyMCE.getParam('entity_encoding') == 'numeric' ? ' ' : ' '; 4404 h = h.replace(/<\/?(body|head|html)[^>]*>/gi, ''); 4405 h = h.replace(new RegExp(' (rowspan="1"|colspan="1")', 'g'), ''); 4406 h = h.replace(/<p><hr \/><\/p>/g, '<hr />'); 4407 h = h.replace(/<p>( | )<\/p><hr \/><p>( | )<\/p>/g, '<hr />'); 4408 h = h.replace(/<td>\s*<br \/>\s*<\/td>/g, '<td>' + nb + '</td>'); 4409 h = h.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>'); 4410 h = h.replace(/<br \/>$/, ''); // Remove last BR for Gecko 4411 h = h.replace(/<br \/><\/p>/g, '</p>'); // Remove last BR in P tags for Gecko 4412 h = h.replace(/<p>\s*( | )\s*<br \/>\s*( | )\s*<\/p>/g, '<p>' + nb + '</p>'); 4413 h = h.replace(/<p>\s*( | )\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>'); 4414 h = h.replace(/<p>\s*<br \/>\s* \s*<\/p>/g, '<p>' + nb + '</p>'); 4415 h = h.replace(new RegExp('<a>(.*?)<\\/a>', 'g'), '$1'); 4416 h = h.replace(/<p([^>]*)>\s*<\/p>/g, '<p$1>' + nb + '</p>'); 4417 4418 // Clean body 4419 if (/^\s*(<br \/>|<p> <\/p>|<p> <\/p>|<p><\/p>)\s*$/.test(h)) 4420 h = ''; 4421 4422 // If preformatted 4423 if (s.preformatted) { 4424 h = h.replace(/^<pre>/, ''); 4425 h = h.replace(/<\/pre>$/, ''); 4426 h = '<pre>' + h + '</pre>'; 4427 } 4428 4429 // Gecko specific processing 4430 if (tinyMCE.isGecko) { 4431 // Makes no sence but FF generates it!! 4432 h = h.replace(/<br \/>\s*<\/li>/g, '</li>'); 4433 h = h.replace(/ \s*<\/(dd|dt)>/g, '</$1>'); 4434 h = h.replace(/<o:p _moz-userdefined="" \/>/g, ''); 4435 h = h.replace(/<td([^>]*)>\s*<br \/>\s*<\/td>/g, '<td$1>' + nb + '</td>'); 4436 } 4437 4438 if (s.force_br_newlines) 4439 h = h.replace(/<p>( | )<\/p>/g, '<br />'); 4440 4441 // Call custom cleanup code 4442 h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h); 4443 4444 // Remove internal classes 4445 if (on_save) { 4446 h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), ''); 4447 h = h.replace(new RegExp(' ?class=""', 'g'), ''); 4448 } 4449 4450 if (s.remove_linebreaks && !c.settings.indent) 4451 h = h.replace(/\n|\r/g, ' '); 4452 4453 if (d) 4454 t4 = new Date().getTime(); 4455 4456 if (on_save && c.settings.indent) 4457 h = c.formatHTML(h); 4458 4459 // If encoding (not recommended option) 4460 if (on_submit && (s.encoding == "xml" || s.encoding == "html")) 4461 h = c.xmlEncode(h); 4462 4463 if (d) 4464 t5 = new Date().getTime(); 4465 4466 if (c.settings.debug) 4467 tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + "."); 4468 4469 return h; 4470 } 4471 }); 4472 4473 function TinyMCE_Cleanup() { 4474 this.isIE = (navigator.appName == "Microsoft Internet Explorer"); 4475 this.rules = tinyMCE.clearArray([]); 4476 4477 // Default config 4478 this.settings = { 4479 indent_elements : 'head,table,tbody,thead,tfoot,form,tr,ul,ol,blockquote,object', 4480 newline_before_elements : 'h1,h2,h3,h4,h5,h6,pre,address,div,ul,ol,li,meta,option,area,title,link,base,script,td', 4481 newline_after_elements : 'br,hr,p,pre,address,div,ul,ol,meta,option,area,link,base,script', 4482 newline_before_after_elements : 'html,head,body,table,thead,tbody,tfoot,tr,form,ul,ol,blockquote,p,object,param,hr,div', 4483 indent_char : '\t', 4484 indent_levels : 1, 4485 entity_encoding : 'raw', 4486 valid_elements : '*[*]', 4487 entities : '', 4488 url_converter : '', 4489 invalid_elements : '', 4490 verify_html : false 4491 }; 4492 4493 this.vElements = tinyMCE.clearArray([]); 4494 this.vElementsRe = ''; 4495 this.closeElementsRe = /^(IMG|BR|HR|LINK|META|BASE|INPUT|AREA)$/; 4496 this.codeElementsRe = /^(SCRIPT|STYLE)$/; 4497 this.serializationId = 0; 4498 this.mceAttribs = { 4499 href : 'mce_href', 4500 src : 'mce_src', 4501 type : 'mce_type' 4502 }; 4503 } 4504 4505 TinyMCE_Cleanup.prototype = { 4506 init : function(s) { 4507 var n, a, i, ir, or, st; 4508 4509 for (n in s) 4510 this.settings[n] = s[n]; 4511 4512 // Setup code formating 4513 s = this.settings; 4514 4515 // Setup regexps 4516 this.inRe = this._arrayToRe(s.indent_elements.split(','), '', '^<(', ')[^>]*'); 4517 this.ouRe = this._arrayToRe(s.indent_elements.split(','), '', '^<\\/(', ')[^>]*'); 4518 this.nlBeforeRe = this._arrayToRe(s.newline_before_elements.split(','), 'gi', '<(', ')([^>]*)>'); 4519 this.nlAfterRe = this._arrayToRe(s.newline_after_elements.split(','), 'gi', '<(', ')([^>]*)>'); 4520 this.nlBeforeAfterRe = this._arrayToRe(s.newline_before_after_elements.split(','), 'gi', '<(\\/?)(', ')([^>]*)>'); 4521 this.serializedNodes = []; 4522 4523 if (s.invalid_elements !== '') 4524 this.iveRe = this._arrayToRe(s.invalid_elements.toUpperCase().split(','), 'g', '^(', ')$'); 4525 else 4526 this.iveRe = null; 4527 4528 // Setup separator 4529 st = ''; 4530 for (i=0; i<s.indent_levels; i++) 4531 st += s.indent_char; 4532 4533 this.inStr = st; 4534 4535 // If verify_html if false force *[*] 4536 if (!s.verify_html) { 4537 s.valid_elements = '*[*]'; 4538 s.extended_valid_elements = ''; 4539 } 4540 4541 this.fillStr = s.entity_encoding == "named" ? " " : " "; 4542 this.idCount = 0; 4543 this.xmlEncodeRe = new RegExp('[\u007F-\uFFFF<>&"]', 'g'); 4544 }, 4545 4546 addRuleStr : function(s) { 4547 var r = this.parseRuleStr(s), n; 4548 4549 for (n in r) { 4550 if (r[n]) 4551 this.rules[n] = r[n]; 4552 } 4553 4554 this.vElements = tinyMCE.clearArray([]); 4555 4556 for (n in this.rules) { 4557 if (this.rules[n]) 4558 this.vElements[this.vElements.length] = this.rules[n].tag; 4559 } 4560 4561 this.vElementsRe = this._arrayToRe(this.vElements, ''); 4562 }, 4563 4564 isValid : function(n) { 4565 if (!this.rulesDone) 4566 this._setupRules(); // Will initialize cleanup rules 4567 4568 // Empty is true since it removes formatting 4569 if (!n) 4570 return true; 4571 4572 // Clean the name up a bit 4573 n = n.replace(/[^a-z0-9]+/gi, '').toUpperCase(); 4574 4575 return !tinyMCE.getParam('cleanup') || this.vElementsRe.test(n); 4576 }, 4577 4578 addChildRemoveRuleStr : function(s) { 4579 var x, y, p, i, t, tn, ta, cl, r; 4580 4581 if (!s) 4582 return; 4583 4584 ta = s.split(','); 4585 for (x=0; x<ta.length; x++) { 4586 s = ta[x]; 4587 4588 // Split tag/children 4589 p = this.split(/\[|\]/, s); 4590 if (p == null || p.length < 1) 4591 t = s.toUpperCase(); 4592 else 4593 t = p[0].toUpperCase(); 4594 4595 // Handle all tag names 4596 tn = this.split('/', t); 4597 for (y=0; y<tn.length; y++) { 4598 r = "^("; 4599 4600 // Build regex 4601 cl = this.split(/\|/, p[1]); 4602 for (i=0; i<cl.length; i++) { 4603 if (cl[i] == '%istrict') 4604 r += tinyMCE.inlineStrict; 4605 else if (cl[i] == '%itrans') 4606 r += tinyMCE.inlineTransitional; 4607 else if (cl[i] == '%istrict_na') 4608 r += tinyMCE.inlineStrict.substring(2); 4609 else if (cl[i] == '%itrans_na') 4610 r += tinyMCE.inlineTransitional.substring(2); 4611 else if (cl[i] == '%btrans') 4612 r += tinyMCE.blockElms; 4613 else if (cl[i] == '%strict') 4614 r += tinyMCE.blockStrict; 4615 else 4616 r += (cl[i].charAt(0) != '#' ? cl[i].toUpperCase() : cl[i]); 4617 4618 r += (i != cl.length - 1 ? '|' : ''); 4619 } 4620 4621 r += ')$'; 4622 4623 if (this.childRules == null) 4624 this.childRules = tinyMCE.clearArray([]); 4625 4626 this.childRules[tn[y]] = new RegExp(r); 4627 4628 if (p.length > 1) 4629 this.childRules[tn[y]].wrapTag = p[2]; 4630 } 4631 } 4632 }, 4633 4634 parseRuleStr : function(s) { 4635 var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray([]), dv; 4636 4637 if (s == null || s.length == 0) 4638 return or; 4639 4640 ta = s.split(','); 4641 for (x=0; x<ta.length; x++) { 4642 s = ta[x]; 4643 if (s.length == 0) 4644 continue; 4645 4646 // Split tag/attrs 4647 p = this.split(/\[|\]/, s); 4648 if (p == null || p.length < 1) 4649 t = s.toUpperCase(); 4650 else 4651 t = p[0].toUpperCase(); 4652 4653 // Handle all tag names 4654 tn = this.split('/', t); 4655 for (y=0; y<tn.length; y++) { 4656 r = {}; 4657 4658 r.tag = tn[y]; 4659 r.forceAttribs = null; 4660 r.defaultAttribs = null; 4661 r.validAttribValues = null; 4662 4663 // Handle prefixes 4664 px = r.tag.charAt(0); 4665 r.forceOpen = px == '+'; 4666 r.removeEmpty = px == '-'; 4667 r.fill = px == '#'; 4668 r.tag = r.tag.replace(/\+|-|#/g, ''); 4669 r.oTagName = tn[0].replace(/\+|-|#/g, '').toLowerCase(); 4670 r.isWild = new RegExp('\\*|\\?|\\+', 'g').test(r.tag); 4671 r.validRe = new RegExp(this._wildcardToRe('^' + r.tag + '$')); 4672 4673 // Setup valid attributes 4674 if (p.length > 1) { 4675 r.vAttribsRe = '^('; 4676 a = this.split(/\|/, p[1]); 4677 4678 for (i=0; i<a.length; i++) { 4679 t = a[i]; 4680 4681 if (t.charAt(0) == '!') { 4682 a[i] = t = t.substring(1); 4683 4684 if (!r.reqAttribsRe) 4685 r.reqAttribsRe = '\\s+(' + t; 4686 else 4687 r.reqAttribsRe += '|' + t; 4688 } 4689 4690 av = new RegExp('(=|:|<)(.*?)$').exec(t); 4691 t = t.replace(new RegExp('(=|:|<).*?$'), ''); 4692 if (av && av.length > 0) { 4693 if (av[0].charAt(0) == ':') { 4694 if (!r.forceAttribs) 4695 r.forceAttribs = tinyMCE.clearArray([]); 4696 4697 r.forceAttribs[t.toLowerCase()] = av[0].substring(1); 4698 } else if (av[0].charAt(0) == '=') { 4699 if (!r.defaultAttribs) 4700 r.defaultAttribs = tinyMCE.clearArray([]); 4701 4702 dv = av[0].substring(1); 4703 4704 r.defaultAttribs[t.toLowerCase()] = dv == '' ? "mce_empty" : dv; 4705 } else if (av[0].charAt(0) == '<') { 4706 if (!r.validAttribValues) 4707 r.validAttribValues = tinyMCE.clearArray([]); 4708 4709 r.validAttribValues[t.toLowerCase()] = this._arrayToRe(this.split('?', av[0].substring(1)), 'i'); 4710 } 4711 } 4712 4713 r.vAttribsRe += '' + t.toLowerCase() + (i != a.length - 1 ? '|' : ''); 4714 4715 a[i] = t.toLowerCase(); 4716 } 4717 4718 if (r.reqAttribsRe) 4719 r.reqAttribsRe = new RegExp(r.reqAttribsRe + ')=\"', 'g'); 4720 4721 r.vAttribsRe += ')$'; 4722 r.vAttribsRe = this._wildcardToRe(r.vAttribsRe); 4723 r.vAttribsReIsWild = new RegExp('\\*|\\?|\\+', 'g').test(r.vAttribsRe); 4724 r.vAttribsRe = new RegExp(r.vAttribsRe); 4725 r.vAttribs = a.reverse(); 4726 4727 //tinyMCE.debug(r.tag, r.oTagName, r.vAttribsRe, r.vAttribsReWC); 4728 } else { 4729 r.vAttribsRe = ''; 4730 r.vAttribs = tinyMCE.clearArray([]); 4731 r.vAttribsReIsWild = false; 4732 } 4733 4734 or[r.tag] = r; 4735 } 4736 } 4737 4738 return or; 4739 }, 4740 4741 serializeNodeAsXML : function(n) { 4742 var s, b; 4743 4744 if (!this.xmlDoc) { 4745 if (this.isIE) { 4746 try {this.xmlDoc = new ActiveXObject('MSXML2.DOMDocument');} catch (e) {} 4747 4748 if (!this.xmlDoc) 4749 try {this.xmlDoc = new ActiveXObject('Microsoft.XmlDom');} catch (e) {} 4750 } else 4751 this.xmlDoc = document.implementation.createDocument('', '', null); 4752 4753 if (!this.xmlDoc) 4754 alert("Error XML Parser could not be found."); 4755 } 4756 4757 if (this.xmlDoc.firstChild) 4758 this.xmlDoc.removeChild(this.xmlDoc.firstChild); 4759 4760 b = this.xmlDoc.createElement("html"); 4761 b = this.xmlDoc.appendChild(b); 4762 4763 this._convertToXML(n, b); 4764 4765 if (this.isIE) 4766 return this.xmlDoc.xml; 4767 else 4768 return new XMLSerializer().serializeToString(this.xmlDoc); 4769 }, 4770 4771 _convertToXML : function(n, xn) { 4772 var xd, el, i, l, cn, at, no, hc = false; 4773 4774 if (tinyMCE.isRealIE && this._isDuplicate(n)) 4775 return; 4776 4777 xd = this.xmlDoc; 4778 4779 switch (n.nodeType) { 4780 case 1: // Element 4781 hc = n.hasChildNodes(); 4782 4783 el = xd.createElement(n.nodeName.toLowerCase()); 4784 4785 at = n.attributes; 4786 for (i=at.length-1; i>-1; i--) { 4787 no = at[i]; 4788 4789 if (no.specified && no.nodeValue) 4790 el.setAttribute(no.nodeName.toLowerCase(), no.nodeValue); 4791 } 4792 4793 if (!hc && !this.closeElementsRe.test(n.nodeName)) 4794 el.appendChild(xd.createTextNode("")); 4795 4796 xn = xn.appendChild(el); 4797 break; 4798 4799 case 3: // Text 4800 xn.appendChild(xd.createTextNode(n.nodeValue)); 4801 return; 4802 4803 case 8: // Comment 4804 xn.appendChild(xd.createComment(n.nodeValue)); 4805 return; 4806 } 4807 4808 if (hc) { 4809 cn = n.childNodes; 4810 4811 for (i=0, l=cn.length; i<l; i++) 4812 this._convertToXML(cn[i], xn); 4813 } 4814 }, 4815 4816 serializeNodeAsHTML : function(n, inn) { 4817 var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr, nn; 4818 4819 if (!this.rulesDone) 4820 this._setupRules(); // Will initialize cleanup rules 4821 4822 if (tinyMCE.isRealIE && this._isDuplicate(n)) 4823 return ''; 4824 4825 // Skip non valid child elements 4826 if (n.parentNode && this.childRules != null) { 4827 cr = this.childRules[n.parentNode.nodeName]; 4828 4829 if (typeof(cr) != "undefined" && !cr.test(n.nodeName)) { 4830 st = true; 4831 t = null; 4832 } 4833 } 4834 4835 switch (n.nodeType) { 4836 case 1: // Element 4837 hc = n.hasChildNodes(); 4838 4839 if (st) 4840 break; 4841 4842 nn = n.nodeName; 4843 4844 if (tinyMCE.isRealIE) { 4845 // MSIE sometimes produces <//tag> 4846 if (n.nodeName.indexOf('/') != -1) 4847 break; 4848 4849 // MSIE has it's NS in a separate attrib 4850 if (n.scopeName && n.scopeName != 'HTML') 4851 nn = n.scopeName.toUpperCase() + ':' + nn.toUpperCase(); 4852 } else if (tinyMCE.isOpera && nn.indexOf(':') > 0) 4853 nn = nn.toUpperCase(); 4854 4855 // Convert fonts to spans 4856 if (this.settings.convert_fonts_to_spans) { 4857 // On get content FONT -> SPAN 4858 if (this.settings.on_save && nn == 'FONT') 4859 nn = 'SPAN'; 4860 4861 // On insert content SPAN -> FONT 4862 if (!this.settings.on_save && nn == 'SPAN') 4863 nn = 'FONT'; 4864 } 4865 4866 if (this.vElementsRe.test(nn) && (!this.iveRe || !this.iveRe.test(nn)) && !inn) { 4867 va = true; 4868 4869 r = this.rules[nn]; 4870 if (!r) { 4871 at = this.rules; 4872 for (no in at) { 4873 if (at[no] && at[no].validRe.test(nn)) { 4874 r = at[no]; 4875 break; 4876 } 4877 } 4878 } 4879 4880 en = r.isWild ? nn.toLowerCase() : r.oTagName; 4881 f = r.fill; 4882 4883 if (r.removeEmpty && !hc) 4884 return ""; 4885 4886 t = '<' + en; 4887 4888 if (r.vAttribsReIsWild) { 4889 // Serialize wildcard attributes 4890 at = n.attributes; 4891 for (i=at.length-1; i>-1; i--) { 4892 no = at[i]; 4893 if (no.specified && r.vAttribsRe.test(no.nodeName)) 4894 t += this._serializeAttribute(n, r, no.nodeName); 4895 } 4896 } else { 4897 // Serialize specific attributes 4898 for (i=r.vAttribs.length-1; i>-1; i--) 4899 t += this._serializeAttribute(n, r, r.vAttribs[i]); 4900 } 4901 4902 // Serialize mce_ atts 4903 if (!this.settings.on_save) { 4904 at = this.mceAttribs; 4905 4906 for (no in at) { 4907 if (at[no]) 4908 t += this._serializeAttribute(n, r, at[no]); 4909 } 4910 } 4911 4912 // Check for required attribs 4913 if (r.reqAttribsRe && !t.match(r.reqAttribsRe)) 4914 t = null; 4915 4916 // Close these 4917 if (t != null && this.closeElementsRe.test(nn)) 4918 return t + ' />'; 4919 4920 if (t != null) 4921 h += t + '>'; 4922 4923 if (this.isIE && this.codeElementsRe.test(nn)) 4924 h += n.innerHTML; 4925 } 4926 break; 4927 4928 case 3: // Text 4929 if (st) 4930 break; 4931 4932 if (n.parentNode && this.codeElementsRe.test(n.parentNode.nodeName)) 4933 return this.isIE ? '' : n.nodeValue; 4934 4935 return this.xmlEncode(n.nodeValue); 4936 4937 case 8: // Comment 4938 if (st) 4939 break; 4940 4941 return "<!--" + this._trimComment(n.nodeValue) + "-->"; 4942 } 4943 4944 if (hc) { 4945 cn = n.childNodes; 4946 4947 for (i=0, l=cn.length; i<l; i++) 4948 h += this.serializeNodeAsHTML(cn[i]); 4949 } 4950 4951 // Fill empty nodes 4952 if (f && !hc) 4953 h += this.fillStr; 4954 4955 // End element 4956 if (t != null && va) 4957 h += '</' + en + '>'; 4958 4959 return h; 4960 }, 4961 4962 _serializeAttribute : function(n, r, an) { 4963 var av = '', t, os = this.settings.on_save; 4964 4965 if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0)) 4966 return ''; 4967 4968 if (os && this.mceAttribs[an]) 4969 av = this._getAttrib(n, this.mceAttribs[an]); 4970 4971 if (av.length == 0) 4972 av = this._getAttrib(n, an); 4973 4974 if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) { 4975 av = t; 4976 4977 if (av == "mce_empty") 4978 return " " + an + '=""'; 4979 } 4980 4981 if (r.forceAttribs && (t = r.forceAttribs[an])) 4982 av = t; 4983 4984 if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an)) 4985 av = this._urlConverter(this, n, av); 4986 4987 if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av)) 4988 return ""; 4989 4990 if (av.length != 0 && av == "{$uid}") 4991 av = "uid_" + (this.idCount++); 4992 4993 if (av.length != 0) { 4994 if (an.indexOf('on') != 0) 4995 av = this.xmlEncode(av, 1); 4996 4997 return " " + an + "=" + '"' + av + '"'; 4998 } 4999 5000 return ""; 5001 }, 5002 5003 formatHTML : function(h) { 5004 var s = this.settings, p = '', i = 0, li = 0, o = '', l; 5005 5006 // Replace BR in pre elements to \n 5007 h = h.replace(/<pre([^>]*)>(.*?)<\/pre>/gi, function (a, b, c) { 5008 c = c.replace(/<br\s*\/>/gi, '\n'); 5009 return '<pre' + b + '>' + c + '</pre>'; 5010 }); 5011 5012 h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :) 5013 h = '\n' + h; 5014 h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting 5015 h = h.replace(this.nlBeforeRe, '\n<$1$2>'); 5016 h = h.replace(this.nlAfterRe, '<$1$2>\n'); 5017 h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n'); 5018 h += '\n'; 5019 5020 //tinyMCE.debug(h); 5021 5022 while ((i = h.indexOf('\n', i + 1)) != -1) { 5023 if ((l = h.substring(li + 1, i)).length != 0) { 5024 if (this.ouRe.test(l) && p.length >= s.indent_levels) 5025 p = p.substring(s.indent_levels); 5026 5027 o += p + l + '\n'; 5028 5029 if (this.inRe.test(l)) 5030 p += this.inStr; 5031 } 5032 5033 li = i; 5034 } 5035 5036 //tinyMCE.debug(h); 5037 5038 return o; 5039 }, 5040 5041 xmlEncode : function(s) { 5042 var cl = this, re = this.xmlEncodeRe; 5043 5044 if (!this.entitiesDone) 5045 this._setupEntities(); // Will intialize lookup table 5046 5047 switch (this.settings.entity_encoding) { 5048 case "raw": 5049 return tinyMCE.xmlEncode(s); 5050 5051 case "named": 5052 return s.replace(re, function (c) { 5053 var b = cl.entities[c.charCodeAt(0)]; 5054 5055 return b ? '&' + b + ';' : c; 5056 }); 5057 5058 case "numeric": 5059 return s.replace(re, function (c) { 5060 return '&#' + c.charCodeAt(0) + ';'; 5061 }); 5062 } 5063 5064 return s; 5065 }, 5066 5067 split : function(re, s) { 5068 var i, l, o = [], c = s.split(re); 5069 5070 for (i=0, l=c.length; i<l; i++) { 5071 if (c[i] !== '') 5072 o[i] = c[i]; 5073 } 5074 5075 return o; 5076 }, 5077 5078 _trimComment : function(s) { 5079 // Remove mce_src, mce_href 5080 s = s.replace(new RegExp('\\smce_src=\"[^\"]*\"', 'gi'), ""); 5081 s = s.replace(new RegExp('\\smce_href=\"[^\"]*\"', 'gi'), ""); 5082 5083 return s; 5084 }, 5085 5086 _getAttrib : function(e, n, d) { 5087 var v, ex, nn; 5088 5089 if (typeof(d) == "undefined") 5090 d = ""; 5091 5092 if (!e || e.nodeType != 1) 5093 return d; 5094 5095 try { 5096 v = e.getAttribute(n, 0); 5097 } catch (ex) { 5098 // IE 7 may cast exception on invalid attributes 5099 v = e.getAttribute(n, 2); 5100 } 5101 5102 if (n == "class" && !v) 5103 v = e.className; 5104 5105 if (this.isIE) { 5106 if (n == "http-equiv") 5107 v = e.httpEquiv; 5108 5109 nn = e.nodeName; 5110 5111 // Skip the default values that IE returns 5112 if (nn == "FORM" && n == "enctype" && v == "application/x-www-form-urlencoded") 5113 v = ""; 5114 5115 if (nn == "INPUT" && n == "size" && v == "20") 5116 v = ""; 5117 5118 if (nn == "INPUT" && n == "maxlength" && v == "2147483647") 5119 v = ""; 5120 5121 // Images 5122 if (n == "width" || n == "height") 5123 v = e.getAttribute(n, 2); 5124 } 5125 5126 if (n == 'style' && v) { 5127 if (!tinyMCE.isOpera) 5128 v = e.style.cssText; 5129 5130 v = tinyMCE.serializeStyle(tinyMCE.parseStyle(v)); 5131 } 5132 5133 if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v !== '') 5134 v = tinyMCE.cleanupEventStr(v); 5135 5136 return (v && v !== '') ? '' + v : d; 5137 }, 5138 5139 _urlConverter : function(c, n, v) { 5140 if (!c.settings.on_save) 5141 return tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, v); 5142 else if (tinyMCE.getParam('convert_urls')) { 5143 if (!this.urlConverter) 5144 this.urlConverter = eval(tinyMCE.settings.urlconverter_callback); 5145 5146 return this.urlConverter(v, n, true); 5147 } 5148 5149 return v; 5150 }, 5151 5152 _arrayToRe : function(a, op, be, af) { 5153 var i, r; 5154 5155 op = typeof(op) == "undefined" ? "gi" : op; 5156 be = typeof(be) == "undefined" ? "^(" : be; 5157 af = typeof(af) == "undefined" ? ")$" : af; 5158 5159 r = be; 5160 5161 for (i=0; i<a.length; i++) 5162 r += this._wildcardToRe(a[i]) + (i != a.length-1 ? "|" : ""); 5163 5164 r += af; 5165 5166 return new RegExp(r, op); 5167 }, 5168 5169 _wildcardToRe : function(s) { 5170 s = s.replace(/\?/g, '(\\S?)'); 5171 s = s.replace(/\+/g, '(\\S+)'); 5172 s = s.replace(/\*/g, '(\\S*)'); 5173 5174 return s; 5175 }, 5176 5177 _setupEntities : function() { 5178 var n, a, i, s = this.settings; 5179 5180 // Setup entities 5181 if (s.entity_encoding == "named") { 5182 n = tinyMCE.clearArray([]); 5183 a = this.split(',', s.entities); 5184 for (i=0; i<a.length; i+=2) 5185 n[a[i]] = a[i+1]; 5186 5187 this.entities = n; 5188 } 5189 5190 this.entitiesDone = true; 5191 }, 5192 5193 _setupRules : function() { 5194 var s = this.settings; 5195 5196 // Setup default rule 5197 this.addRuleStr(s.valid_elements); 5198 this.addRuleStr(s.extended_valid_elements); 5199 this.addChildRemoveRuleStr(s.valid_child_elements); 5200 5201 this.rulesDone = true; 5202 }, 5203 5204 _isDuplicate : function(n) { 5205 var i, l, sn; 5206 5207 if (!this.settings.fix_content_duplication) 5208 return false; 5209 5210 if (tinyMCE.isRealIE && n.nodeType == 1) { 5211 // Mark elements 5212 if (n.mce_serialized == this.serializationId) 5213 return true; 5214 5215 n.setAttribute('mce_serialized', this.serializationId); 5216 } else { 5217 sn = this.serializedNodes; 5218 5219 // Search lookup table for text nodes and comments 5220 for (i=0, l = sn.length; i<l; i++) { 5221 if (sn[i] == n) 5222 return true; 5223 } 5224 5225 sn.push(n); 5226 } 5227 5228 return false; 5229 } 5230 5231 }; 5232 5233 /* file:jscripts/tiny_mce/classes/TinyMCE_DOMUtils.class.js */ 5234 5235 tinyMCE.add(TinyMCE_Engine, { 5236 createTagHTML : function(tn, a, h) { 5237 var o = '', f = tinyMCE.xmlEncode, n; 5238 5239 o = '<' + tn; 5240 5241 if (a) { 5242 for (n in a) { 5243 if (typeof(a[n]) != 'function' && a[n] != null) 5244 o += ' ' + f(n) + '="' + f('' + a[n]) + '"'; 5245 } 5246 } 5247 5248 o += !h ? ' />' : '>' + h + '</' + tn + '>'; 5249 5250 return o; 5251 }, 5252 5253 createTag : function(d, tn, a, h) { 5254 var o = d.createElement(tn), n; 5255 5256 if (a) { 5257 for (n in a) { 5258 if (typeof(a[n]) != 'function' && a[n] != null) 5259 tinyMCE.setAttrib(o, n, a[n]); 5260 } 5261 } 5262 5263 if (h) 5264 o.innerHTML = h; 5265 5266 return o; 5267 }, 5268 5269 getElementByAttributeValue : function(n, e, a, v) { 5270 return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0]; 5271 }, 5272 5273 getElementsByAttributeValue : function(n, e, a, v) { 5274 var i, nl = n.getElementsByTagName(e), o = []; 5275 5276 for (i=0; i<nl.length; i++) { 5277 if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1) 5278 o[o.length] = nl[i]; 5279 } 5280 5281 return o; 5282 }, 5283 5284 isBlockElement : function(n) { 5285 return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName); 5286 }, 5287 5288 getParentBlockElement : function(n, r) { 5289 return this.getParentNode(n, function(n) { 5290 return tinyMCE.isBlockElement(n); 5291 }, r); 5292 5293 return null; 5294 }, 5295 5296 insertAfter : function(n, r){ 5297 if (r.nextSibling) 5298 r.parentNode.insertBefore(n, r.nextSibling); 5299 else 5300 r.parentNode.appendChild(n); 5301 }, 5302 5303 setInnerHTML : function(e, h) { 5304 var i, nl, n; 5305 5306 // Convert all strong/em to b/i in Gecko 5307 if (tinyMCE.isGecko) { 5308 h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>'); 5309 h = h.replace(/<em([^>]*)>/gi, '<i$1>'); 5310 h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>'); 5311 h = h.replace(/<strong([^>]*)>/gi, '<b$1>'); 5312 h = h.replace(/<\/strong>/gi, '</b>'); 5313 h = h.replace(/<\/em>/gi, '</i>'); 5314 } 5315 5316 if (tinyMCE.isRealIE) { 5317 // Since MSIE handles invalid HTML better that valid XHTML we 5318 // need to make some things invalid. <hr /> gets converted to <hr>. 5319 h = h.replace(/\s\/>/g, '>'); 5320 5321 // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones 5322 h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true"> </p>'); // Keep empty paragraphs 5323 h = h.replace(/<p([^>]*)>\s* \s*<\/p>/gi, '<p$1 mce_keep="true"> </p>'); // Keep empty paragraphs 5324 h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true"> </p>'); // Keep empty paragraphs 5325 5326 // Remove first comment 5327 e.innerHTML = tinyMCE.uniqueTag + h; 5328 e.firstChild.removeNode(true); 5329 5330 // Remove weird auto generated empty paragraphs unless it's supposed to be there 5331 nl = e.getElementsByTagName("p"); 5332 for (i=nl.length-1; i>=0; i--) { 5333 n = nl[i]; 5334 5335 if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep) 5336 n.parentNode.removeChild(n); 5337 } 5338 } else { 5339 h = this.fixGeckoBaseHREFBug(1, e, h); 5340 e.innerHTML = h; 5341 this.fixGeckoBaseHREFBug(2, e, h); 5342 } 5343 }, 5344 5345 getOuterHTML : function(e) { 5346 var d; 5347 5348 if (tinyMCE.isIE) 5349 return e.outerHTML; 5350 5351 d = e.ownerDocument.createElement("body"); 5352 d.appendChild(e.cloneNode(true)); 5353 5354 return d.innerHTML; 5355 }, 5356 5357 setOuterHTML : function(e, h, d) { 5358 var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t; 5359 5360 if (tinyMCE.isIE && e.nodeType == 1) 5361 e.outerHTML = h; 5362 else { 5363 t = d.createElement("body"); 5364 t.innerHTML = h; 5365 5366 for (i=0, nl=t.childNodes; i<nl.length; i++) 5367 e.parentNode.insertBefore(nl[i].cloneNode(true), e); 5368 5369 e.parentNode.removeChild(e); 5370 } 5371 }, 5372 5373 _getElementById : function(id, d) { 5374 var e, i, j, f; 5375 5376 if (typeof(d) == "undefined") 5377 d = document; 5378 5379 e = d.getElementById(id); 5380 if (!e) { 5381 f = d.forms; 5382 5383 for (i=0; i<f.length; i++) { 5384 for (j=0; j<f[i].elements.length; j++) { 5385 if (f[i].elements[j].name == id) { 5386 e = f[i].elements[j]; 5387 break; 5388 } 5389 } 5390 } 5391 } 5392 5393 return e; 5394 }, 5395 5396 getNodeTree : function(n, na, t, nn) { 5397 return this.selectNodes(n, function(n) { 5398 return (!t || n.nodeType == t) && (!nn || n.nodeName == nn); 5399 }, na ? na : []); 5400 }, 5401 5402 getParentElement : function(n, na, f, r) { 5403 var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v; 5404 5405 // Compatiblity with old scripts where f param was a attribute string 5406 if (f && typeof(f) == 'string') 5407 return this.getParentElement(n, na, function(no) {return tinyMCE.getAttrib(no, f) !== '';}); 5408 5409 return this.getParentNode(n, function(n) { 5410 return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n)); 5411 }, r); 5412 }, 5413 5414 getParentNode : function(n, f, r) { 5415 while (n) { 5416 if (n == r) 5417 return null; 5418 5419 if (f(n)) 5420 return n; 5421 5422 n = n.parentNode; 5423 } 5424 5425 return null; 5426 }, 5427 5428 getAttrib : function(elm, name, dv) { 5429 var v; 5430 5431 if (typeof(dv) == "undefined") 5432 dv = ""; 5433 5434 // Not a element 5435 if (!elm || elm.nodeType != 1) 5436 return dv; 5437 5438 try { 5439 v = elm.getAttribute(name, 0); 5440 } catch (ex) { 5441 // IE 7 may cast exception on invalid attributes 5442 v = elm.getAttribute(name, 2); 5443 } 5444 5445 // Try className for class attrib 5446 if (name == "class" && !v) 5447 v = elm.className; 5448 5449 // Workaround for a issue with Firefox 1.5rc2+ 5450 if (tinyMCE.isGecko) { 5451 if (name == "src" && elm.src != null && elm.src !== '') 5452 v = elm.src; 5453 5454 // Workaround for a issue with Firefox 1.5rc2+ 5455 if (name == "href" && elm.href != null && elm.href !== '') 5456 v = elm.href; 5457 } else if (tinyMCE.isIE) { 5458 switch (name) { 5459 case "http-equiv": 5460 v = elm.httpEquiv; 5461 break; 5462 5463 case "width": 5464 case "height": 5465 v = elm.getAttribute(name, 2); 5466 break; 5467 } 5468 } 5469 5470 if (name == "style" && !tinyMCE.isOpera) 5471 v = elm.style.cssText; 5472 5473 return (v && v !== '') ? v : dv; 5474 }, 5475 5476 setAttrib : function(el, name, va, fix) { 5477 if (typeof(va) == "number" && va != null) 5478 va = "" + va; 5479 5480 if (fix) { 5481 if (va == null) 5482 va = ""; 5483 5484 va = va.replace(/[^0-9%]/g, ''); 5485 } 5486 5487 if (name == "style") 5488 el.style.cssText = va; 5489 5490 if (name == "class") 5491 el.className = va; 5492 5493 if (va != null && va !== '' && va != -1) 5494 el.setAttribute(name, va); 5495 else 5496 el.removeAttribute(name); 5497 }, 5498 5499 setStyleAttrib : function(e, n, v) { 5500 e.style[n] = v; 5501 5502 // Style attrib deleted in IE 5503 if (tinyMCE.isIE && v == null || v == '') { 5504 v = tinyMCE.serializeStyle(tinyMCE.parseStyle(e.style.cssText)); 5505 e.style.cssText = v; 5506 e.setAttribute("style", v); 5507 } 5508 }, 5509 5510 switchClass : function(ei, c) { 5511 var e; 5512 5513 if (tinyMCE.switchClassCache[ei]) 5514 e = tinyMCE.switchClassCache[ei]; 5515 else 5516 e = tinyMCE.switchClassCache[ei] = document.getElementById(ei); 5517 5518 if (e) { 5519 // Keep tile mode 5520 if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0) 5521 c = 'mceTiledButton ' + c; 5522 5523 e.className = c; 5524 } 5525 }, 5526 5527 getAbsPosition : function(n, cn) { 5528 var l = 0, t = 0; 5529 5530 while (n && n != cn) { 5531 l += n.offsetLeft; 5532 t += n.offsetTop; 5533 n = n.offsetParent; 5534 } 5535 5536 return {absLeft : l, absTop : t}; 5537 }, 5538 5539 prevNode : function(e, n) { 5540 var a = n.split(','), i; 5541 5542 while ((e = e.previousSibling) != null) { 5543 for (i=0; i<a.length; i++) { 5544 if (e.nodeName == a[i]) 5545 return e; 5546 } 5547 } 5548 5549 return null; 5550 }, 5551 5552 nextNode : function(e, n) { 5553 var a = n.split(','), i; 5554 5555 while ((e = e.nextSibling) != null) { 5556 for (i=0; i<a.length; i++) { 5557 if (e.nodeName == a[i]) 5558 return e; 5559 } 5560 } 5561 5562 return null; 5563 }, 5564 5565 selectElements : function(n, na, f) { 5566 var i, a = [], nl, x; 5567 5568 for (x=0, na = na.split(','); x<na.length; x++) 5569 for (i=0, nl = n.getElementsByTagName(na[x]); i<nl.length; i++) 5570 (!f || f(nl[i])) && a.push(nl[i]); 5571 5572 return a; 5573 }, 5574 5575 selectNodes : function(n, f, a) { 5576 var i; 5577 5578 if (!a) 5579 a = []; 5580 5581 if (f(n)) 5582 a[a.length] = n; 5583 5584 if (n.hasChildNodes()) { 5585 for (i=0; i<n.childNodes.length; i++) 5586 tinyMCE.selectNodes(n.childNodes[i], f, a); 5587 } 5588 5589 return a; 5590 }, 5591 5592 addCSSClass : function(e, c, b) { 5593 var o = this.removeCSSClass(e, c); 5594 return e.className = b ? c + (o !== '' ? (' ' + o) : '') : (o !== '' ? (o + ' ') : '') + c; 5595 }, 5596 5597 removeCSSClass : function(e, c) { 5598 c = e.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' '); 5599 return e.className = c != ' ' ? c : ''; 5600 }, 5601 5602 hasCSSClass : function(n, c) { 5603 return new RegExp('\\b' + c + '\\b', 'g').test(n.className); 5604 }, 5605 5606 renameElement : function(e, n, d) { 5607 var ne, i, ar; 5608 5609 d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d; 5610 5611 if (e) { 5612 ne = d.createElement(n); 5613 5614 ar = e.attributes; 5615 for (i=ar.length-1; i>-1; i--) { 5616 if (ar[i].specified && ar[i].nodeValue) 5617 ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue); 5618 } 5619 5620 ar = e.childNodes; 5621 for (i=0; i<ar.length; i++) 5622 ne.appendChild(ar[i].cloneNode(true)); 5623 5624 e.parentNode.replaceChild(ne, e); 5625 } 5626 }, 5627 5628 getViewPort : function(w) { 5629 var d = w.document, m = d.compatMode == 'CSS1Compat', b = d.body, de = d.documentElement; 5630 5631 return { 5632 left : w.pageXOffset || (m ? de.scrollLeft : b.scrollLeft), 5633 top : w.pageYOffset || (m ? de.scrollTop : b.scrollTop), 5634 width : w.innerWidth || (m ? de.clientWidth : b.clientWidth), 5635 height : w.innerHeight || (m ? de.clientHeight : b.clientHeight) 5636 }; 5637 }, 5638 5639 getStyle : function(n, na, d) { 5640 if (!n) 5641 return false; 5642 5643 // Gecko 5644 if (tinyMCE.isGecko && n.ownerDocument.defaultView) { 5645 try { 5646 return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na); 5647 } catch (n) { 5648 // Old safari might fail 5649 return null; 5650 } 5651 } 5652 5653 // Camelcase it, if needed 5654 na = na.replace(/-(\D)/g, function(a, b){ 5655 return b.toUpperCase(); 5656 }); 5657 5658 // IE & Opera 5659 if (n.currentStyle) 5660 return n.currentStyle[na]; 5661 5662 return false; 5663 } 5664 5665 }); 5666 5667 /* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */ 5668 5669 tinyMCE.add(TinyMCE_Engine, { 5670 parseURL : function(url_str) { 5671 var urlParts = [], i, pos, lastPos, chr; 5672 5673 if (url_str) { 5674 // Parse protocol part 5675 pos = url_str.indexOf('://'); 5676 if (pos != -1) { 5677 urlParts.protocol = url_str.substring(0, pos); 5678 lastPos = pos + 3; 5679 } 5680 5681 // Find port or path start 5682 for (i=lastPos; i<url_str.length; i++) { 5683 chr = url_str.charAt(i); 5684 5685 if (chr == ':') 5686 break; 5687 5688 if (chr == '/') 5689 break; 5690 } 5691 pos = i; 5692 5693 // Get host 5694 urlParts.host = url_str.substring(lastPos, pos); 5695 5696 // Get port 5697 urlParts.port = ""; 5698 lastPos = pos; 5699 if (url_str.charAt(pos) == ':') { 5700 pos = url_str.indexOf('/', lastPos); 5701 urlParts.port = url_str.substring(lastPos+1, pos); 5702 } 5703 5704 // Get path 5705 lastPos = pos; 5706 pos = url_str.indexOf('?', lastPos); 5707 5708 if (pos == -1) 5709 pos = url_str.indexOf('#', lastPos); 5710 5711 if (pos == -1) 5712 pos = url_str.length; 5713 5714 urlParts.path = url_str.substring(lastPos, pos); 5715 5716 // Get query 5717 lastPos = pos; 5718 if (url_str.charAt(pos) == '?') { 5719 pos = url_str.indexOf('#'); 5720 pos = (pos == -1) ? url_str.length : pos; 5721 urlParts.query = url_str.substring(lastPos+1, pos); 5722 } 5723 5724 // Get anchor 5725 lastPos = pos; 5726 if (url_str.charAt(pos) == '#') { 5727 pos = url_str.length; 5728 urlParts.anchor = url_str.substring(lastPos+1, pos); 5729 } 5730 } 5731 5732 return urlParts; 5733 }, 5734 5735 serializeURL : function(up) { 5736 var o = ""; 5737 5738 if (up.protocol) 5739 o += up.protocol + "://"; 5740 5741 if (up.host) 5742 o += up.host; 5743 5744 if (up.port) 5745 o += ":" + up.port; 5746 5747 if (up.path) 5748 o += up.path; 5749 5750 if (up.query) 5751 o += "?" + up.query; 5752 5753 if (up.anchor) 5754 o += "#" + up.anchor; 5755 5756 return o; 5757 }, 5758 5759 convertAbsoluteURLToRelativeURL : function(base_url, url_to_relative) { 5760 var baseURL = this.parseURL(base_url), targetURL = this.parseURL(url_to_relative); 5761 var i, strTok1, strTok2, breakPoint = 0, outPath = "", forceSlash = false; 5762 var fileName, pos; 5763 5764 if (targetURL.path == '') 5765 targetURL.path = "/"; 5766 else 5767 forceSlash = true; 5768 5769 // Crop away last path part 5770 base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/')); 5771 strTok1 = base_url.split('/'); 5772 strTok2 = targetURL.path.split('/'); 5773 5774 if (strTok1.length >= strTok2.length) { 5775 for (i=0; i<strTok1.length; i++) { 5776 if (i >= strTok2.length || strTok1[i] != strTok2[i]) { 5777 breakPoint = i + 1; 5778 break; 5779 } 5780 } 5781 } 5782 5783 if (strTok1.length < strTok2.length) { 5784 for (i=0; i<strTok2.length; i++) { 5785 if (i >= strTok1.length || strTok1[i] != strTok2[i]) { 5786 breakPoint = i + 1; 5787 break; 5788 } 5789 } 5790 } 5791 5792 if (breakPoint == 1) 5793 return targetURL.path; 5794 5795 for (i=0; i<(strTok1.length-(breakPoint-1)); i++) 5796 outPath += "../"; 5797 5798 for (i=breakPoint-1; i<strTok2.length; i++) { 5799 if (i != (breakPoint-1)) 5800 outPath += "/" + strTok2[i]; 5801 else 5802 outPath += strTok2[i]; 5803 } 5804 5805 targetURL.protocol = null; 5806 targetURL.host = null; 5807 targetURL.port = null; 5808 targetURL.path = outPath == '' && forceSlash ? "/" : outPath; 5809 5810 // Remove document prefix from local anchors 5811 fileName = baseURL.path; 5812 5813 if ((pos = fileName.lastIndexOf('/')) != -1) 5814 fileName = fileName.substring(pos + 1); 5815 5816 // Is local anchor 5817 if (fileName == targetURL.path && targetURL.anchor !== '') 5818 targetURL.path = ""; 5819 5820 // If empty and not local anchor force filename or slash 5821 if (targetURL.path == '' && !targetURL.anchor) 5822 targetURL.path = fileName !== '' ? fileName : "/"; 5823 5824 return this.serializeURL(targetURL); 5825 }, 5826 5827 convertRelativeToAbsoluteURL : function(base_url, relative_url) { 5828 var baseURL = this.parseURL(base_url), baseURLParts, relURLParts, newRelURLParts, numBack, relURL = this.parseURL(relative_url), i; 5829 var len, absPath, start, end, newBaseURLParts; 5830 5831 if (relative_url == '' || relative_url.indexOf('://') != -1 || /^(mailto:|javascript:|#|\/)/.test(relative_url)) 5832 return relative_url; 5833 5834 // Split parts 5835 baseURLParts = baseURL.path.split('/'); 5836 relURLParts = relURL.path.split('/'); 5837 5838 // Remove empty chunks 5839 newBaseURLParts = []; 5840 for (i=baseURLParts.length-1; i>=0; i--) { 5841 if (baseURLParts[i].length == 0) 5842 continue; 5843 5844 newBaseURLParts[newBaseURLParts.length] = baseURLParts[i]; 5845 } 5846 baseURLParts = newBaseURLParts.reverse(); 5847 5848 // Merge relURLParts chunks 5849 newRelURLParts = []; 5850 numBack = 0; 5851 for (i=relURLParts.length-1; i>=0; i--) { 5852 if (relURLParts[i].length == 0 || relURLParts[i] == ".") 5853 continue; 5854 5855 if (relURLParts[i] == '..') { 5856 numBack++; 5857 continue; 5858 } 5859 5860 if (numBack > 0) { 5861 numBack--; 5862 continue; 5863 } 5864 5865 newRelURLParts[newRelURLParts.length] = relURLParts[i]; 5866 } 5867 5868 relURLParts = newRelURLParts.reverse(); 5869 5870 // Remove end from absolute path 5871 len = baseURLParts.length-numBack; 5872 absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/'); 5873 start = ""; 5874 end = ""; 5875 5876 // Build output URL 5877 relURL.protocol = baseURL.protocol; 5878 relURL.host = baseURL.host; 5879 relURL.port = baseURL.port; 5880 5881 // Re-add trailing slash if it's removed 5882 if (relURL.path.charAt(relURL.path.length-1) == "/") 5883 absPath += "/"; 5884 5885 relURL.path = absPath; 5886 5887 return this.serializeURL(relURL); 5888 }, 5889 5890 convertURL : function(url, node, on_save) { 5891 var dl = document.location, start, portPart, urlParts, baseUrlParts, tmpUrlParts, curl; 5892 var prot = dl.protocol, host = dl.hostname, port = dl.port; 5893 5894 // Pass through file protocol 5895 if (prot == "file:") 5896 return url; 5897 5898 // Something is wrong, remove weirdness 5899 url = tinyMCE.regexpReplace(url, '(http|https):///', '/'); 5900 5901 // Mailto link or anchor (Pass through) 5902 if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || /^[ \t\r\n\+]*[#\?]/.test(url)) 5903 return url; 5904 5905 // Fix relative/Mozilla 5906 if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/') 5907 return tinyMCE.settings.base_href + url; 5908 5909 // Handle relative URLs 5910 if (on_save && tinyMCE.getParam('relative_urls')) { 5911 curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url); 5912 if (curl.charAt(0) == '/') 5913 curl = tinyMCE.settings.document_base_prefix + curl; 5914 5915 urlParts = tinyMCE.parseURL(curl); 5916 tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings.document_base_url); 5917 5918 // Force relative 5919 if (urlParts.host == tmpUrlParts.host && (urlParts.port == tmpUrlParts.port)) 5920 return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings.document_base_url, curl); 5921 } 5922 5923 // Handle absolute URLs 5924 if (!tinyMCE.getParam('relative_urls')) { 5925 urlParts = tinyMCE.parseURL(url); 5926 baseUrlParts = tinyMCE.parseURL(tinyMCE.settings.base_href); 5927 5928 // Force absolute URLs from relative URLs 5929 url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url); 5930 5931 // If anchor and path is the same page 5932 if (urlParts.anchor && urlParts.path == baseUrlParts.path) 5933 return "#" + urlParts.anchor; 5934 } 5935 5936 // Remove current domain 5937 if (tinyMCE.getParam('remove_script_host')) { 5938 start = ""; 5939 portPart = ""; 5940 5941 if (port !== '') 5942 portPart = ":" + port; 5943 5944 start = prot + "//" + host + portPart + "/"; 5945 5946 if (url.indexOf(start) == 0) 5947 url = url.substring(start.length-1); 5948 } 5949 5950 return url; 5951 }, 5952 5953 convertAllRelativeURLs : function(body) { 5954 var i, elms, src, href, mhref, msrc; 5955 5956 // Convert all image URL:s to absolute URL 5957 elms = body.getElementsByTagName("img"); 5958 for (i=0; i<elms.length; i++) { 5959 src = tinyMCE.getAttrib(elms[i], 'src'); 5960 5961 msrc = tinyMCE.getAttrib(elms[i], 'mce_src'); 5962 if (msrc !== '') 5963 src = msrc; 5964 5965 if (src !== '') { 5966 src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, src); 5967 elms[i].setAttribute("src", src); 5968 } 5969 } 5970 5971 // Convert all link URL:s to absolute URL 5972 elms = body.getElementsByTagName("a"); 5973 for (i=0; i<elms.length; i++) { 5974 href = tinyMCE.getAttrib(elms[i], 'href'); 5975 5976 mhref = tinyMCE.getAttrib(elms[i], 'mce_href'); 5977 if (mhref !== '') 5978 href = mhref; 5979 5980 if (href && href !== '') { 5981 href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, href); 5982 elms[i].setAttribute("href", href); 5983 } 5984 } 5985 } 5986 5987 }); 5988 5989 /* file:jscripts/tiny_mce/classes/TinyMCE_Array.class.js */ 5990 5991 tinyMCE.add(TinyMCE_Engine, { 5992 clearArray : function(a) { 5993 var n; 5994 5995 for (n in a) 5996 a[n] = null; 5997 5998 return a; 5999 }, 6000 6001 explode : function(d, s) { 6002 var ar = s.split(d), oar = [], i; 6003 6004 for (i = 0; i<ar.length; i++) { 6005 if (ar[i] !== '') 6006 oar[oar.length] = ar[i]; 6007 } 6008 6009 return oar; 6010 } 6011 }); 6012 6013 /* file:jscripts/tiny_mce/classes/TinyMCE_Event.class.js */ 6014 6015 tinyMCE.add(TinyMCE_Engine, { 6016 _setEventsEnabled : function(node, state) { 6017 var evs, x, y, elms, i, event; 6018 var events = ['onfocus','onblur','onclick','ondblclick', 6019 'onmousedown','onmouseup','onmouseover','onmousemove', 6020 'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup']; 6021 6022 evs = tinyMCE.settings.event_elements.split(','); 6023 for (y=0; y<evs.length; y++){ 6024 elms = node.getElementsByTagName(evs[y]); 6025 for (i=0; i<elms.length; i++) { 6026 event = ""; 6027 6028 for (x=0; x<events.length; x++) { 6029 if ((event = tinyMCE.getAttrib(elms[i], events[x])) !== '') { 6030 event = tinyMCE.cleanupEventStr("" + event); 6031 6032 if (!state) 6033 event = "return true;" + event; 6034 else 6035 event = event.replace(/^return true;/gi, ''); 6036 6037 elms[i].removeAttribute(events[x]); 6038 elms[i].setAttribute(events[x], event); 6039 } 6040 } 6041 } 6042 } 6043 }, 6044 6045 _eventPatch : function(editor_id) { 6046 var n, inst, win, e; 6047 6048 // Remove odd, error 6049 if (typeof(tinyMCE) == "undefined") 6050 return true; 6051 6052 try { 6053 // Try selected instance first 6054 if (tinyMCE.selectedInstance) { 6055 win = tinyMCE.selectedInstance.getWin(); 6056 6057 if (win && win.event) { 6058 e = win.event; 6059 6060 if (!e.target) 6061 e.target = e.srcElement; 6062 6063 TinyMCE_Engine.prototype.handleEvent(e); 6064 return; 6065 } 6066 } 6067 6068 // Search for it 6069 for (n in tinyMCE.instances) { 6070 inst = tinyMCE.instances[n]; 6071 6072 if (!tinyMCE.isInstance(inst)) 6073 continue; 6074 6075 inst.select(); 6076 win = inst.getWin(); 6077 6078 if (win && win.event) { 6079 e = win.event; 6080 6081 if (!e.target) 6082 e.target = e.srcElement; 6083 6084 TinyMCE_Engine.prototype.handleEvent(e); 6085 return; 6086 } 6087 } 6088 } catch (ex) { 6089 // Ignore error if iframe is pointing to external URL 6090 } 6091 }, 6092 6093 findEvent : function(e) { 6094 var n, inst; 6095 6096 if (e) 1028 }, 1029 1030 get : function(e) { 1031 if (typeof(e) == 'string') 1032 return this.doc.getElementById(e); 1033 6097 1034 return e; 6098 6099 for (n in tinyMCE.instances) { 6100 inst = tinyMCE.instances[n]; 6101 6102 if (tinyMCE.isInstance(inst) && inst.getWin().event) 6103 return inst.getWin().event; 6104 } 6105 6106 return null; 6107 }, 6108 6109 unloadHandler : function() { 6110 tinyMCE.triggerSave(true, true); 6111 }, 6112 6113 addEventHandlers : function(inst) { 6114 this.setEventHandlers(inst, 1); 6115 }, 6116 6117 setEventHandlers : function(inst, s) { 6118 var doc = inst.getDoc(), ie, ot, i, f = s ? tinyMCE.addEvent : tinyMCE.removeEvent; 6119 6120 ie = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'controlselect', 'dblclick']; 6121 ot = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'focus', 'blur', 'dragdrop']; 6122 6123 inst.switchSettings(); 6124 6125 if (tinyMCE.isIE) { 6126 for (i=0; i<ie.length; i++) 6127 f(doc, ie[i], TinyMCE_Engine.prototype._eventPatch); 6128 } else { 6129 for (i=0; i<ot.length; i++) 6130 f(doc, ot[i], tinyMCE.handleEvent); 6131 6132 // Force designmode 6133 try { 6134 doc.designMode = "On"; 6135 } catch (e) { 6136 // Ignore 6137 } 6138 } 6139 }, 6140 6141 onMouseMove : function() { 6142 var inst, lh; 6143 6144 // Fix for IE7 bug where it's not restoring hover on anchors correctly 6145 if (tinyMCE.lastHover) { 6146 lh = tinyMCE.lastHover; 6147 6148 // Call out on menus and refresh class on normal buttons 6149 if (lh.className.indexOf('mceMenu') != -1) 6150 tinyMCE._menuButtonEvent('out', lh); 6151 else 6152 lh.className = lh.className; 6153 6154 tinyMCE.lastHover = null; 6155 } 6156 6157 if (!tinyMCE.hasMouseMoved) { 6158 inst = tinyMCE.selectedInstance; 6159 6160 // Workaround for bug #1437457 (Odd MSIE bug) 6161 if (inst.isFocused) { 6162 inst.undoBookmark = inst.selection.getBookmark(); 6163 tinyMCE.hasMouseMoved = true; 6164 } 6165 } 6166 6167 // tinyMCE.cancelEvent(inst.getWin().event); 6168 // return false; 6169 }, 6170 6171 cancelEvent : function(e) { 6172 if (!e) 6173 return false; 6174 6175 if (tinyMCE.isIE) { 6176 e.returnValue = false; 6177 e.cancelBubble = true; 6178 } else { 6179 e.preventDefault(); 6180 e.stopPropagation && e.stopPropagation(); 6181 } 6182 6183 return false; 6184 }, 6185 6186 addEvent : function(o, n, h) { 6187 // Add cleanup for all non unload events 6188 if (n != 'unload') { 6189 function clean() { 6190 var ex; 6191 6192 try { 6193 tinyMCE.removeEvent(o, n, h); 6194 tinyMCE.removeEvent(window, 'unload', clean); 6195 o = n = h = null; 6196 } catch (ex) { 6197 // IE may produce access denied exception on unload 6198 } 6199 } 6200 6201 // Add memory cleaner 6202 tinyMCE.addEvent(window, 'unload', clean); 6203 } 6204 6205 if (o.attachEvent) 6206 o.attachEvent("on" + n, h); 6207 else 6208 o.addEventListener(n, h, false); 6209 }, 6210 6211 removeEvent : function(o, n, h) { 6212 if (o.detachEvent) 6213 o.detachEvent("on" + n, h); 6214 else 6215 o.removeEventListener(n, h, false); 6216 }, 6217 6218 addSelectAccessibility : function(e, s, w) { 6219 // Add event handlers 6220 if (!s._isAccessible) { 6221 s.onkeydown = tinyMCE.accessibleEventHandler; 6222 s.onblur = tinyMCE.accessibleEventHandler; 6223 s._isAccessible = true; 6224 s._win = w; 6225 } 6226 6227 return false; 6228 }, 6229 6230 accessibleEventHandler : function(e) { 6231 var elm, win = this._win; 6232 6233 e = tinyMCE.isIE ? win.event : e; 6234 elm = tinyMCE.isIE ? e.srcElement : e.target; 6235 6236 // Unpiggyback onchange on blur 6237 if (e.type == "blur") { 6238 if (elm.oldonchange) { 6239 elm.onchange = elm.oldonchange; 6240 elm.oldonchange = null; 6241 } 6242 6243 return true; 6244 } 6245 6246 // Piggyback onchange 6247 if (elm.nodeName == "SELECT" && !elm.oldonchange) { 6248 elm.oldonchange = elm.onchange; 6249 elm.onchange = null; 6250 } 6251 6252 // Execute onchange and remove piggyback 6253 if (e.keyCode == 13 || e.keyCode == 32) { 6254 elm.onchange = elm.oldonchange; 6255 elm.onchange(); 6256 elm.oldonchange = null; 6257 6258 tinyMCE.cancelEvent(e); 6259 return false; 6260 } 6261 6262 return true; 6263 }, 6264 6265 _resetIframeHeight : function() { 6266 var ife; 6267 6268 if (tinyMCE.isRealIE) { 6269 ife = tinyMCE.selectedInstance.iframeElement; 6270 6271 /* if (ife._oldWidth) { 6272 ife.style.width = ife._oldWidth; 6273 ife.width = ife._oldWidth; 6274 }*/ 6275 6276 if (ife._oldHeight) { 6277 ife.style.height = ife._oldHeight; 6278 ife.height = ife._oldHeight; 6279 } 6280 } 6281 } 6282 6283 }); 6284 6285 /* file:jscripts/tiny_mce/classes/TinyMCE_Selection.class.js */ 6286 6287 function TinyMCE_Selection(inst) { 6288 this.instance = inst; 6289 }; 6290 6291 TinyMCE_Selection.prototype = { 6292 getSelectedHTML : function() { 6293 var inst = this.instance, e, r = this.getRng(), h; 6294 6295 if (!r) 6296 return null; 6297 6298 e = document.createElement("body"); 6299 6300 if (r.cloneContents) 6301 e.appendChild(r.cloneContents()); 6302 else if (typeof(r.item) != 'undefined' || typeof(r.htmlText) != 'undefined') 6303 e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText; 6304 else 6305 e.innerHTML = r.toString(); // Failed, use text for now 6306 6307 h = tinyMCE._cleanupHTML(inst, inst.contentDocument, inst.settings, e, e, false, true, false); 6308 6309 // When editing always use fonts internaly 6310 //if (tinyMCE.getParam("convert_fonts_to_spans")) 6311 // tinyMCE.convertSpansToFonts(inst.getDoc()); 6312 6313 return h; 6314 }, 6315 6316 getSelectedText : function() { 6317 var inst = this.instance, d, r, s, t; 6318 6319 if (tinyMCE.isIE) { 6320 d = inst.getDoc(); 6321 6322 if (d.selection.type == "Text") { 6323 r = d.selection.createRange(); 6324 t = r.text; 6325 } else 6326 t = ''; 6327 } else { 6328 s = this.getSel(); 6329 6330 if (s && s.toString) 6331 t = s.toString(); 6332 else 6333 t = ''; 6334 } 6335 6336 return t; 6337 }, 6338 6339 getBookmark : function(simple) { 6340 var inst = this.instance, rng = this.getRng(), doc = inst.getDoc(), b = inst.getBody(); 6341 var trng, sx, sy, xx = -999999999, vp = inst.getViewPort(); 6342 var sp, le, s, e, nl, i, si, ei, w; 6343 6344 sx = vp.left; 6345 sy = vp.top; 6346 6347 if (simple) 6348 return {rng : rng, scrollX : sx, scrollY : sy}; 6349 6350 if (tinyMCE.isRealIE) { 6351 if (rng.item) { 6352 e = rng.item(0); 6353 6354 nl = b.getElementsByTagName(e.nodeName); 6355 for (i=0; i<nl.length; i++) { 6356 if (e == nl[i]) { 6357 sp = i; 6358 break; 6359 } 6360 } 6361 6362 return { 6363 tag : e.nodeName, 6364 index : sp, 6365 scrollX : sx, 6366 scrollY : sy 1035 }, 1036 1037 // #if !jquery 1038 1039 select : function(pa, s) { 1040 var t = this, cs, c, pl, o = [], x, i, l, n; 1041 1042 s = t.get(s) || t.doc; 1043 1044 if (t.settings.strict) { 1045 function get(s, n) { 1046 return s.getElementsByTagName(n.toLowerCase()); 6367 1047 }; 6368 1048 } else { 6369 trng = doc.body.createTextRange(); 6370 trng.moveToElementText(inst.getBody()); 6371 trng.collapse(true); 6372 bp = Math.abs(trng.move('character', xx)); 6373 6374 trng = rng.duplicate(); 6375 trng.collapse(true); 6376 sp = Math.abs(trng.move('character', xx)); 6377 6378 trng = rng.duplicate(); 6379 trng.collapse(false); 6380 le = Math.abs(trng.move('character', xx)) - sp; 1049 function get(s, n) { 1050 return s.getElementsByTagName(n); 1051 }; 1052 } 1053 1054 // Simple element pattern. For example: "p" or "*" 1055 if (t.elmPattern.test(pa)) { 1056 x = get(s, pa); 1057 1058 for (i = 0, l = x.length; i<l; i++) 1059 o.push(x[i]); 1060 1061 return o; 1062 } 1063 1064 // Simple class pattern. For example: "p.class" or ".class" 1065 if (t.elmClassPattern.test(pa)) { 1066 pl = t.elmClassPattern.exec(pa); 1067 x = get(s, pl[1] || '*'); 1068 c = ' ' + pl[2] + ' '; 1069 1070 for (i = 0, l = x.length; i<l; i++) { 1071 n = x[i]; 1072 1073 if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1) 1074 o.push(n); 1075 } 1076 1077 return o; 1078 } 1079 1080 function collect(n) { 1081 if (!n.mce_save) { 1082 n.mce_save = 1; 1083 o.push(n); 1084 } 1085 }; 1086 1087 function collectIE(n) { 1088 if (!n.getAttribute('mce_save')) { 1089 n.setAttribute('mce_save', '1'); 1090 o.push(n); 1091 } 1092 }; 1093 1094 function find(n, f, r) { 1095 var i, l, nl = get(r, n); 1096 1097 for (i = 0, l = nl.length; i < l; i++) 1098 f(nl[i]); 1099 }; 1100 1101 each(pa.split(','), function(v, i) { 1102 v = tinymce.trim(v); 1103 1104 // Simple element pattern, most common in TinyMCE 1105 if (t.elmPattern.test(v)) { 1106 each(get(s, v), function(n) { 1107 collect(n); 1108 }); 1109 1110 return; 1111 } 1112 1113 // Simple element pattern with class, fairly common in TinyMCE 1114 if (t.elmClassPattern.test(v)) { 1115 x = t.elmClassPattern.exec(v); 1116 1117 each(get(s, x[1]), function(n) { 1118 if (t.hasClass(n, x[2])) 1119 collect(n); 1120 }); 1121 1122 return; 1123 } 1124 1125 if (!(cs = t.cache[pa])) { 1126 cs = 'x=(function(cf, s) {'; 1127 pl = v.split(' '); 1128 1129 each(pl, function(v) { 1130 var p = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v); 1131 1132 // Find elements 1133 p[1] = p[1] || '*'; 1134 cs += 'find("' + p[1] + '", function(n) {'; 1135 1136 // Check id 1137 if (p[2]) 1138 cs += 'if (n.id !== "' + p[2] + '") return;'; 1139 1140 // Check classes 1141 if (p[3]) { 1142 cs += 'var c = " " + n.className + " ";'; 1143 cs += 'if ('; 1144 c = ''; 1145 each(p[3].split('.'), function(v) { 1146 if (v) 1147 c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1'; 1148 }); 1149 cs += c + ') return;'; 1150 } 1151 }); 1152 1153 cs += 'cf(n);'; 1154 1155 for (i = pl.length - 1; i >= 0; i--) 1156 cs += '}, ' + (i ? 'n' : 's') + ');'; 1157 1158 cs += '})'; 1159 1160 // Compile CSS pattern function 1161 t.cache[pa] = cs = eval(cs); 1162 } 1163 1164 // Run selector function 1165 cs(isIE ? collectIE : collect, s); 1166 }); 1167 1168 // Cleanup 1169 each(o, function(n) { 1170 if (isIE) 1171 n.removeAttribute('mce_save'); 1172 else 1173 delete n.mce_save; 1174 }); 1175 1176 return o; 1177 }, 1178 1179 // #endif 1180 1181 add : function(p, n, a, h, c) { 1182 var t = this; 1183 1184 return this.run(p, function(p) { 1185 var e, k; 1186 1187 e = is(n, 'string') ? t.doc.createElement(n) : n; 1188 1189 if (a) { 1190 for (k in a) { 1191 if (a.hasOwnProperty(k) && !is(a[k], 'object')) 1192 t.setAttrib(e, k, '' + a[k]); 1193 } 1194 1195 if (a.style && !is(a.style, 'string')) { 1196 each(a.style, function(v, n) { 1197 t.setStyle(e, n, v); 1198 }); 1199 } 1200 } 1201 1202 if (h) { 1203 if (h.nodeType) 1204 e.appendChild(h); 1205 else 1206 e.innerHTML = h; 1207 } 1208 1209 return !c ? p.appendChild(e) : e; 1210 }); 1211 }, 1212 1213 create : function(n, a, h) { 1214 return this.add(this.doc.createElement(n), n, a, h, 1); 1215 }, 1216 1217 createHTML : function(n, a, h) { 1218 var o = '', t = this, k; 1219 1220 o += '<' + n; 1221 1222 for (k in a) { 1223 if (a.hasOwnProperty(k)) 1224 o += ' ' + k + '="' + t.encode(a[k]) + '"'; 1225 } 1226 1227 if (tinymce.is(h)) 1228 return o + '>' + h + '</' + n + '>'; 1229 1230 return o + ' />'; 1231 }, 1232 1233 remove : function(n, k) { 1234 return this.run(n, function(n) { 1235 var p; 1236 1237 p = n.parentNode; 1238 1239 if (!p) 1240 return null; 1241 1242 if (k) { 1243 each (n.childNodes, function(c) { 1244 p.insertBefore(c.cloneNode(true), n); 1245 }); 1246 } 1247 1248 return p.removeChild(n); 1249 }); 1250 }, 1251 1252 // #if !jquery 1253 1254 setStyle : function(n, na, v) { 1255 var t = this; 1256 1257 return t.run(n, function(e) { 1258 var s, i; 1259 1260 s = e.style; 1261 1262 // Camelcase it, if needed 1263 na = na.replace(/-(\D)/g, function(a, b){ 1264 return b.toUpperCase(); 1265 }); 1266 1267 // Default px suffix on these 1268 if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v))) 1269 v += 'px'; 1270 1271 switch (na) { 1272 case 'opacity': 1273 // IE specific opacity 1274 if (isIE) { 1275 s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")"; 1276 1277 if (!n.currentStyle || !n.currentStyle.hasLayout) 1278 s.display = 'inline-block'; 1279 } 1280 1281 // Fix for older browsers 1282 s['-moz-opacity'] = s['-khtml-opacity'] = v; 1283 break; 1284 1285 case 'float': 1286 isIE ? s.styleFloat = v : s.cssFloat = v; 1287 break; 1288 } 1289 1290 s[na] = v || ''; 1291 1292 // Force update of the style data 1293 if (t.settings.update_styles) 1294 t.setAttrib(e, 'mce_style'); 1295 }); 1296 }, 1297 1298 getStyle : function(n, na, c) { 1299 n = this.get(n); 1300 1301 if (!n) 1302 return false; 1303 1304 // Gecko 1305 if (this.doc.defaultView && c) { 1306 // Remove camelcase 1307 na = na.replace(/[A-Z]/g, function(a){ 1308 return '-' + a; 1309 }); 1310 1311 try { 1312 return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na); 1313 } catch (ex) { 1314 // Old safari might fail 1315 return null; 1316 } 1317 } 1318 1319 // Camelcase it, if needed 1320 na = na.replace(/-(\D)/g, function(a, b){ 1321 return b.toUpperCase(); 1322 }); 1323 1324 if (na == 'float') 1325 na = isIE ? 'styleFloat' : 'cssFloat'; 1326 1327 // IE & Opera 1328 if (n.currentStyle && c) 1329 return n.currentStyle[na]; 1330 1331 return n.style[na]; 1332 }, 1333 1334 setStyles : function(e, o) { 1335 var t = this, s = t.settings, ol; 1336 1337 ol = s.update_styles; 1338 s.update_styles = 0; 1339 1340 each(o, function(v, n) { 1341 t.setStyle(e, n, v); 1342 }); 1343 1344 // Update style info 1345 s.update_styles = ol; 1346 if (s.update_styles) 1347 t.setAttrib(e, s.cssText); 1348 }, 1349 1350 setAttrib : function(e, n, v) { 1351 var t = this; 1352 1353 // Strict XML mode 1354 if (t.settings.strict) 1355 n = n.toLowerCase(); 1356 1357 return this.run(e, function(e) { 1358 var s = t.settings; 1359 1360 switch (n) { 1361 case "style": 1362 if (s.keep_values) { 1363 if (v) 1364 e.setAttribute('mce_style', v, 2); 1365 else 1366 e.removeAttribute('mce_style', 2); 1367 } 1368 1369 e.style.cssText = v; 1370 break; 1371 1372 case "class": 1373 e.className = v; 1374 break; 1375 1376 case "src": 1377 case "href": 1378 if (s.keep_values) { 1379 if (s.url_converter) 1380 v = s.url_converter.call(s.url_converter_scope || t, v, n, e); 1381 1382 t.setAttrib(e, 'mce_' + n, v, 2); 1383 } 1384 1385 break; 1386 } 1387 1388 if (is(v) && v !== null && v.length !== 0) 1389 e.setAttribute(n, '' + v, 2); 1390 else 1391 e.removeAttribute(n, 2); 1392 }); 1393 }, 1394 1395 setAttribs : function(e, o) { 1396 var t = this; 1397 1398 return this.run(e, function(e) { 1399 each(o, function(v, n) { 1400 t.setAttrib(e, n, v); 1401 }); 1402 }); 1403 }, 1404 1405 // #endif 1406 1407 getAttrib : function(e, n, dv) { 1408 var v, t = this; 1409 1410 e = t.get(e); 1411 1412 if (!e) 1413 return false; 1414 1415 if (!is(dv)) 1416 dv = ""; 1417 1418 // Try the mce variant for these 1419 if (/^(src|href|style)$/.test(n)) { 1420 v = e.getAttribute("mce_" + n); 1421 1422 if (v) 1423 return v; 1424 } 1425 1426 v = e.getAttribute(n, 2); 1427 1428 if (!v) { 1429 switch (n) { 1430 case 'class': 1431 v = e.className; 1432 break; 1433 1434 default: 1435 v = e.attributes[n]; 1436 v = v && is(v.nodeValue) ? v.nodeValue : v; 1437 } 1438 } 1439 1440 switch (n) { 1441 case 'style': 1442 v = v || e.style.cssText; 1443 1444 if (v) { 1445 v = t.serializeStyle(t.parseStyle(v)); 1446 1447 if (t.settings.keep_values) 1448 e.setAttribute('mce_style', v); 1449 } 1450 1451 break; 1452 } 1453 1454 // Remove Apple and WebKit stuff 1455 if (isWebKit && n === "class" && v) 1456 v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, ''); 1457 1458 // Handle IE issues 1459 if (isIE) { 1460 switch (n) { 1461 case 'rowspan': 1462 case 'colspan': 1463 // IE returns 1 as default value 1464 if (v === 1) 1465 v = ''; 1466 1467 break; 1468 1469 case 'size': 1470 // IE returns +0 as default value for size 1471 if (v === '+0') 1472 v = ''; 1473 1474 break; 1475 1476 case 'hspace': 1477 // IE returns -1 as default value 1478 if (v === -1) 1479 v = ''; 1480 1481 break; 1482 1483 case 'tabindex': 1484 // IE returns 32768 as default value 1485 if (v === 32768) 1486 v = ''; 1487 1488 break; 1489 1490 default: 1491 // IE has odd anonymous function for event attributes 1492 if (n.indexOf('on') === 0 && v) 1493 v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1'); 1494 } 1495 } 1496 1497 return (v && v != '') ? '' + v : dv; 1498 }, 1499 1500 getPos : function(n) { 1501 var t = this, x = 0, y = 0, e, d = t.doc; 1502 1503 n = t.get(n); 1504 1505 // Use getBoundingClientRect on IE, Opera has it but it's not perfect 1506 if (n && isIE) { 1507 n = n.getBoundingClientRect(); 1508 e = t.boxModel ? d.documentElement : d.body; 1509 x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border 1510 x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x; 1511 n.top += window.self != window.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset 1512 1513 return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x}; 1514 } 1515 1516 while (n) { 1517 x += n.offsetLeft || 0; 1518 y += n.offsetTop || 0; 1519 x -= n.scrollLeft || 0; 1520 y -= n.scrollTop || 0; 1521 n = n.offsetParent; 1522 } 1523 1524 return {x : x, y : y}; 1525 }, 1526 1527 parseStyle : function(st) { 1528 var t = this, s = t.settings, o = {}; 1529 1530 if (!st) 1531 return o; 1532 1533 function compress(p, s, ot) { 1534 var t, r, b, l; 1535 1536 // Get values and check it it needs compressing 1537 t = o[p + '-top' + s]; 1538 if (!t) 1539 return; 1540 1541 r = o[p + '-right' + s]; 1542 if (t != r) 1543 return; 1544 1545 b = o[p + '-bottom' + s]; 1546 if (r != b) 1547 return; 1548 1549 l = o[p + '-left' + s]; 1550 if (b != l) 1551 return; 1552 1553 // Compress 1554 o[ot] = l; 1555 delete o[p + '-top' + s]; 1556 delete o[p + '-right' + s]; 1557 delete o[p + '-bottom' + s]; 1558 delete o[p + '-left' + s]; 1559 }; 1560 1561 function compress2(ta, a, b, c) { 1562 var t; 1563 1564 t = o[a]; 1565 if (!t) 1566 return; 1567 1568 t = o[b]; 1569 if (!t) 1570 return; 1571 1572 t = o[c]; 1573 if (!t) 1574 return; 1575 1576 // Compress 1577 o[ta] = o[a] + ' ' + o[b] + ' ' + o[c]; 1578 delete o[a]; 1579 delete o[b]; 1580 delete o[c]; 1581 }; 1582 1583 each(st.split(';'), function(v) { 1584 var sv, ur = []; 1585 1586 if (v) { 1587 v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';}); 1588 v = v.split(':'); 1589 sv = tinymce.trim(v[1]); 1590 sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];}); 1591 1592 sv = sv.replace(/rgb\([^\)]+\)/g, function(v) { 1593 return t.toHex(v); 1594 }); 1595 1596 if (s.url_converter) { 1597 sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) { 1598 return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null)) + ')'; 1599 }); 1600 } 1601 1602 o[tinymce.trim(v[0]).toLowerCase()] = sv; 1603 } 1604 }); 1605 1606 compress("border", "", "border"); 1607 compress("border", "-width", "border-width"); 1608 compress("border", "-color", "border-color"); 1609 compress("border", "-style", "border-style"); 1610 compress("padding", "", "padding"); 1611 compress("margin", "", "margin"); 1612 compress2('border', 'border-width', 'border-style', 'border-color'); 1613 1614 return o; 1615 }, 1616 1617 serializeStyle : function(o) { 1618 var s = ''; 1619 1620 each(o, function(v, k) { 1621 if (k && v) { 1622 switch (k) { 1623 case 'color': 1624 case 'background-color': 1625 v = v.toLowerCase(); 1626 break; 1627 } 1628 1629 s += (s ? ' ' : '') + k + ': ' + v + ';'; 1630 } 1631 }); 1632 1633 return s; 1634 }, 1635 1636 loadCSS : function(u) { 1637 var t = this, d = this.doc; 1638 1639 if (!u) 1640 u = ''; 1641 1642 each(u.split(','), function(u) { 1643 if (t.files[u]) 1644 return; 1645 1646 t.files[u] = true; 1647 1648 if (!d.createStyleSheet) 1649 t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : u}); 1650 else 1651 d.createStyleSheet(u); 1652 }); 1653 }, 1654 1655 // #if !jquery 1656 1657 addClass : function(e, c) { 1658 return this.run(e, function(e) { 1659 var o; 1660 1661 if (!c) 1662 return 0; 1663 1664 if (this.hasClass(e, c)) 1665 return e.className; 1666 1667 o = this.removeClass(e, c); 1668 1669 return e.className = (o != '' ? (o + ' ') : '') + c; 1670 }); 1671 }, 1672 1673 removeClass : function(e, c) { 1674 var t = this, re; 1675 1676 return t.run(e, function(e) { 1677 var v; 1678 1679 if (t.hasClass(e, c)) { 1680 if (!re) 1681 re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g"); 1682 1683 v = e.className.replace(re, ' '); 1684 1685 return e.className = tinymce.trim(v != ' ' ? v : ''); 1686 } 1687 1688 return e.className; 1689 }); 1690 }, 1691 1692 hasClass : function(n, c) { 1693 n = this.get(n); 1694 1695 if (!n || !c) 1696 return false; 1697 1698 return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1; 1699 }, 1700 1701 show : function(e) { 1702 return this.setStyle(e, 'display', 'block'); 1703 }, 1704 1705 hide : function(e) { 1706 return this.setStyle(e, 'display', 'none'); 1707 }, 1708 1709 isHidden : function(e) { 1710 e = this.get(e); 1711 1712 return e.style.display == 'none' || this.getStyle(e, 'display') == 'none'; 1713 }, 1714 1715 // #endif 1716 1717 uniqueId : function(p) { 1718 return (!p ? 'mce_' : p) + (this.counter++); 1719 }, 1720 1721 setHTML : function(e, h) { 1722 var t = this; 1723 1724 return this.run(e, function(e) { 1725 var r; 1726 1727 h = t.processHTML(h); 1728 1729 if (isIE) { 1730 e.innerHTML = '<br />' + h; 1731 e.removeChild(e.firstChild); 1732 } else 1733 e.innerHTML = h; 1734 1735 return h; 1736 }); 1737 }, 1738 1739 processHTML : function(h) { 1740 var t = this, s = t.settings; 1741 1742 // Convert strong and em to b and i in FF since it can't handle them 1743 if (tinymce.isGecko) { 1744 h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>'); 1745 h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>'); 1746 } 1747 1748 // Fix some issues 1749 h = h.replace(/<(a)([^>]*)\/>/gi, '<$1$2></$1>'); // Force open 1750 1751 // Store away src and href in mce_src and mce_href since browsers mess them up 1752 if (s.keep_values) { 1753 // Wrap scripts in comments for serialization purposes 1754 if (h.indexOf('<script') !== -1) { 1755 h = h.replace(/<script>/g, '<script type="text/javascript">'); 1756 h = h.replace(/<script(|[^>]+)>(\s*<!--|\/\/\s*<\[CDATA\[)?[\r\n]*/g, '<mce:script$1><!--\n'); 1757 h = h.replace(/\s*(\/\/\s*-->|\/\/\s*]]>)?<\/script>/g, '\n// --></mce:script>'); 1758 h = h.replace(/<mce:script(|[^>]+)><!--\n\/\/ --><\/mce:script>/g, '<mce:script$1></mce:script>'); 1759 } 1760 1761 // Process all tags with src, href or style 1762 h = h.replace(/<([\w:]+) [^>]*(src|href|style)[^>]*>/gi, function(a, n) { 1763 function handle(m, b, c) { 1764 var u = c; 1765 1766 // Tag already got a mce_ version 1767 if (a.indexOf('mce_' + b) != -1) 1768 return m; 1769 1770 if (b == 'style') { 1771 // Why did I need this one? 1772 //if (isIE) 1773 // u = t.serializeStyle(t.parseStyle(u)); 1774 1775 if (s.hex_colors) { 1776 u = u.replace(/rgb\([^\)]+\)/g, function(v) { 1777 return t.toHex(v); 1778 }); 1779 } 1780 1781 if (s.url_converter) { 1782 u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) { 1783 return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')'; 1784 }); 1785 } 1786 } else { 1787 if (s.url_converter) 1788 u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)); 1789 } 1790 1791 return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"'; 1792 }; 1793 1794 a = a.replace(/ (src|href|style)=[\"]([^\"]+)[\"]/gi, handle); // W3C 1795 a = a.replace(/ (src|href|style)=[\']([^\']+)[\']/gi, handle); // W3C 1796 1797 return a.replace(/ (src|href|style)=([^\s\"\'>]+)/gi, handle); // IE 1798 }); 1799 } 1800 1801 return h; 1802 }, 1803 1804 getOuterHTML : function(e) { 1805 var d; 1806 1807 e = this.get(e); 1808 1809 if (!e) 1810 return null; 1811 1812 if (isIE) 1813 return e.outerHTML; 1814 1815 d = (e.ownerDocument || this.doc).createElement("body"); 1816 d.appendChild(e.cloneNode(true)); 1817 1818 return d.innerHTML; 1819 }, 1820 1821 setOuterHTML : function(e, h, d) { 1822 var t = this; 1823 1824 return this.run(e, function(e) { 1825 var n, tp; 1826 1827 e = t.get(e); 1828 d = d || e.ownerDocument || t.doc; 1829 1830 if (isIE && e.nodeType == 1) 1831 e.outerHTML = h; 1832 else { 1833 tp = d.createElement("body"); 1834 tp.innerHTML = h; 1835 1836 n = tp.lastChild; 1837 while (n) { 1838 t.insertAfter(n.cloneNode(true), e); 1839 n = n.previousSibling; 1840 } 1841 1842 t.remove(e); 1843 } 1844 }); 1845 }, 1846 1847 decode : function(s) { 1848 var e = document.createElement("div"); 1849 1850 e.innerHTML = s; 1851 1852 return !e.firstChild ? s : e.firstChild.nodeValue; 1853 }, 1854 1855 encode : function(s) { 1856 return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) { 1857 switch (c) { 1858 case '&': 1859 return '&'; 1860 1861 case '"': 1862 return '"'; 1863 1864 case '<': 1865 return '<'; 1866 1867 case '>': 1868 return '>'; 1869 } 1870 1871 return c; 1872 }) : s; 1873 }, 1874 1875 // #if !jquery 1876 1877 insertAfter : function(n, r) { 1878 var t = this; 1879 1880 r = t.get(r); 1881 1882 return this.run(n, function(n) { 1883 var p, ns; 1884 1885 p = r.parentNode; 1886 ns = r.nextSibling; 1887 1888 if (ns) 1889 p.insertBefore(n, ns); 1890 else 1891 p.appendChild(n); 1892 1893 return n; 1894 }); 1895 }, 1896 1897 // #endif 1898 1899 isBlock : function(n) { 1900 if (n.nodeType && n.nodeType !== 1) 1901 return false; 1902 1903 n = n.nodeName || n; 1904 1905 return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n); 1906 }, 1907 1908 // #if !jquery 1909 1910 replace : function(n, o, k) { 1911 if (is(o, 'array')) 1912 n = n.cloneNode(true); 1913 1914 return this.run(o, function(o) { 1915 if (k) { 1916 each(o.childNodes, function(c) { 1917 n.appendChild(c.cloneNode(true)); 1918 }); 1919 } 1920 1921 return o.parentNode.replaceChild(n, o); 1922 }); 1923 }, 1924 1925 // #endif 1926 1927 toHex : function(s) { 1928 var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s); 1929 1930 function hex(s) { 1931 s = parseInt(s).toString(16); 1932 1933 return s.length > 1 ? s : '0' + s; // 0 -> 00 1934 }; 1935 1936 if (c) { 1937 s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]); 1938 1939 return s; 1940 } 1941 1942 return s; 1943 }, 1944 1945 getClasses : function() { 1946 var t = this, cl = [], i, lo = {}, f = t.settings.class_filter; 1947 1948 if (t.classes) 1949 return t.classes; 1950 1951 function addClasses(s) { 1952 // IE style imports 1953 each(s.imports, function(r) { 1954 addClasses(r); 1955 }); 1956 1957 each(s.cssRules || s.rules, function(r) { 1958 // Real type or fake it on IE 1959 switch (r.type || 1) { 1960 // Rule 1961 case 1: 1962 if (r.selectorText) { 1963 each(r.selectorText.split(','), function(v) { 1964 v = v.replace(/^\s*|\s*$|^\s\./g, ""); 1965 1966 if (f && !(v = f(v))) 1967 return; 1968 1969 if (/^\.mce/.test(v) || !/^\.[\w\-]+$/.test(v)) 1970 return; 1971 1972 v = v.substring(1); 1973 if (!lo[v]) { 1974 cl.push({'class' : v}); 1975 lo[v] = 1; 1976 } 1977 }); 1978 } 1979 break; 1980 1981 // Import 1982 case 3: 1983 addClasses(r.styleSheet); 1984 break; 1985 } 1986 }); 1987 }; 1988 1989 try { 1990 each(t.doc.styleSheets, addClasses); 1991 } catch (ex) { 1992 // Ignore 1993 } 1994 1995 if (cl.length > 0) 1996 t.classes = cl; 1997 1998 return cl; 1999 }, 2000 2001 run : function(e, f, s) { 2002 var t = this, o; 2003 2004 if (typeof(e) === 'string') 2005 e = t.doc.getElementById(e); 2006 2007 if (!e) 2008 return false; 2009 2010 s = s || this; 2011 if (!e.nodeType && (e.length || e.length === 0)) { 2012 o = []; 2013 2014 each(e, function(e, i) { 2015 if (e) { 2016 if (typeof(e) == 'string') 2017 e = t.doc.getElementById(e); 2018 2019 o.push(f.call(s, e, i)); 2020 } 2021 }); 2022 2023 return o; 2024 } 2025 2026 return f.call(s, e); 2027 } 2028 2029 /* 2030 walk : function(n, f, s) { 2031 var d = this.doc, w; 2032 2033 if (d.createTreeWalker) { 2034 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); 2035 2036 while ((n = w.nextNode()) != null) 2037 f.call(s || this, n); 2038 } else 2039 tinymce.walk(n, f, 'childNodes', s); 2040 } 2041 */ 2042 2043 /* 2044 toRGB : function(s) { 2045 var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s); 2046 2047 if (c) { 2048 // #FFF -> #FFFFFF 2049 if (!is(c[3])) 2050 c[3] = c[2] = c[1]; 2051 2052 return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")"; 2053 } 2054 2055 return s; 2056 } 2057 */ 2058 2059 }); 2060 2061 // Setup page DOM 2062 tinymce.DOM = new tinymce.dom.DOMUtils(document); 2063 })(); 2064 2065 /* file:jscripts/tiny_mce/classes/dom/Event.js */ 2066 2067 (function() { 2068 // Shorten names 2069 var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event; 2070 2071 tinymce.create('static tinymce.dom.Event', { 2072 inits : [], 2073 events : [], 2074 2075 // #if !jquery 2076 2077 add : function(o, n, f, s) { 2078 var cb, t = this, el = t.events, r; 2079 2080 // Handle array 2081 if (o && o instanceof Array) { 2082 r = []; 2083 2084 each(o, function(o) { 2085 o = DOM.get(o); 2086 r.push(t.add(o, n, f, s)); 2087 }); 2088 2089 return r; 2090 } 2091 2092 o = DOM.get(o); 2093 2094 if (!o) 2095 return; 2096 2097 // Setup event callback 2098 cb = function(e) { 2099 e = e || window.event; 2100 2101 // Patch in target in IE it's W3C valid 2102 if (e && !e.target && isIE) 2103 e.target = e.srcElement; 2104 2105 if (!s) 2106 return f(e); 2107 2108 return f.call(s, e); 2109 }; 2110 2111 if (n == 'unload') { 2112 tinymce.unloads.unshift({func : cb}); 2113 return cb; 2114 } 2115 2116 if (n == 'init') { 2117 if (t.domLoaded) 2118 cb(); 2119 else 2120 t.inits.push(cb); 2121 2122 return cb; 2123 } 2124 2125 // Store away listener reference 2126 el.push({ 2127 obj : o, 2128 name : n, 2129 func : f, 2130 cfunc : cb, 2131 scope : s 2132 }); 2133 2134 t._add(o, n, cb); 2135 2136 return f; 2137 }, 2138 2139 remove : function(o, n, f) { 2140 var t = this, a = t.events, s = false, r; 2141 2142 // Handle array 2143 if (o && o instanceof Array) { 2144 r = []; 2145 2146 each(o, function(o) { 2147 o = DOM.get(o); 2148 r.push(t.remove(o, n, f)); 2149 }); 2150 2151 return r; 2152 } 2153 2154 o = DOM.get(o); 2155 2156 each(a, function(e, i) { 2157 if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) { 2158 a.splice(i, 1); 2159 t._remove(o, n, e.cfunc); 2160 s = true; 2161 return false; 2162 } 2163 }); 2164 2165 return s; 2166 }, 2167 2168 // #endif 2169 2170 cancel : function(e) { 2171 if (!e) 2172 return false; 2173 2174 this.stop(e); 2175 return this.prevent(e); 2176 }, 2177 2178 stop : function(e) { 2179 if (e.stopPropagation) 2180 e.stopPropagation(); 2181 else 2182 e.cancelBubble = true; 2183 2184 return false; 2185 }, 2186 2187 prevent : function(e) { 2188 if (e.preventDefault) 2189 e.preventDefault(); 2190 else 2191 e.returnValue = false; 2192 2193 return false; 2194 }, 2195 2196 _unload : function() { 2197 var t = Event; 2198 2199 each(t.events, function(e, i) { 2200 t._remove(e.obj, e.name, e.cfunc); 2201 e.obj = e.cfunc = null; 2202 }); 2203 2204 t.events = []; 2205 t = null; 2206 }, 2207 2208 _add : function(o, n, f) { 2209 if (o.attachEvent) 2210 o.attachEvent('on' + n, f); 2211 else if (o.addEventListener) 2212 o.addEventListener(n, f, false); 2213 else 2214 o['on' + n] = f; 2215 }, 2216 2217 _remove : function(o, n, f) { 2218 if (o.detachEvent) 2219 o.detachEvent('on' + n, f); 2220 else if (o.removeEventListener) 2221 o.removeEventListener(n, f, false); 2222 else 2223 o['on' + n] = null; 2224 }, 2225 2226 _pageInit : function() { 2227 var e = Event; 2228 2229 e._remove(window, 'DOMContentLoaded', e._pageInit); 2230 e.domLoaded = true; 2231 2232 each(e.inits, function(c) { 2233 c(); 2234 }); 2235 2236 e.inits = []; 2237 }, 2238 2239 _wait : function() { 2240 var t; 2241 2242 // No need since the document is already loaded 2243 if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) 2244 return; 2245 2246 if (isIE && document.location.protocol != 'https:') { 2247 // Fake DOMContentLoaded on IE 2248 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>'); 2249 DOM.get("__ie_onload").onreadystatechange = function() { 2250 if (this.readyState == "complete") { 2251 Event._pageInit(); 2252 DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak 2253 } 2254 }; 2255 } else { 2256 Event._add(window, 'DOMContentLoaded', Event._pageInit, Event); 2257 2258 if (isIE || isWebKit) { 2259 t = setInterval(function() { 2260 if (/loaded|complete/.test(document.readyState)) { 2261 clearInterval(t); 2262 Event._pageInit(); 2263 } 2264 }, 10); 2265 } 2266 } 2267 } 2268 2269 }); 2270 2271 // Shorten name 2272 Event = tinymce.dom.Event; 2273 2274 // Dispatch DOM content loaded event for IE and Safari 2275 Event._wait(); 2276 tinymce.addUnload(Event._unload); 2277 })(); 2278 2279 /* file:jscripts/tiny_mce/classes/dom/Element.js */ 2280 2281 (function() { 2282 var each = tinymce.each; 2283 2284 tinymce.create('tinymce.dom.Element', { 2285 Element : function(id, s) { 2286 var t = this, dom, el; 2287 2288 s = s || {}; 2289 t.id = id; 2290 t.dom = dom = s.dom || tinymce.DOM; 2291 t.settings = s; 2292 2293 // Only IE leaks DOM references, this is a lot faster 2294 if (!tinymce.isIE) 2295 el = t.dom.get(t.id); 2296 2297 each([ 2298 'getPos', 2299 'getRect', 2300 'getParent', 2301 'add', 2302 'setStyle', 2303 'getStyle', 2304 'setStyles', 2305 'setAttrib', 2306 'setAttribs', 2307 'getAttrib', 2308 'addClass', 2309 'removeClass', 2310 'hasClass', 2311 'getOuterHTML', 2312 'setOuterHTML', 2313 'remove', 2314 'show', 2315 'hide', 2316 'isHidden', 2317 'setHTML', 2318 'get' 2319 ], function(k) { 2320 t[k] = function() { 2321 var a = arguments, o; 2322 2323 // Opera fails 2324 if (tinymce.isOpera) { 2325 a = [id]; 2326 2327 each(arguments, function(v) { 2328 a.push(v); 2329 }); 2330 } else 2331 Array.prototype.unshift.call(a, el || id); 2332 2333 o = dom[k].apply(dom, a); 2334 t.update(k); 2335 2336 return o; 2337 }; 2338 }); 2339 }, 2340 2341 on : function(n, f, s) { 2342 return tinymce.dom.Event.add(this.id, n, f, s); 2343 }, 2344 2345 getXY : function() { 2346 return { 2347 x : parseInt(this.getStyle('left')), 2348 y : parseInt(this.getStyle('top')) 2349 }; 2350 }, 2351 2352 getSize : function() { 2353 var n = this.dom.get(this.id); 2354 2355 return { 2356 w : parseInt(this.getStyle('width') || n.clientWidth), 2357 h : parseInt(this.getStyle('height') || n.clientHeight) 2358 }; 2359 }, 2360 2361 moveTo : function(x, y) { 2362 this.setStyles({left : x, top : y}); 2363 }, 2364 2365 moveBy : function(x, y) { 2366 var p = this.getXY(); 2367 2368 this.moveTo(p.x + x, p.y + y); 2369 }, 2370 2371 resizeTo : function(w, h) { 2372 this.setStyles({width : w, height : h}); 2373 }, 2374 2375 resizeBy : function(w, h) { 2376 var s = this.getSize(); 2377 2378 this.resizeTo(s.w + w, s.h + h); 2379 }, 2380 2381 update : function(k) { 2382 var t = this, b, dom = t.dom; 2383 2384 if (tinymce.isIE6 && t.settings.blocker) { 2385 k = k || ''; 2386 2387 // Ignore getters 2388 if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0) 2389 return; 2390 2391 // Remove blocker on remove 2392 if (k == 'remove') { 2393 dom.remove(t.blocker); 2394 return; 2395 } 2396 2397 if (!t.blocker) { 2398 t.blocker = dom.uniqueId(); 2399 b = dom.add(t.settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'}); 2400 dom.setStyle(b, 'opacity', 0); 2401 } else 2402 b = dom.get(t.blocker); 2403 2404 dom.setStyle(b, 'left', t.getStyle('left', 1)); 2405 dom.setStyle(b, 'top', t.getStyle('top', 1)); 2406 dom.setStyle(b, 'width', t.getStyle('width', 1)); 2407 dom.setStyle(b, 'height', t.getStyle('height', 1)); 2408 dom.setStyle(b, 'display', t.getStyle('display', 1)); 2409 dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1); 2410 } 2411 } 2412 2413 }); 2414 })(); 2415 2416 /* file:jscripts/tiny_mce/classes/dom/Selection.js */ 2417 2418 (function() { 2419 // Shorten names 2420 var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each; 2421 2422 tinymce.create('tinymce.dom.Selection', { 2423 Selection : function(dom, win, serializer) { 2424 var t = this; 2425 2426 t.dom = dom; 2427 t.win = win; 2428 t.serializer = serializer; 2429 2430 // Prevent leaks 2431 tinymce.addUnload(function() { 2432 t.win = null; 2433 }); 2434 }, 2435 2436 getContent : function(s) { 2437 var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n; 2438 2439 s = s || {}; 2440 wb = wa = ''; 2441 s.get = true; 2442 s.format = s.format || 'html'; 2443 2444 if (s.format == 'text') 2445 return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : '')); 2446 2447 if (r.cloneContents) { 2448 n = r.cloneContents(); 2449 2450 if (n) 2451 e.appendChild(n); 2452 } else if (is(r.item) || is(r.htmlText)) 2453 e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText; 2454 else 2455 e.innerHTML = r.toString(); 2456 2457 // Keep whitespace before and after 2458 if (/^\s/.test(e.innerHTML)) 2459 wb = ' '; 2460 2461 if (/\s+$/.test(e.innerHTML)) 2462 wa = ' '; 2463 2464 return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa; 2465 }, 2466 2467 setContent : function(h, s) { 2468 var t = this, r = t.getRng(), d; 2469 2470 s = s || {format : 'html'}; 2471 s.set = true; 2472 h = t.dom.processHTML(h); 2473 2474 if (r.insertNode) { 2475 d = t.win.document; 2476 2477 // Use insert HTML if it exists (places cursor after content) 2478 if (d.queryCommandEnabled('InsertHTML')) 2479 return d.execCommand('InsertHTML', false, h); 2480 2481 r.deleteContents(); 2482 r.insertNode(t.getRng().createContextualFragment(h)); 2483 } else { 2484 if (r.item) 2485 r.item(0).outerHTML = h; 2486 else 2487 r.pasteHTML(h); 2488 } 2489 }, 2490 2491 getStart : function() { 2492 var t = this, r = t.getRng(), e; 2493 2494 if (isIE) { 2495 if (r.item) 2496 return r.item(0); 2497 2498 r = r.duplicate(); 2499 r.collapse(1); 2500 e = r.parentElement(); 2501 2502 if (e.nodeName == 'BODY') 2503 return e.firstChild; 2504 2505 return e; 2506 } else { 2507 e = r.startContainer; 2508 2509 if (e.nodeName == 'BODY') 2510 return e.firstChild; 2511 2512 return t.dom.getParent(e, function(n) {return n.nodeType == 1;}); 2513 } 2514 }, 2515 2516 getEnd : function() { 2517 var t = this, r = t.getRng(), e; 2518 2519 if (isIE) { 2520 if (r.item) 2521 return r.item(0); 2522 2523 r = r.duplicate(); 2524 r.collapse(0); 2525 e = r.parentElement(); 2526 2527 if (e.nodeName == 'BODY') 2528 return e.lastChild; 2529 2530 return e; 2531 } else { 2532 e = r.endContainer; 2533 2534 if (e.nodeName == 'BODY') 2535 return e.lastChild; 2536 2537 return t.dom.getParent(e, function(n) {return n.nodeType == 1;}); 2538 } 2539 }, 2540 2541 getBookmark : function(si) { 2542 var t = this, r = t.getRng(), tr, sx, sy, vp = t.dom.getViewPort(t.win), e, sp, bp, le, c = -0xFFFFFF, s, ro = t.dom.getRoot(); 2543 2544 sx = vp.x; 2545 sy = vp.y; 2546 2547 // Simple bookmark fast but not as persistent 2548 if (si == 'simple') 2549 return {rng : r, scrollX : sx, scrollY : sy}; 2550 2551 // Handle IE 2552 if (isIE) { 2553 // Control selection 2554 if (r.item) { 2555 e = r.item(0); 2556 2557 each(t.dom.select(e.nodeName), function(n, i) { 2558 if (e == n) { 2559 sp = i; 2560 return false; 2561 } 2562 }); 2563 2564 return { 2565 tag : e.nodeName, 2566 index : sp, 2567 scrollX : sx, 2568 scrollY : sy 2569 }; 2570 } 2571 2572 // Text selection 2573 tr = t.dom.doc.body.createTextRange(); 2574 tr.moveToElementText(ro); 2575 tr.collapse(true); 2576 bp = Math.abs(tr.move('character', c)); 2577 2578 tr = r.duplicate(); 2579 tr.collapse(true); 2580 sp = Math.abs(tr.move('character', c)); 2581 2582 tr = r.duplicate(); 2583 tr.collapse(false); 2584 le = Math.abs(tr.move('character', c)) - sp; 6381 2585 6382 2586 return { … … 6387 2591 }; 6388 2592 } 6389 } else { 6390 s = this.getSel(); 6391 e = this.getFocusElement(); 2593 2594 // Handle W3C 2595 e = t.getNode(); 2596 s = t.getSel(); 6392 2597 6393 2598 if (!s) 6394 2599 return null; 6395 2600 2601 // Image selection 6396 2602 if (e && e.nodeName == 'IMG') { 6397 /*nl = b.getElementsByTagName('IMG');6398 for (i=0; i<nl.length; i++) {6399 if (e == nl[i]) {6400 sp = i;6401 break;6402 }6403 }*/6404 6405 2603 return { 6406 start : -1,6407 end : -1,6408 index : sp,6409 2604 scrollX : sx, 6410 2605 scrollY : sy … … 6412 2607 } 6413 2608 2609 // Text selection 2610 2611 function getPos(r, sn, en) { 2612 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; 2613 2614 while ((n = w.nextNode()) != null) { 2615 if (n == sn) 2616 d.start = p; 2617 2618 if (n == en) { 2619 d.end = p; 2620 return d; 2621 } 2622 2623 p += n.nodeValue ? n.nodeValue.length : 0; 2624 } 2625 2626 return null; 2627 }; 2628 6414 2629 // Caret or selection 6415 2630 if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) { 6416 e = this._getPosText(b, s.anchorNode, s.focusNode);2631 e = getPos(ro, s.anchorNode, s.focusNode); 6417 2632 6418 2633 if (!e) … … 6426 2641 }; 6427 2642 } else { 6428 e = this._getPosText(b, rng.startContainer, rng.endContainer);2643 e = getPos(ro, r.startContainer, r.endContainer); 6429 2644 6430 2645 if (!e) … … 6432 2647 6433 2648 return { 6434 start : e.start + r ng.startOffset,6435 end : e.end + r ng.endOffset,2649 start : e.start + r.startOffset, 2650 end : e.end + r.endOffset, 6436 2651 scrollX : sx, 6437 2652 scrollY : sy 6438 2653 }; 6439 2654 } 2655 }, 2656 2657 moveToBookmark : function(b) { 2658 var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd; 2659 2660 function getPos(r, sp, ep) { 2661 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; 2662 2663 while ((n = w.nextNode()) != null) { 2664 p += n.nodeValue ? n.nodeValue.length : 0; 2665 2666 if (p >= sp && !d.startNode) { 2667 d.startNode = n; 2668 d.startOffset = sp - (p - n.nodeValue.length); 2669 } 2670 2671 if (p >= ep) { 2672 d.endNode = n; 2673 d.endOffset = ep - (p - n.nodeValue.length); 2674 2675 return d; 2676 } 2677 } 2678 2679 return null; 2680 }; 2681 2682 if (!b) 2683 return false; 2684 2685 t.win.scrollTo(b.scrollX, b.scrollY); 2686 2687 // Handle explorer 2688 if (isIE) { 2689 // Handle simple 2690 if (r = b.rng) { 2691 try { 2692 r.select(); 2693 } catch (ex) { 2694 // Ignore 2695 } 2696 2697 return true; 2698 } 2699 2700 t.win.focus(); 2701 2702 // Handle control bookmark 2703 if (b.tag) { 2704 r = ro.createControlRange(); 2705 2706 each(t.dom.select(b.tag), function(n, i) { 2707 if (i == b.index) 2708 r.addElement(n); 2709 }); 2710 } else { 2711 // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs 2712 try { 2713 // Incorrect bookmark 2714 if (b.start < 0) 2715 return true; 2716 2717 r = s.createRange(); 2718 r.moveToElementText(ro); 2719 r.collapse(true); 2720 r.moveStart('character', b.start); 2721 r.moveEnd('character', b.length); 2722 } catch (ex2) { 2723 return true; 2724 } 2725 } 2726 2727 r.select(); 2728 2729 return true; 2730 } 2731 2732 // Handle W3C 2733 if (!s) 2734 return false; 2735 2736 // Handle simple 2737 if (b.rng) { 2738 s.removeAllRanges(); 2739 s.addRange(b.rng); 2740 } else { 2741 if (is(b.start) && is(b.end)) { 2742 try { 2743 sd = getPos(ro, b.start, b.end); 2744 if (sd) { 2745 r = t.dom.doc.createRange(); 2746 r.setStart(sd.startNode, sd.startOffset); 2747 r.setEnd(sd.endNode, sd.endOffset); 2748 s.removeAllRanges(); 2749 s.addRange(r); 2750 } 2751 2752 if (!tinymce.isOpera) 2753 t.win.focus(); 2754 } catch (ex) { 2755 // Ignore 2756 } 2757 } 2758 } 2759 }, 2760 2761 select : function(n, c) { 2762 var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document; 2763 2764 function first(n) { 2765 return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null; 2766 }; 2767 2768 function last(n) { 2769 var c, o, w; 2770 2771 if (!n) 2772 return null; 2773 2774 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); 2775 while (c = w.nextNode()) 2776 o = c; 2777 2778 return o; 2779 }; 2780 2781 if (isIE) { 2782 try { 2783 b = d.body; 2784 2785 if (/^(IMG|TABLE)$/.test(n.nodeName)) { 2786 r = b.createControlRange(); 2787 r.addElement(n); 2788 } else { 2789 r = b.createTextRange(); 2790 r.moveToElementText(n); 2791 } 2792 2793 r.select(); 2794 } catch (ex) { 2795 // Throws illigal agrument in IE some times 2796 } 2797 } else { 2798 if (c) { 2799 fn = first(n); 2800 ln = last(n); 2801 2802 if (fn && ln) { 2803 //console.debug(fn, ln); 2804 r = d.createRange(); 2805 r.setStart(fn, 0); 2806 r.setEnd(ln, ln.nodeValue.length); 2807 } else 2808 r.selectNode(n); 2809 } else 2810 r.selectNode(n); 2811 2812 t.setRng(r); 2813 } 2814 2815 return n; 2816 }, 2817 2818 isCollapsed : function() { 2819 var t = this, r = t.getRng(), s = t.getSel(); 2820 2821 if (!r || r.item) 2822 return false; 2823 2824 return !s || r.boundingWidth == 0 || s.isCollapsed; 2825 }, 2826 2827 collapse : function(b) { 2828 var t = this, r = t.getRng(), n; 2829 2830 // Control range on IE 2831 if (r.item) { 2832 n = r.item(0); 2833 r = this.win.document.body.createTextRange(); 2834 r.moveToElementText(n); 2835 } 2836 2837 r.collapse(!!b); 2838 t.setRng(r); 2839 }, 2840 2841 getSel : function() { 2842 var t = this, w = this.win; 2843 2844 return w.getSelection ? w.getSelection() : w.document.selection; 2845 }, 2846 2847 getRng : function() { 2848 var t = this, s = t.getSel(), r; 2849 2850 try { 2851 if (s) 2852 r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange()); 2853 } catch (ex) { 2854 // IE throws unspecified error here if TinyMCE is placed in a frame/iframe 2855 } 2856 2857 // No range found then create an empty one 2858 // This can occur when the editor is placed in a hidden container element on Gecko 2859 // Or on IE when there was an exception 2860 if (!r) 2861 r = isIE ? t.win.document.body.createTextRange() : t.win.document.createRange(); 2862 2863 return r; 2864 }, 2865 2866 setRng : function(r) { 2867 var s; 2868 2869 if (!isIE) { 2870 s = this.getSel(); 2871 2872 if (s) { 2873 s.removeAllRanges(); 2874 s.addRange(r); 2875 } 2876 } else 2877 r.select(); 2878 }, 2879 2880 setNode : function(n) { 2881 var t = this; 2882 2883 t.setContent(t.dom.getOuterHTML(n)); 2884 2885 return n; 2886 }, 2887 2888 getNode : function() { 2889 var t = this, r = t.getRng(), s = t.getSel(), e; 2890 2891 if (!isIE) { 2892 // Range maybe lost after the editor is made visible again 2893 if (!r) 2894 return t.dom.getRoot(); 2895 2896 e = r.commonAncestorContainer; 2897 2898 // Handle selection a image or other control like element such as anchors 2899 if (!r.collapsed) { 2900 if (r.startContainer == r.endContainer || (tinymce.isWebKit && r.startContainer == r.endContainer.parentNode)) { 2901 if (r.startOffset - r.endOffset < 2 || tinymce.isWebKit) { 2902 if (r.startContainer.hasChildNodes()) 2903 e = r.startContainer.childNodes[r.startOffset]; 2904 } 2905 } 2906 } 2907 2908 return t.dom.getParent(e, function(n) { 2909 return n.nodeType == 1; 2910 }); 2911 } 2912 2913 return r.item ? r.item(0) : r.parentElement(); 6440 2914 } 6441 2915 6442 return null; 2916 }); 2917 })(); 2918 2919 /* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */ 2920 2921 (function() { 2922 tinymce.create('tinymce.dom.XMLWriter', { 2923 node : null, 2924 2925 XMLWriter : function(s) { 2926 // Get XML document 2927 function getXML() { 2928 var i = document.implementation; 2929 2930 if (!i || !i.createDocument) { 2931 // Try IE objects 2932 try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {} 2933 try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {} 2934 } else 2935 return i.createDocument('', '', null); 2936 }; 2937 2938 this.doc = getXML(); 2939 this.reset(); 2940 }, 2941 2942 reset : function() { 2943 var t = this, d = t.doc; 2944 2945 if (d.firstChild) 2946 d.removeChild(d.firstChild); 2947 2948 t.node = d.appendChild(d.createElement("html")); 2949 }, 2950 2951 writeStartElement : function(n) { 2952 var t = this; 2953 2954 t.node = t.node.appendChild(t.doc.createElement(n)); 2955 }, 2956 2957 writeAttribute : function(n, v) { 2958 // Since Opera doesn't escape > into > we need to do it our self 2959 if (tinymce.isOpera) 2960 v = v.replace(/>/g, '|>'); 2961 2962 this.node.setAttribute(n, v); 2963 }, 2964 2965 writeEndElement : function() { 2966 this.node = this.node.parentNode; 2967 }, 2968 2969 writeFullEndElement : function() { 2970 var t = this, n = t.node; 2971 2972 n.appendChild(t.doc.createTextNode("")); 2973 t.node = n.parentNode; 2974 }, 2975 2976 writeText : function(v) { 2977 // Since Opera doesn't escape > into > we need to do it our self 2978 if (tinymce.isOpera) 2979 v = v.replace(/>/g, '|>'); 2980 2981 this.node.appendChild(this.doc.createTextNode(v)); 2982 }, 2983 2984 writeCDATA : function(v) { 2985 this.node.appendChild(this.doc.createCDATA(v)); 2986 }, 2987 2988 writeComment : function(v) { 2989 this.node.appendChild(this.doc.createComment(v)); 2990 }, 2991 2992 getContent : function() { 2993 var h; 2994 2995 h = this.doc.xml || new XMLSerializer().serializeToString(this.doc); 2996 h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g, ''); 2997 h = h.replace(/ ?\/>/g, ' />'); 2998 2999 // Since Opera doesn't escape > into > we need to do it our self to normalize the output for all browsers 3000 if (tinymce.isOpera) 3001 h = h.replace(/\|>/g, '>'); 3002 3003 return h; 3004 } 3005 3006 }); 3007 })(); 3008 3009 /* file:jscripts/tiny_mce/classes/dom/Serializer.js */ 3010 3011 (function() { 3012 // Shorten names 3013 var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE; 3014 3015 // Returns only attribites that have values not all attributes in IE 3016 function getIEAtts(n) { 3017 var o = []; 3018 3019 // Object will throw exception in IE 3020 if (n.nodeName == 'OBJECT') 3021 return n.attributes; 3022 3023 n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) { 3024 o.push({specified : 1, nodeName : b}); 3025 }); 3026 3027 return o; 3028 }; 3029 3030 function wildcardToRE(s) { 3031 return s.replace(/([?+*])/g, '.$1'); 3032 }; 3033 3034 tinymce.create('tinymce.dom.Serializer', { 3035 Serializer : function(s) { 3036 var t = this; 3037 3038 t.key = 0; 3039 t.onPreProcess = new Dispatcher(t); 3040 t.onPostProcess = new Dispatcher(t); 3041 t.writer = new tinymce.dom.XMLWriter(); 3042 3043 // Default settings 3044 t.settings = s = extend({ 3045 dom : tinymce.DOM, 3046 valid_nodes : 0, 3047 node_filter : 0, 3048 attr_filter : 0, 3049 invalid_attrs : /^(mce_|_moz_$)/, 3050 closed : /(br|hr|input|meta|img|link|param)/, 3051 entity_encoding : 'named', 3052 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', 3053 valid_elements : '*[*]', 3054 extended_valid_elements : 0, 3055 valid_child_elements : 0, 3056 invalid_elements : 0, 3057 fix_table_elements : 0, 3058 fix_list_elements : true, 3059 fix_content_duplication : true, 3060 convert_fonts_to_spans : false, 3061 font_size_classes : 0, 3062 font_size_style_values : 0, 3063 apply_source_formatting : 0, 3064 indent_mode : 'simple', 3065 indent_char : '\t', 3066 indent_levels : 1, 3067 remove_linebreaks : 1 3068 }, s); 3069 3070 t.dom = s.dom; 3071 3072 if (s.fix_list_elements) { 3073 t.onPreProcess.add(function(se, o) { 3074 var nl, x, a = ['ol', 'ul'], i, n, p, r = /^(OL|UL)$/, np; 3075 3076 function prevNode(e, n) { 3077 var a = n.split(','), i; 3078 3079 while ((e = e.previousSibling) != null) { 3080 for (i=0; i<a.length; i++) { 3081 if (e.nodeName == a[i]) 3082 return e; 3083 } 3084 } 3085 3086 return null; 3087 }; 3088 3089 for (x=0; x<a.length; x++) { 3090 nl = t.dom.select(a[x], o.node); 3091 3092 for (i=0; i<nl.length; i++) { 3093 n = nl[i]; 3094 p = n.parentNode; 3095 3096 if (r.test(p.nodeName)) { 3097 np = prevNode(n, 'LI'); 3098 3099 if (!np) { 3100 np = t.dom.create('li'); 3101 np.innerHTML = ' '; 3102 np.appendChild(n); 3103 p.insertBefore(np, p.firstChild); 3104 } else 3105 np.appendChild(n); 3106 } 3107 } 3108 } 3109 }); 3110 } 3111 3112 if (s.fix_table_elements) { 3113 t.onPreProcess.add(function(se, o) { 3114 var ta = [], d = t.dom.doc; 3115 3116 // Build list of HTML chunks and replace tables with comment placeholders 3117 each(t.dom.select('table', o.node), function(e) { 3118 var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), p = [], i, h; 3119 3120 if (pa) { 3121 t.dom.getParent(e, function(n) { 3122 if (n != e) 3123 p.push(n.nodeName); 3124 }); 3125 3126 h = ''; 3127 3128 for (i = 0; i < p.length; i++) 3129 h += '</' + p[i]+ '>'; 3130 3131 h += t.dom.getOuterHTML(e); 3132 3133 for (i = p.length - 1; i >= 0; i--) 3134 h += '<' + p[i]+ '>'; 3135 3136 ta.push(h); 3137 e.parentNode.replaceChild(d.createComment('mcetable:' + (ta.length - 1)), e); 3138 } 3139 }); 3140 3141 // Replace table placeholders with end parents + table + start parents HTML code 3142 t.dom.setHTML(o.node, o.node.innerHTML.replace(/<!--mcetable:([0-9]+)-->/g, function(a, b) { 3143 return ta[parseInt(b)]; 3144 })); 3145 }); 3146 } 3147 }, 3148 3149 setEntities : function(s) { 3150 var a, i, l = {}, re = '', v; 3151 3152 // No need to setup more than once 3153 if (this.entityLookup) 3154 return; 3155 3156 // Build regex and lookup array 3157 a = s.split(','); 3158 for (i = 0; i < a.length; i += 2) { 3159 v = a[i]; 3160 3161 // Don't add default & " etc. 3162 if (v == 34 || v == 38 || v == 60 || v == 62) 3163 continue; 3164 3165 l[String.fromCharCode(a[i])] = a[i + 1]; 3166 3167 v = parseInt(a[i]).toString(16); 3168 re += '\\u' + '0000'.substring(v.length) + v; 3169 } 3170 3171 this.entitiesRE = new RegExp('[' + re + ']', 'g'); 3172 this.entityLookup = l; 3173 }, 3174 3175 setValidChildRules : function(s) { 3176 this.childRules = null; 3177 this.addValidChildRules(s); 3178 }, 3179 3180 addValidChildRules : function(s) { 3181 var t = this, inst, intr, bloc; 3182 3183 if (!s) 3184 return; 3185 3186 inst = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment'; 3187 intr = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment'; 3188 bloc = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP'; 3189 3190 each(s.split(','), function(s) { 3191 var p = s.split(/\[|\]/), re; 3192 3193 s = ''; 3194 each(p[1].split('|'), function(v) { 3195 if (s) 3196 s += '|'; 3197 3198 switch (v) { 3199 case '%itrans': 3200 v = intr; 3201 break; 3202 3203 case '%itrans_na': 3204 v = intr.substring(2); 3205 break; 3206 3207 case '%istrict': 3208 v = inst; 3209 break; 3210 3211 case '%istrict_na': 3212 v = inst.substring(2); 3213 break; 3214 3215 case '%btrans': 3216 v = bloc; 3217 break; 3218 3219 case '%bstrict': 3220 v = bloc; 3221 break; 3222 } 3223 3224 s += v; 3225 }); 3226 re = new RegExp('^(' + s.toLowerCase() + ')$', 'i'); 3227 3228 each(p[0].split('/'), function(s) { 3229 t.childRules = t.childRules || {}; 3230 t.childRules[s] = re; 3231 }); 3232 }); 3233 3234 // Build regex 3235 s = ''; 3236 each(t.childRules, function(v, k) { 3237 if (s) 3238 s += '|'; 3239 3240 s += k; 3241 }); 3242 3243 t.parentElementsRE = new RegExp('^(' + s.toLowerCase() + ')$', 'i'); 3244 3245 /*console.debug(t.parentElementsRE.toString()); 3246 each(t.childRules, function(v) { 3247 console.debug(v.toString()); 3248 });*/ 3249 }, 3250 3251 setRules : function(s) { 3252 var t = this; 3253 3254 t._setup(); 3255 t.rules = {}; 3256 t.wildRules = []; 3257 t.validElements = {}; 3258 3259 return t.addRules(s); 3260 }, 3261 3262 addRules : function(s) { 3263 var t = this, dr; 3264 3265 if (!s) 3266 return; 3267 3268 t._setup(); 3269 3270 each(s.split(','), function(s) { 3271 var p = s.split(/\[|\]/), tn = p[0].split('/'), ra, at, wat, va = []; 3272 3273 // Extend with default rules 3274 if (dr) 3275 at = tinymce.extend([], dr.attribs); 3276 3277 // Parse attributes 3278 if (p.length > 1) { 3279 each(p[1].split('|'), function(s) { 3280 var ar = {}, i; 3281 3282 at = at || []; 3283 3284 // Parse attribute rule 3285 s = s.replace(/::/g, '~'); 3286 s = /^([!\-])?([\w*.?~]+|)([=:<])?(.+)?$/.exec(s); 3287 s[2] = s[2].replace(/~/g, ':'); 3288 3289 // Add required attributes 3290 if (s[1] == '!') { 3291 ra = ra || []; 3292 ra.push(s[2]); 3293 } 3294 3295 // Remove inherited attributes 3296 if (s[1] == '-') { 3297 for (i = 0; i <at.length; i++) { 3298 if (at[i].name == s[2]) { 3299 at.splice(i, 1); 3300 return; 3301 } 3302 } 3303 } 3304 3305 switch (s[3]) { 3306 // Add default attrib values 3307 case '=': 3308 ar.defaultVal = s[4] || ''; 3309 break; 3310 3311 // Add forced attrib values 3312 case ':': 3313 ar.forcedVal = s[4]; 3314 break; 3315 3316 // Add validation values 3317 case '<': 3318 ar.validVals = s[4].split('?'); 3319 break; 3320 } 3321 3322 if (/[*.?]/.test(s[2])) { 3323 wat = wat || []; 3324 ar.nameRE = new RegExp('^' + wildcardToRE(s[2]) + '$'); 3325 wat.push(ar); 3326 } else { 3327 ar.name = s[2]; 3328 at.push(ar); 3329 } 3330 3331 va.push(s[2]); 3332 }); 3333 } 3334 3335 // Handle element names 3336 each(tn, function(s, i) { 3337 var pr = s.charAt(0), x = 1, ru = {}; 3338 3339 // Extend with default rule data 3340 if (dr) { 3341 if (dr.noEmpty) 3342 ru.noEmpty = dr.noEmpty; 3343 3344 if (dr.fullEnd) 3345 ru.fullEnd = dr.fullEnd; 3346 3347 if (dr.padd) 3348 ru.padd = dr.padd; 3349 } 3350 3351 // Handle prefixes 3352 switch (pr) { 3353 case '-': 3354 ru.noEmpty = true; 3355 break; 3356 3357 case '+': 3358 ru.fullEnd = true; 3359 break; 3360 3361 case '#': 3362 ru.padd = true; 3363 break; 3364 3365 default: 3366 x = 0; 3367 } 3368 3369 tn[i] = s = s.substring(x); 3370 t.validElements[s] = 1; 3371 3372 // Add element name or element regex 3373 if (/[*.?]/.test(tn[0])) { 3374 ru.nameRE = new RegExp('^' + wildcardToRE(tn[0]) + '$'); 3375 t.wildRules = t.wildRules || {}; 3376 t.wildRules.push(ru); 3377 } else { 3378 ru.name = tn[0]; 3379 3380 // Store away default rule 3381 if (tn[0] == '@') 3382 dr = ru; 3383 3384 t.rules[s] = ru; 3385 } 3386 3387 ru.attribs = at; 3388 3389 if (ra) 3390 ru.requiredAttribs = ra; 3391 3392 if (wat) { 3393 // Build valid attributes regexp 3394 s = ''; 3395 each(va, function(v) { 3396 if (s) 3397 s += '|'; 3398 3399 s += '(' + wildcardToRE(v) + ')'; 3400 }); 3401 ru.validAttribsRE = new RegExp('^' + s.toLowerCase() + '$'); 3402 ru.wildAttribs = wat; 3403 } 3404 }); 3405 }); 3406 3407 // Build valid elements regexp 3408 s = ''; 3409 each(t.validElements, function(v, k) { 3410 if (s) 3411 s += '|'; 3412 3413 if (k != '@') 3414 s += k; 3415 }); 3416 t.validElementsRE = new RegExp('^(' + wildcardToRE(s.toLowerCase()) + ')$'); 3417 3418 //console.debug(t.validElementsRE.toString()); 3419 //console.dir(t.rules); 3420 //console.dir(t.wildRules); 3421 }, 3422 3423 findRule : function(n) { 3424 var t = this, rl = t.rules, i, r; 3425 3426 t._setup(); 3427 3428 // Exact match 3429 r = rl[n]; 3430 if (r) 3431 return r; 3432 3433 // Try wildcards 3434 rl = t.wildRules; 3435 for (i = 0; i < rl.length; i++) { 3436 if (rl[i].nameRE.test(n)) 3437 return rl[i]; 3438 } 3439 3440 return null; 3441 }, 3442 3443 findAttribRule : function(ru, n) { 3444 var i, wa = ru.wildAttribs; 3445 3446 for (i = 0; i < wa.length; i++) { 3447 if (wa[i].nameRE.test(n)) 3448 return wa[i]; 3449 } 3450 3451 return null; 3452 }, 3453 3454 serialize : function(n, o) { 3455 var h, t = this; 3456 3457 t._setup(); 3458 o = o || {}; 3459 o.format = o.format || 'html'; 3460 t.processObj = o; 3461 n = n.cloneNode(true); 3462 t.key = '' + (parseInt(t.key) + 1); 3463 3464 // Pre process 3465 if (!o.no_events) { 3466 o.node = n; 3467 t.onPreProcess.dispatch(t, o); 3468 } 3469 3470 // Serialize HTML DOM into a string 3471 t.writer.reset(); 3472 t._serializeNode(n, o.getInner); 3473 3474 // Post process 3475 o.content = t.writer.getContent(); 3476 3477 if (!o.no_events) 3478 t.onPostProcess.dispatch(t, o); 3479 3480 t._postProcess(o); 3481 o.node = null; 3482 3483 return tinymce.trim(o.content); 3484 }, 3485 3486 // Internal functions 3487 3488 _postProcess : function(o) { 3489 var t = this, s = t.settings, h = o.content, sc = [], p, l; 3490 3491 if (o.format == 'html') { 3492 // Protect some elements 3493 p = t._protect({ 3494 content : h, 3495 patterns : [ 3496 /(<script[^>]*>)(.*?)(<\/script>)/g, 3497 /(<style[^>]*>)(.*?)(<\/style>)/g, 3498 /(<pre[^>]*>)(.*?)(<\/pre>)/g 3499 ] 3500 }); 3501 3502 h = p.content; 3503 3504 // Entity encode 3505 if (s.entity_encoding !== 'raw') { 3506 if (s.entity_encoding.indexOf('named') != -1) { 3507 t.setEntities(s.entities); 3508 l = t.entityLookup; 3509 3510 h = h.replace(t.entitiesRE, function(a) { 3511 var v; 3512 3513 if (v = l[a]) 3514 a = '&' + v + ';'; 3515 3516 return a; 3517 }); 3518 } 3519 3520 if (s.entity_encoding.indexOf('numeric') != -1) { 3521 h = h.replace(/[\u007E-\uFFFF]/g, function(a) { 3522 return '&#' + a.charCodeAt(0) + ';'; 3523 }); 3524 } 3525 } 3526 3527 // Use BR instead of padded P elements inside editor and use <p> </p> outside editor 3528 if (o.set) 3529 h = h.replace(/<p>\s+( | |\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>'); 3530 else 3531 h = h.replace(/<p>\s+( | |\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>'); 3532 3533 // Since Gecko and Safari keeps whitespace in the DOM we need to 3534 // remove it inorder to match other browsers. But I think Gecko and Safari is right. 3535 // This process is only done when getting contents out from the editor. 3536 if (!o.set) { 3537 if (s.remove_linebreaks) { 3538 h = h.replace(/(<[^>]+>)\s+/g, '$1 '); 3539 h = h.replace(/\s+(<\/[^>]+>)/g, ' $1'); 3540 h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start 3541 h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start 3542 h = h.replace(/\s+<\/(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end 3543 } 3544 3545 // Simple indentation 3546 if (s.apply_source_formatting && s.indent_mode == 'simple') { 3547 // Add line breaks before and after block elements 3548 h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html)(|[^>]+)>\s*/g, '\n<$1$2$3>\n'); 3549 h = h.replace(/\s*<(p|h[1-6]|div|title|style|pre|script|td|li)(|[^>]+)>/g, '\n<$1$2>'); 3550 h = h.replace(/<\/(p|h[1-6]|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n'); 3551 h = h.replace(/\n\n/g, '\n'); 3552 } 3553 } 3554 3555 h = t._unprotect(h, p); 3556 } 3557 3558 o.content = h; 3559 }, 3560 3561 _serializeNode : function(n, inn) { 3562 var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv; 3563 3564 if (!s.node_filter || s.node_filter(n)) { 3565 switch (n.nodeType) { 3566 case 1: // Element 3567 if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus')) 3568 return; 3569 3570 iv = false; 3571 hc = n.hasChildNodes(); 3572 nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase(); 3573 3574 // Add correct prefix on IE 3575 if (isIE) { 3576 if (n.scopeName !== 'HTML' && n.scopeName !== 'html') 3577 nn = n.scopeName + ':' + nn; 3578 } 3579 3580 // Remove mce prefix on IE needed for the abbr element 3581 if (nn.indexOf('mce:') === 0) 3582 nn = nn.substring(4); 3583 3584 // Check if valid 3585 if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) { 3586 iv = true; 3587 break; 3588 } 3589 3590 if (isIE) { 3591 // Fix IE content duplication (DOM can have multiple copies of the same node) 3592 if (s.fix_content_duplication) { 3593 if (n.mce_serialized == t.key) 3594 return; 3595 3596 n.mce_serialized = t.key; 3597 } 3598 3599 // IE sometimes adds a / infront of the node name 3600 if (nn.charAt(0) == '/') 3601 nn = nn.substring(1); 3602 } 3603 3604 // Check if valid child 3605 if (t.childRules) { 3606 if (t.parentElementsRE.test(t.elementName)) { 3607 if (!t.childRules[t.elementName].test(nn)) { 3608 iv = true; 3609 break; 3610 } 3611 } 3612 3613 t.elementName = nn; 3614 } 3615 3616 ru = t.findRule(nn); 3617 nn = ru.name || nn; 3618 3619 // Skip empty nodes or empty node name in IE 3620 if ((!hc && ru.noEmpty) || (isIE && !nn)) { 3621 iv = true; 3622 break; 3623 } 3624 3625 // Check required 3626 if (ru.requiredAttribs) { 3627 a = ru.requiredAttribs; 3628 3629 for (i = a.length - 1; i >= 0; i--) { 3630 if (this.dom.getAttrib(n, a[i]) !== '') 3631 break; 3632 } 3633 3634 // None of the required was there 3635 if (i == -1) { 3636 iv = true; 3637 break; 3638 } 3639 } 3640 3641 w.writeStartElement(nn); 3642 3643 // Add ordered attributes 3644 if (ru.attribs) { 3645 for (i=0, at = ru.attribs, l = at.length; i<l; i++) { 3646 a = at[i]; 3647 v = t._getAttrib(n, a); 3648 3649 if (v !== null) 3650 w.writeAttribute(a.name, v); 3651 } 3652 } 3653 3654 // Add wild attributes 3655 if (ru.validAttribsRE) { 3656 at = isIE ? getIEAtts(n) : n.attributes; 3657 for (i=at.length-1; i>-1; i--) { 3658 no = at[i]; 3659 3660 if (no.specified) { 3661 a = no.nodeName.toLowerCase(); 3662 3663 if (s.invalid_attrs.test(a) || !ru.validAttribsRE.test(a)) 3664 continue; 3665 3666 ar = t.findAttribRule(ru, a); 3667 v = t._getAttrib(n, ar, a); 3668 3669 if (v !== null) 3670 w.writeAttribute(a, v); 3671 } 3672 } 3673 } 3674 3675 // Padd empty nodes with a 3676 if (!hc && ru.padd) 3677 w.writeText('\u00a0'); 3678 3679 break; 3680 3681 case 3: // Text 3682 // Check if valid child 3683 if (t.childRules && t.parentElementsRE.test(t.elementName)) { 3684 if (!t.childRules[t.elementName].test(n.nodeName)) 3685 return; 3686 } 3687 3688 return w.writeText(n.nodeValue); 3689 3690 case 4: // CDATA 3691 return w.writeCDATA(n.nodeValue); 3692 3693 case 8: // Comment 3694 return w.writeComment(n.nodeValue); 3695 } 3696 } else if (n.nodeType == 1) 3697 hc = n.hasChildNodes(); 3698 3699 if (hc) { 3700 cn = n.firstChild; 3701 3702 while (cn) { 3703 t._serializeNode(cn); 3704 t.elementName = nn; 3705 cn = cn.nextSibling; 3706 } 3707 } 3708 3709 // Write element end 3710 if (!iv) { 3711 if (hc || !s.closed.test(nn)) 3712 w.writeFullEndElement(); 3713 else 3714 w.writeEndElement(); 3715 } 3716 }, 3717 3718 _protect : function(o) { 3719 o.items = o.items || []; 3720 3721 function enc(s) { 3722 return s.replace(/[\r\n]/g, function(c) { 3723 if (c === '\n') 3724 return '\\n'; 3725 3726 return '\\r'; 3727 }); 3728 }; 3729 3730 function dec(s) { 3731 return s.replace(/\\[rn]/g, function(c) { 3732 if (c === '\\n') 3733 return '\n'; 3734 3735 return '\r'; 3736 }); 3737 }; 3738 3739 each(o.patterns, function(p) { 3740 o.content = dec(enc(o.content).replace(p, function(x, a, b, c) { 3741 o.items.push(dec(b)); 3742 return a + '<!--mce:' + (o.items.length - 1) + '-->' + c; 3743 })); 3744 }); 3745 3746 return o; 3747 }, 3748 3749 _unprotect : function(h, o) { 3750 h = h.replace(/\<!--mce:([0-9]+)--\>/g, function(a, b) { 3751 return o.items[parseInt(b)]; 3752 }); 3753 3754 o.items = []; 3755 3756 return h; 3757 }, 3758 3759 _setup : function() { 3760 var t = this, s = this.settings; 3761 3762 if (t.done) 3763 return; 3764 3765 t.done = 1; 3766 3767 t.setRules(s.valid_elements); 3768 t.addRules(s.extended_valid_elements); 3769 t.addValidChildRules(s.valid_child_elements); 3770 3771 if (s.invalid_elements) 3772 t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(',', '|').toLowerCase()) + ')$'); 3773 3774 if (s.attrib_value_filter) 3775 t.attribValueFilter = s.attribValueFilter; 3776 }, 3777 3778 _getAttrib : function(n, a, na) { 3779 var i, v; 3780 3781 na = na || a.name; 3782 3783 if (a.forcedVal && (v = a.forcedVal)) { 3784 if (v === '{$uid}') 3785 return this.dom.uniqueId(); 3786 3787 return v; 3788 } 3789 3790 v = this.dom.getAttrib(n, na); 3791 3792 switch (na) { 3793 case 'rowspan': 3794 case 'colspan': 3795 // Whats the point? Remove usless attribute value 3796 if (v == '1') 3797 v = ''; 3798 3799 break; 3800 } 3801 3802 if (this.attribValueFilter) 3803 v = this.attribValueFilter(na, v, n); 3804 3805 if (a.validVals) { 3806 for (i = a.validVals.length - 1; i >= 0; i--) { 3807 if (v == a.validVals[i]) 3808 break; 3809 } 3810 3811 if (i == -1) 3812 return null; 3813 } 3814 3815 if (v === '' && typeof(a.defaultVal) != 'undefined') { 3816 v = a.defaultVal; 3817 3818 if (v === '{$uid}') 3819 return this.dom.uniqueId(); 3820 3821 return v; 3822 } else { 3823 // Remove internal mceItemXX classes when content is extracted from editor 3824 if (na == 'class' && this.processObj.get) 3825 v = v.replace(/\bmceItem\w+\b/g, ''); 3826 } 3827 3828 if (v === '') 3829 return null; 3830 3831 3832 return v; 3833 } 3834 3835 }); 3836 })(); 3837 3838 /* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */ 3839 3840 (function() { 3841 var each = tinymce.each; 3842 3843 tinymce.create('tinymce.dom.ScriptLoader', { 3844 ScriptLoader : function(s) { 3845 this.settings = s || {}; 3846 this.queue = []; 3847 this.lookup = {}; 3848 }, 3849 3850 markDone : function(u) { 3851 this.lookup[u] = {state : 2, url : u}; 3852 }, 3853 3854 add : function(u, cb, s, pr) { 3855 var t = this, lo = t.lookup, o; 3856 3857 if (o = lo[u]) { 3858 // Is loaded fire callback 3859 if (cb && o.state == 2) 3860 cb.call(s || this); 3861 3862 return o; 3863 } 3864 3865 o = {state : 0, url : u, func : cb, scope : s || this}; 3866 3867 if (pr) 3868 t.queue.unshift(o); 3869 else 3870 t.queue.push(o); 3871 3872 lo[u] = o; 3873 3874 return o; 3875 }, 3876 3877 load : function(u, cb, s) { 3878 var o; 3879 3880 if (!tinymce.is(u, 'string')) { 3881 o = []; 3882 3883 each(u, function(u) { 3884 o.push({state : 0, url : u}); 3885 }); 3886 3887 this.loadScripts(o, cb, s); 3888 } else 3889 this.loadScripts([{state : 0, url : u}], cb, s); 3890 }, 3891 3892 loadQueue : function(cb, s) { 3893 var t = this; 3894 3895 if (!t.queueLoading) { 3896 t.queueLoading = 1; 3897 t.queueCallbacks = []; 3898 3899 t.loadScripts(t.queue, function() { 3900 t.queueLoading = 0; 3901 3902 if (cb) 3903 cb.call(s || t); 3904 3905 each(t.queueCallbacks, function(o) { 3906 o.func.call(o.scope); 3907 }); 3908 }); 3909 } else if (cb) 3910 t.queueCallbacks.push({func : cb, scope : s || t}); 3911 }, 3912 3913 eval : function(co) { 3914 var w = window; 3915 3916 // Evaluate script 3917 if (!w.execScript) { 3918 try { 3919 eval.call(w, co); 3920 } catch (ex) { 3921 eval(co, w); // Firefox 3.0a8 3922 } 3923 } else 3924 w.execScript(co); // IE 3925 }, 3926 3927 loadScripts : function(sc, cb, s) { 3928 var t = this, lo = t.lookup; 3929 3930 function done(o) { 3931 o.state = 2; // Has been loaded 3932 3933 // Run callback 3934 if (o.func) 3935 o.func.call(o.scope || t); 3936 }; 3937 3938 function allDone() { 3939 var l; 3940 3941 // Check if all files are loaded 3942 l = sc.length; 3943 each(sc, function(o) { 3944 o = lo[o.url]; 3945 3946 if (o.state === 2) {// It has finished loading 3947 done(o); 3948 l--; 3949 } else 3950 load(o); 3951 }); 3952 3953 // They are all loaded 3954 if (l === 0 && cb) { 3955 cb.call(s || t); 3956 cb = 0; 3957 } 3958 }; 3959 3960 function load(o) { 3961 if (o.state > 0) 3962 return; 3963 3964 o.state = 1; // Is loading 3965 3966 tinymce.util.XHR.send({ 3967 url : o.url, 3968 error : t.settings.error, 3969 success : function(co) { 3970 t.eval(co); 3971 done(o); 3972 allDone(); 3973 } 3974 }); 3975 }; 3976 3977 each(sc, function(o) { 3978 var u = o.url; 3979 3980 // Add to queue if needed 3981 if (!lo[u]) { 3982 lo[u] = o; 3983 t.queue.push(o); 3984 } else 3985 o = lo[u]; 3986 3987 // Is already loading or has been loaded 3988 if (o.state > 0) 3989 return; 3990 3991 if (!tinymce.dom.Event.domLoaded && !t.settings.strict_mode) { 3992 var ix, ol = ''; 3993 3994 // Add onload events 3995 if (cb || o.func) { 3996 o.state = 1; // Is loading 3997 3998 ix = tinymce.dom.ScriptLoader._addOnLoad(function() { 3999 done(o); 4000 allDone(); 4001 }); 4002 4003 if (tinymce.isIE) 4004 ol = ' onreadystatechange="'; 4005 else 4006 ol = ' onload="'; 4007 4008 ol += 'tinymce.dom.ScriptLoader._onLoad(this,\'' + u + '\',' + ix + ');"'; 4009 } 4010 4011 document.write('<script type="text/javascript" src="' + u + '"' + ol + '></script>'); 4012 4013 if (!o.func) 4014 done(o); 4015 } else 4016 load(o); 4017 }); 4018 4019 allDone(); 4020 }, 4021 4022 // Static methods 4023 'static' : { 4024 _addOnLoad : function(f) { 4025 var t = this; 4026 4027 t._funcs = t._funcs || []; 4028 t._funcs.push(f); 4029 4030 return t._funcs.length - 1; 4031 }, 4032 4033 _onLoad : function(e, u, ix) { 4034 if (!tinymce.isIE || e.readyState == 'complete') 4035 this._funcs[ix].call(this); 4036 } 4037 } 4038 4039 }); 4040 4041 // Global script loader 4042 tinymce.ScriptLoader = new tinymce.dom.ScriptLoader(); 4043 })(); 4044 4045 /* file:jscripts/tiny_mce/classes/ui/Control.js */ 4046 4047 (function() { 4048 // Shorten class names 4049 var DOM = tinymce.DOM, is = tinymce.is; 4050 4051 tinymce.create('tinymce.ui.Control', { 4052 Control : function(id, s) { 4053 this.id = id; 4054 this.settings = s = s || {}; 4055 this.rendered = false; 4056 this.onRender = new tinymce.util.Dispatcher(this); 4057 this.classPrefix = ''; 4058 this.scope = s.scope || this; 4059 this.disabled = 0; 4060 this.active = 0; 4061 }, 4062 4063 setDisabled : function(s) { 4064 var e; 4065 4066 if (s != this.disabled) { 4067 e = DOM.get(this.id); 4068 4069 // Add accessibility title for unavailable actions 4070 if (e && this.settings.unavailable_prefix) { 4071 if (s) { 4072 this.prevTitle = e.title; 4073 e.title = this.settings.unavailable_prefix + ": " + e.title; 4074 } else 4075 e.title = this.prevTitle; 4076 } 4077 4078 this.setState('Disabled', s); 4079 this.setState('Enabled', !s); 4080 this.disabled = s; 4081 } 4082 }, 4083 4084 isDisabled : function() { 4085 return this.disabled; 4086 }, 4087 4088 setActive : function(s) { 4089 if (s != this.active) { 4090 this.setState('Active', s); 4091 this.active = s; 4092 } 4093 }, 4094 4095 isActive : function() { 4096 return this.active; 4097 }, 4098 4099 setState : function(c, s) { 4100 var n = DOM.get(this.id); 4101 4102 c = this.classPrefix + c; 4103 4104 if (s) 4105 DOM.addClass(n, c); 4106 else 4107 DOM.removeClass(n, c); 4108 }, 4109 4110 isRendered : function() { 4111 return this.rendered; 4112 }, 4113 4114 renderHTML : function() { 4115 }, 4116 4117 renderTo : function(n) { 4118 n.innerHTML = this.renderHTML(); 4119 }, 4120 4121 postRender : function() { 4122 var t = this, b; 4123 4124 // Set pending states 4125 if (is(t.disabled)) { 4126 b = t.disabled; 4127 t.disabled = -1; 4128 t.setDisabled(b); 4129 } 4130 4131 if (is(t.active)) { 4132 b = t.active; 4133 t.active = -1; 4134 t.setActive(b); 4135 } 4136 }, 4137 4138 destroy : function() { 4139 DOM.remove(this.id); 4140 } 4141 4142 }); 4143 })(); 4144 /* file:jscripts/tiny_mce/classes/ui/Container.js */ 4145 4146 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', { 4147 Container : function(id, s) { 4148 this.parent(id, s); 4149 this.controls = []; 4150 this.lookup = {}; 6443 4151 }, 6444 4152 6445 moveToBookmark : function(bookmark) { 6446 var inst = this.instance, rng, nl, i, ex, b = inst.getBody(), sd; 6447 var doc = inst.getDoc(), win = inst.getWin(), sel = this.getSel(); 6448 6449 if (!bookmark) 4153 add : function(c) { 4154 this.lookup[c.id] = c; 4155 this.controls.push(c); 4156 4157 return c; 4158 }, 4159 4160 get : function(n) { 4161 return this.lookup[n]; 4162 } 4163 4164 }); 4165 4166 4167 /* file:jscripts/tiny_mce/classes/ui/Separator.js */ 4168 4169 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { 4170 renderHTML : function() { 4171 return tinymce.DOM.createHTML('span', {'class' : 'mceSeparator'}); 4172 } 4173 4174 }); 4175 4176 /* file:jscripts/tiny_mce/classes/ui/MenuItem.js */ 4177 4178 (function() { 4179 var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk; 4180 4181 tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', { 4182 MenuItem : function(id, s) { 4183 this.parent(id, s); 4184 this.classPrefix = 'mceMenuItem'; 4185 }, 4186 4187 setSelected : function(s) { 4188 this.setState('Selected', s); 4189 this.selected = s; 4190 }, 4191 4192 isSelected : function() { 4193 return this.selected; 4194 }, 4195 4196 postRender : function() { 4197 var t = this; 4198 4199 t.parent(); 4200 4201 // Set pending state 4202 if (is(t.selected)) 4203 t.setSelected(t.selected); 4204 } 4205 4206 }); 4207 })(); 4208 4209 /* file:jscripts/tiny_mce/classes/ui/Menu.js */ 4210 4211 (function() { 4212 var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk; 4213 4214 tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', { 4215 Menu : function(id, s) { 4216 var t = this; 4217 4218 t.parent(id, s); 4219 t.items = {}; 4220 t.collapsed = false; 4221 t.menuCount = 0; 4222 t.onAddItem = new tinymce.util.Dispatcher(this); 4223 }, 4224 4225 expand : function(d) { 4226 var t = this; 4227 4228 if (d) { 4229 walk(t, function(o) { 4230 if (o.expand) 4231 o.expand(); 4232 }, 'items', t); 4233 } 4234 4235 t.collapsed = false; 4236 }, 4237 4238 collapse : function(d) { 4239 var t = this; 4240 4241 if (d) { 4242 walk(t, function(o) { 4243 if (o.collapse) 4244 o.collapse(); 4245 }, 'items', t); 4246 } 4247 4248 t.collapsed = true; 4249 }, 4250 4251 isCollapsed : function() { 4252 return this.collapsed; 4253 }, 4254 4255 add : function(o) { 4256 if (!o.settings) 4257 o = new tinymce.ui.MenuItem(o.id || DOM.uniqueId(), o); 4258 4259 this.onAddItem.dispatch(this, o); 4260 4261 return this.items[o.id] = o; 4262 }, 4263 4264 addSeparator : function() { 4265 return this.add({separator : true}); 4266 }, 4267 4268 addMenu : function(o) { 4269 if (!o.collapse) 4270 o = this.createMenu(o); 4271 4272 this.menuCount++; 4273 4274 return this.add(o); 4275 }, 4276 4277 hasMenus : function() { 4278 return this.menuCount !== 0; 4279 }, 4280 4281 remove : function(o) { 4282 delete this.items[o.id]; 4283 }, 4284 4285 removeAll : function() { 4286 var t = this; 4287 4288 walk(t, function(o) { 4289 if (o.removeAll) 4290 o.removeAll(); 4291 4292 o.destroy(); 4293 }, 'items', t); 4294 4295 t.items = {}; 4296 }, 4297 4298 createMenu : function(o) { 4299 var m = new tinymce.ui.Menu(o.id || DOM.uniqueId(), o); 4300 4301 m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem); 4302 4303 return m; 4304 } 4305 4306 }); 4307 })(); 4308 /* file:jscripts/tiny_mce/classes/ui/DropMenu.js */ 4309 4310 (function() { 4311 var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element; 4312 4313 tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', { 4314 DropMenu : function(id, s) { 4315 s = s || {}; 4316 s.container = s.container || document.body; 4317 s.offset_x = s.offset_x || 0; 4318 s.offset_y = s.offset_y || 0; 4319 s.vp_offset_x = s.vp_offset_x || 0; 4320 s.vp_offset_y = s.vp_offset_y || 0; 4321 this.parent(id, s); 4322 this.onHideMenu = new tinymce.util.Dispatcher(this); 4323 this.classPrefix = 'mceMenu'; 4324 }, 4325 4326 createMenu : function(s) { 4327 var t = this, cs = t.settings, m; 4328 4329 s.container = s.container || cs.container; 4330 s.parent = t; 4331 s.constrain = s.constrain || cs.constrain; 4332 s['class'] = s['class'] || cs['class']; 4333 s.vp_offset_x = s.vp_offset_x || cs.vp_offset_x; 4334 s.vp_offset_y = s.vp_offset_y || cs.vp_offset_y; 4335 m = new tinymce.ui.DropMenu(s.id || DOM.uniqueId(), s); 4336 4337 m.onAddItem.add(t.onAddItem.dispatch, t.onAddItem); 4338 4339 return m; 4340 }, 4341 4342 update : function() { 4343 var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th; 4344 4345 tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth; 4346 th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight; 4347 4348 if (!DOM.boxModel) 4349 t.element.setStyles({width : tw + 2, height : th + 2}); 4350 else 4351 t.element.setStyles({width : tw, height : th}); 4352 4353 if (s.max_width) 4354 DOM.setStyle(co, 'width', tw); 4355 4356 if (s.max_height) { 4357 DOM.setStyle(co, 'height', th); 4358 4359 if (tb.clientHeight < s.max_height) 4360 DOM.setStyle(co, 'overflow', 'hidden'); 4361 } 4362 }, 4363 4364 showMenu : function(x, y, px) { 4365 var t = this, s = t.settings, co, vp = DOM.getViewPort(), w, h, mx, my, ot = 2, dm, tb; 4366 4367 t.collapse(1); 4368 4369 if (t.isMenuVisible) 4370 return; 4371 4372 if (!t.rendered) { 4373 co = DOM.add(t.settings.container, t.renderNode()); 4374 4375 each(t.items, function(o) { 4376 o.postRender(); 4377 }); 4378 4379 t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container}); 4380 } else 4381 co = DOM.get('menu_' + t.id); 4382 4383 DOM.setStyles(co, {left : -0xFFFF , top : -0xFFFF}); 4384 DOM.show(co); 4385 t.update(); 4386 4387 x += s.offset_x || 0; 4388 y += s.offset_y || 0; 4389 vp.w -= 4; 4390 vp.h -= 4; 4391 4392 // Move inside viewport if not submenu 4393 if (s.constrain) { 4394 w = co.clientWidth - ot; 4395 h = co.clientHeight - ot; 4396 mx = vp.x + vp.w; 4397 my = vp.y + vp.h; 4398 4399 if ((x + s.vp_offset_x + w) > mx) 4400 x = px ? px - w : Math.max(0, (mx - s.vp_offset_x) - w); 4401 4402 if ((y + s.vp_offset_y + h) > my) 4403 y = Math.max(0, (my - s.vp_offset_y) - h); 4404 } 4405 4406 DOM.setStyles(co, {left : x , top : y}); 4407 t.element.update(); 4408 4409 t.isMenuVisible = 1; 4410 t.mouseClickFunc = Event.add(co, 'click', function(e) { 4411 var m; 4412 4413 e = e.target; 4414 4415 if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, 'mceMenuItemSub')) { 4416 m = t.items[e.id]; 4417 4418 if (m.isDisabled()) 4419 return; 4420 4421 if (m.settings.onclick) 4422 m.settings.onclick(e); 4423 4424 dm = t; 4425 4426 while (dm) { 4427 if (dm.hideMenu) 4428 dm.hideMenu(); 4429 4430 dm = dm.settings.parent; 4431 } 4432 4433 return Event.cancel(e); // Cancel to fix onbeforeunload problem 4434 } 4435 }); 4436 4437 if (t.hasMenus()) { 4438 t.mouseOverFunc = Event.add(co, 'mouseover', function(e) { 4439 var m, r, mi; 4440 4441 e = e.target; 4442 if (e && (e = DOM.getParent(e, 'TR'))) { 4443 m = t.items[e.id]; 4444 4445 if (t.lastMenu) 4446 t.lastMenu.collapse(1); 4447 4448 if (m.isDisabled()) 4449 return; 4450 4451 if (e && DOM.hasClass(e, 'mceMenuItemSub')) { 4452 //p = DOM.getPos(s.container); 4453 r = DOM.getRect(e); 4454 m.showMenu((r.x + r.w - ot), r.y - ot, r.x); 4455 t.lastMenu = m; 4456 DOM.addClass(DOM.get(m.id).firstChild, 'mceMenuItemActive'); 4457 } 4458 } 4459 }); 4460 } 4461 }, 4462 4463 hideMenu : function() { 4464 var t = this, co = DOM.get('menu_' + t.id), e; 4465 4466 if (!t.isMenuVisible) 4467 return; 4468 4469 Event.remove(co, 'mouseover', t.mouseOverFunc); 4470 Event.remove(co, 'click', t.mouseClickFunc); 4471 DOM.hide(co); 4472 t.isMenuVisible = 0; 4473 4474 if (t.element) 4475 t.element.hide(); 4476 4477 if (e = DOM.get(t.id)) 4478 DOM.removeClass(e.firstChild, 'mceMenuItemActive'); 4479 4480 t.onHideMenu.dispatch(t); 4481 }, 4482 4483 add : function(o) { 4484 var t = this, co; 4485 4486 o = t.parent(o); 4487 4488 if (t.isRendered && (co = DOM.get('menu_' + t.id))) 4489 t._add(DOM.select('tbody', co)[0], o); 4490 4491 return o; 4492 }, 4493 4494 collapse : function(d) { 4495 this.parent(d); 4496 this.hideMenu(); 4497 }, 4498 4499 remove : function(o) { 4500 DOM.remove(o.id); 4501 4502 return this.parent(o); 4503 }, 4504 4505 destroy : function() { 4506 var t = this, co = DOM.get('menu_' + t.id); 4507 4508 Event.remove(co, 'mouseover', t.mouseOverFunc); 4509 Event.remove(co, 'click', t.mouseClickFunc); 4510 4511 if (t.element) 4512 t.element.remove(); 4513 4514 DOM.remove(co); 4515 }, 4516 4517 renderNode : function() { 4518 var t = this, s = t.settings, n, tb, co, w; 4519 4520 w = DOM.create('div', {id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:150'}); 4521 co = DOM.add(w, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenu' + (s['class'] ? ' ' + s['class'] : '')}); 4522 t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container}); 4523 4524 if (s.menu_line) 4525 DOM.add(co, 'span', {'class' : 'mceMenuLine'}); 4526 4527 // n = DOM.add(co, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenuContainer'}); 4528 n = DOM.add(co, 'table', {id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0}); 4529 tb = DOM.add(n, 'tbody'); 4530 4531 each(t.items, function(o) { 4532 t._add(tb, o); 4533 }); 4534 4535 t.rendered = true; 4536 4537 return w; 4538 }, 4539 4540 // Internal functions 4541 4542 _add : function(tb, o) { 4543 var n, s = o.settings, a, ro, it; 4544 4545 if (s.separator) { 4546 ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItemSeparator'}); 4547 DOM.add(ro, 'td', {'class' : 'mceMenuItemSeparator'}); 4548 4549 if (n = ro.previousSibling) 4550 DOM.addClass(n, 'last'); 4551 4552 return; 4553 } 4554 4555 n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItem mceMenuItemEnabled'}); 4556 n = it = DOM.add(n, 'td'); 4557 n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'}); 4558 4559 DOM.addClass(it, s['class']); 4560 // n = DOM.add(n, 'span', {'class' : 'item'}); 4561 DOM.add(n, 'span', {'class' : 'icon' + (s.icon ? ' ' + s.icon : '')}); 4562 n = DOM.add(n, s.element || 'span', {'class' : 'text', title : o.settings.title}, o.settings.title); 4563 4564 if (o.settings.style) 4565 DOM.setAttrib(n, 'style', o.settings.style); 4566 4567 if (tb.childNodes.length == 1) 4568 DOM.addClass(ro, 'first'); 4569 4570 if ((n = ro.previousSibling) && DOM.hasClass(n, 'mceMenuItemSeparator')) 4571 DOM.addClass(ro, 'first'); 4572 4573 if (o.collapse) 4574 DOM.addClass(ro, 'mceMenuItemSub'); 4575 4576 if (n = ro.previousSibling) 4577 DOM.removeClass(n, 'last'); 4578 4579 DOM.addClass(ro, 'last'); 4580 } 4581 4582 }); 4583 })(); 4584 /* file:jscripts/tiny_mce/classes/ui/Button.js */ 4585 4586 (function() { 4587 var DOM = tinymce.DOM; 4588 4589 tinymce.create('tinymce.ui.Button:tinymce.ui.Control', { 4590 Button : function(id, s) { 4591 this.parent(id, s); 4592 this.classPrefix = 'mceButton'; 4593 }, 4594 4595 renderHTML : function() { 4596 var s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class'] + '" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">'; 4597 4598 if (s.image) 4599 h += '<img class="icon" src="' + s.image + '" /></a>'; 4600 else 4601 h += '<span class="icon ' + s['class'] + '"></span></a>'; 4602 4603 return h; 4604 }, 4605 4606 postRender : function() { 4607 var t = this, s = t.settings; 4608 4609 tinymce.dom.Event.add(t.id, 'click', function(e) { 4610 if (!t.isDisabled()) 4611 return s.onclick.call(s.scope, e); 4612 }); 4613 } 4614 4615 }); 4616 })(); 4617 4618 /* file:jscripts/tiny_mce/classes/ui/ListBox.js */ 4619 4620 (function() { 4621 var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; 4622 4623 tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', { 4624 ListBox : function(id, s) { 4625 var t = this; 4626 4627 t.parent(id, s); 4628 t.items = []; 4629 t.onChange = new Dispatcher(t); 4630 t.onPostRender = new Dispatcher(t); 4631 t.onAdd = new Dispatcher(t); 4632 t.onRenderMenu = new tinymce.util.Dispatcher(this); 4633 t.classPrefix = 'mceListBox'; 4634 }, 4635 4636 select : function(v) { 4637 var t = this, e, fv; 4638 4639 // Do we need to do something? 4640 if (v != t.selectedValue) { 4641 e = DOM.get(t.id + '_text'); 4642 t.selectedValue = v; 4643 4644 // Find item 4645 each(t.items, function(o) { 4646 if (o.value == v) { 4647 DOM.setHTML(e, DOM.encode(o.title)); 4648 fv = 1; 4649 return false; 4650 } 4651 }); 4652 4653 // If no item was found then present title 4654 if (!fv) { 4655 DOM.setHTML(e, DOM.encode(t.settings.title)); 4656 DOM.addClass(e, 'title'); 4657 e = 0; 4658 return; 4659 } else 4660 DOM.removeClass(e, 'title'); 4661 } 4662 4663 e = 0; 4664 }, 4665 4666 add : function(n, v, o) { 4667 var t = this; 4668 4669 o = o || {}; 4670 o = tinymce.extend(o, { 4671 title : n, 4672 value : v 4673 }); 4674 4675 t.items.push(o); 4676 t.onAdd.dispatch(t, o); 4677 }, 4678 4679 getLength : function() { 4680 return this.items.length; 4681 }, 4682 4683 renderHTML : function() { 4684 var h = '', t = this, s = t.settings; 4685 4686 h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="mceListBox mceListBoxEnabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>'; 4687 h += '<td>' + DOM.createHTML('a', {id : t.id + '_text', href : 'javascript:;', 'class' : 'text', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>'; 4688 h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'open', onclick : "return false;", onmousedown : 'return false;'}, '<span></span>') + '</td>'; 4689 h += '</tr></tbody></table>'; 4690 4691 return h; 4692 }, 4693 4694 showMenu : function() { 4695 var t = this, p1, p2, e = DOM.get(this.id), m; 4696 4697 if (t.isDisabled() || t.items.length == 0) 4698 return; 4699 4700 if (!t.isMenuRendered) { 4701 t.renderMenu(); 4702 t.isMenuRendered = true; 4703 } 4704 4705 p1 = DOM.getPos(this.settings.menu_container); 4706 p2 = DOM.getPos(e); 4707 4708 m = t.menu; 4709 m.settings.offset_x = p2.x; 4710 m.settings.offset_y = p2.y; 4711 4712 // Select in menu 4713 if (t.oldID) 4714 m.items[t.oldID].setSelected(0); 4715 4716 each(t.items, function(o) { 4717 if (o.value === t.selectedValue) { 4718 m.items[o.id].setSelected(1); 4719 t.oldID = o.id; 4720 } 4721 }); 4722 4723 m.showMenu(0, e.clientHeight); 4724 4725 Event.add(document, 'mousedown', t.hideMenu, t); 4726 DOM.addClass(t.id, 'mceListBoxSelected'); 4727 }, 4728 4729 hideMenu : function(e) { 4730 var t = this; 4731 4732 if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) { 4733 DOM.removeClass(t.id, 'mceListBoxSelected'); 4734 Event.remove(document, 'mousedown', t.hideMenu, t); 4735 4736 if (t.menu) 4737 t.menu.hideMenu(); 4738 } 4739 }, 4740 4741 renderMenu : function() { 4742 var t = this, m; 4743 4744 m = t.settings.control_manager.createDropMenu(t.id + '_menu', { 4745 menu_line : 1, 4746 'class' : 'mceListBoxMenu noIcons', 4747 max_width : 150, 4748 max_height : 150 4749 }); 4750 4751 m.onHideMenu.add(t.hideMenu, t); 4752 4753 m.add({ 4754 title : t.settings.title, 4755 'class' : 'mceMenuItemTitle' 4756 }).setDisabled(1); 4757 4758 each(t.items, function(o) { 4759 o.id = DOM.uniqueId(); 4760 o.onclick = function() { 4761 if (t.settings.onselect(o.value) !== false) 4762 t.select(o.value); // Must be runned after 4763 }; 4764 4765 m.add(o); 4766 }); 4767 4768 t.onRenderMenu.dispatch(t, m); 4769 t.menu = m; 4770 }, 4771 4772 postRender : function() { 4773 var t = this; 4774 4775 Event.add(t.id, 'click', t.showMenu, t); 4776 4777 // Old IE doesn't have hover on all elements 4778 if (tinymce.isIE6 || !DOM.boxModel) { 4779 Event.add(t.id, 'mouseover', function() { 4780 if (!DOM.hasClass(t.id, 'mceListBoxDisabled')) 4781 DOM.addClass(t.id, 'mceListBoxHover'); 4782 }); 4783 4784 Event.add(t.id, 'mouseout', function() { 4785 if (!DOM.hasClass(t.id, 'mceListBoxDisabled')) 4786 DOM.removeClass(t.id, 'mceListBoxHover'); 4787 }); 4788 } 4789 4790 t.onPostRender.dispatch(t, DOM.get(t.id)); 4791 } 4792 4793 }); 4794 })(); 4795 /* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */ 4796 4797 (function() { 4798 var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; 4799 4800 tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', { 4801 NativeListBox : function(id, s) { 4802 this.parent(id, s); 4803 this.classPrefix = 'mceNativeListBox'; 4804 }, 4805 4806 setDisabled : function(s) { 4807 DOM.get(this.id).disabled = s; 4808 }, 4809 4810 isDisabled : function() { 4811 return DOM.get(this.id).disabled; 4812 }, 4813 4814 select : function(v) { 4815 var e = DOM.get(this.id), ol = e.options; 4816 4817 v = '' + (v || ''); 4818 4819 e.selectedIndex = 0; 4820 each(ol, function(o, i) { 4821 if (o.value == v) { 4822 e.selectedIndex = i; 4823 return false; 4824 } 4825 }); 4826 }, 4827 4828 add : function(n, v, a) { 4829 var o, t = this; 4830 4831 a = a || {}; 4832 a.value = v; 4833 4834 if (t.isRendered()) 4835 DOM.add(DOM.get(this.id), 'option', a, n); 4836 4837 o = { 4838 title : n, 4839 value : v, 4840 attribs : a 4841 }; 4842 4843 t.items.push(o); 4844 t.onAdd.dispatch(t, o); 4845 }, 4846 4847 getLength : function() { 4848 return DOM.get(this.id).options.length - 1; 4849 }, 4850 4851 renderHTML : function() { 4852 var h, t = this; 4853 4854 h = DOM.createHTML('option', {value : ''}, '-- ' + t.settings.title + ' --'); 4855 4856 each(t.items, function(it) { 4857 h += DOM.createHTML('option', {value : it.value}, it.title); 4858 }); 4859 4860 h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox'}, h); 4861 4862 return h; 4863 }, 4864 4865 postRender : function() { 4866 var t = this, ch; 4867 4868 t.rendered = true; 4869 4870 function onChange(e) { 4871 var v = e.target.options[e.target.selectedIndex].value; 4872 4873 t.onChange.dispatch(t, v); 4874 4875 if (t.settings.onselect) 4876 t.settings.onselect(v); 4877 }; 4878 4879 Event.add(t.id, 'change', onChange); 4880 4881 // Accessibility keyhandler 4882 Event.add(t.id, 'keydown', function(e) { 4883 var bf; 4884 4885 Event.remove(t.id, 'change', ch); 4886 4887 bf = Event.add(t.id, 'blur', function() { 4888 Event.add(t.id, 'change', onChange); 4889 Event.remove(t.id, 'blur', bf); 4890 }); 4891 4892 if (e.keyCode == 13 || e.keyCode == 32) { 4893 onChange(e); 4894 return Event.cancel(e); 4895 } 4896 }); 4897 4898 t.onPostRender.dispatch(t, DOM.get(t.id)); 4899 } 4900 4901 }); 4902 })(); 4903 /* file:jscripts/tiny_mce/classes/ui/MenuButton.js */ 4904 4905 (function() { 4906 var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each; 4907 4908 tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', { 4909 MenuButton : function(id, s) { 4910 this.parent(id, s); 4911 this.onRenderMenu = new tinymce.util.Dispatcher(this); 4912 s.menu_container = s.menu_container || document.body; 4913 }, 4914 4915 showMenu : function() { 4916 var t = this, p1, p2, e = DOM.get(t.id), m; 4917 4918 if (t.isDisabled()) 4919 return; 4920 4921 if (!t.isMenuRendered) { 4922 t.renderMenu(); 4923 t.isMenuRendered = true; 4924 } 4925 4926 p1 = DOM.getPos(t.settings.menu_container); 4927 p2 = DOM.getPos(e); 4928 4929 m = t.menu; 4930 m.settings.offset_x = p2.x; 4931 m.settings.offset_y = p2.y; 4932 m.settings.vp_offset_x = p2.x; 4933 m.settings.vp_offset_y = p2.y; 4934 m.showMenu(0, e.clientHeight); 4935 4936 Event.add(document, 'mousedown', t.hideMenu, t); 4937 t.setState('Selected', 1); 4938 }, 4939 4940 renderMenu : function() { 4941 var t = this, m; 4942 4943 m = t.settings.control_manager.createDropMenu(t.id + '_menu', { 4944 menu_line : 1, 4945 'class' : this.classPrefix + 'Menu' 4946 }); 4947 4948 m.onHideMenu.add(t.hideMenu, t); 4949 4950 t.onRenderMenu.dispatch(t, m); 4951 t.menu = m; 4952 }, 4953 4954 hideMenu : function(e) { 4955 var t = this; 4956 4957 if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) { 4958 t.setState('Selected', 0); 4959 Event.remove(document, 'mousedown', t.hideMenu, t); 4960 if (t.menu) 4961 t.menu.hideMenu(); 4962 } 4963 }, 4964 4965 postRender : function() { 4966 var t = this, s = t.settings; 4967 4968 Event.add(t.id, 'click', function() { 4969 if (!t.isDisabled()) { 4970 if (s.onclick) 4971 s.onclick(t.value); 4972 4973 t.showMenu(); 4974 } 4975 }); 4976 } 4977 4978 }); 4979 })(); 4980 4981 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */ 4982 4983 (function() { 4984 var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each; 4985 4986 tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', { 4987 SplitButton : function(id, s) { 4988 this.parent(id, s); 4989 this.classPrefix = 'mceSplitButton'; 4990 }, 4991 4992 renderHTML : function() { 4993 var h, t = this, s = t.settings, h1; 4994 4995 h = '<tbody><tr>'; 4996 4997 if (s.image) 4998 h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'action ' + s['class']}); 4999 else 5000 h1 = DOM.createHTML('span', {'class' : 'action ' + s['class']}); 5001 5002 h += '<td>' + DOM.createHTML('a', {id : t.id + '_action', href : 'javascript:;', 'class' : 'action ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>'; 5003 5004 h1 = DOM.createHTML('span', {'class' : 'open ' + s['class']}); 5005 h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'open ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>'; 5006 5007 h += '</tr></tbody>'; 5008 5009 return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h); 5010 }, 5011 5012 postRender : function() { 5013 var t = this, s = t.settings; 5014 5015 if (s.onclick) { 5016 Event.add(t.id + '_action', 'click', function() { 5017 if (!t.isDisabled()) 5018 s.onclick(t.value); 5019 }); 5020 } 5021 5022 Event.add(t.id + '_open', 'click', t.showMenu, t); 5023 5024 // Old IE doesn't have hover on all elements 5025 if (tinymce.isIE6 || !DOM.boxModel) { 5026 Event.add(t.id, 'mouseover', function() { 5027 if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled')) 5028 DOM.addClass(t.id, 'mceSplitButtonHover'); 5029 }); 5030 5031 Event.add(t.id, 'mouseout', function() { 5032 if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled')) 5033 DOM.removeClass(t.id, 'mceSplitButtonHover'); 5034 }); 5035 } 5036 } 5037 5038 }); 5039 })(); 5040 5041 /* file:jscripts/tiny_mce/classes/ui/ColorSplitButton.js */ 5042 5043 (function() { 5044 var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each; 5045 5046 tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', { 5047 ColorSplitButton : function(id, s) { 5048 var t = this; 5049 5050 t.parent(id, s); 5051 5052 t.settings = s = tinymce.extend({ 5053 colors : '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF', 5054 grid_width : 8, 5055 default_color : '#888888' 5056 }, t.settings); 5057 5058 t.value = s.default_color; 5059 }, 5060 5061 showMenu : function() { 5062 var t = this, r, p, e; 5063 5064 if (t.isDisabled()) 5065 return; 5066 5067 if (!t.isMenuRendered) { 5068 t.renderMenu(); 5069 t.isMenuRendered = true; 5070 } 5071 5072 e = DOM.get(t.id); 5073 DOM.show(t.id + '_menu'); 5074 DOM.addClass(e, 'mceSplitButtonSelected'); 5075 p2 = DOM.getPos(e); 5076 DOM.setStyles(t.id + '_menu', { 5077 left : p2.x, 5078 top : p2.y + e.clientHeight, 5079 zIndex : 150 5080 }); 5081 e = 0; 5082 5083 Event.add(document, 'mousedown', t.hideMenu, t); 5084 }, 5085 5086 hideMenu : function(e) { 5087 var t = this; 5088 5089 if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) { 5090 DOM.removeClass(t.id, 'mceSplitButtonSelected'); 5091 Event.remove(document, 'mousedown', t.hideMenu, t); 5092 DOM.hide(t.id + '_menu'); 5093 } 5094 }, 5095 5096 renderMenu : function() { 5097 var t = this, m, i = 0, s = t.settings, n, tb, tr, w; 5098 5099 w = DOM.add(s.menu_container, 'div', {id : t.id + '_menu', 'class' : s['menu_class'] + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'}); 5100 m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'}); 5101 DOM.add(m, 'span', {'class' : 'mceMenuLine'}); 5102 5103 n = DOM.add(m, 'table', {'class' : 'mceColorSplitMenu'}); 5104 tb = DOM.add(n, 'tbody'); 5105 5106 // Generate color grid 5107 i = 0; 5108 each(is(s.colors, 'array') ? s.colors : s.colors.split(','), function(c) { 5109 c = c.replace(/^#/, ''); 5110 5111 if (!i--) { 5112 tr = DOM.add(tb, 'tr'); 5113 i = s.grid_width - 1; 5114 } 5115 5116 n = DOM.add(tr, 'td'); 5117 5118 n = DOM.add(n, 'a', { 5119 href : 'javascript:;', 5120 style : { 5121 backgroundColor : '#' + c 5122 } 5123 }); 5124 5125 Event.add(n, 'mousedown', function() { 5126 t.setColor('#' + c); 5127 }); 5128 }); 5129 5130 if (s.more_colors_func) { 5131 n = DOM.add(tb, 'tr'); 5132 n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'morecolors'}); 5133 n = DOM.add(n, 'a', {href : 'javascript:;', onclick : 'return false;', 'class' : 'morecolors'}, s.more_colors_title); 5134 5135 Event.add(n, 'click', function(e) { 5136 s.more_colors_func.call(s.more_colors_scope || this); 5137 return Event.cancel(e); // Cancel to fix onbeforeunload problem 5138 }); 5139 } 5140 5141 DOM.addClass(m, 'mceColorSplitMenu'); 5142 5143 return w; 5144 }, 5145 5146 setColor : function(c) { 5147 var t = this, p, s = this.settings, co = s.menu_container, po, cp, id = t.id + '_preview'; 5148 5149 if (!(p = DOM.get(id))) { 5150 DOM.setStyle(t.id + '_action', 'position', 'relative'); 5151 p = DOM.add(t.id + '_action', 'div', {id : id, 'class' : 'mceColorPreview'}); 5152 } 5153 5154 p.style.backgroundColor = c; 5155 5156 t.value = c; 5157 t.hideMenu(); 5158 s.onselect(c); 5159 } 5160 5161 }); 5162 })(); 5163 5164 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */ 5165 5166 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 5167 renderHTML : function() { 5168 var t = this, h = '', c = 'mceToolbarEnd', co, dom = tinymce.DOM, s = t.settings; 5169 5170 h += dom.createHTML('td', {'class' : 'mceToolbarStart'}, dom.createHTML('span', null, '<!-- IE -->')); 5171 5172 tinymce.each(t.controls, function(c) { 5173 h += '<td>' + c.renderHTML() + '</td>'; 5174 }); 5175 5176 co = t.controls[t.controls.length - 1].constructor; 5177 5178 if (co === tinymce.ui.Button) 5179 c += ' mceToolbarEndButton'; 5180 else if (co === tinymce.ui.SplitButton) 5181 c += ' mceToolbarEndSplitButton'; 5182 else if (co === tinymce.ui.ListBox) 5183 c += ' mceToolbarEndListBox'; 5184 5185 h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->')); 5186 5187 return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || ''}, '<tbody><tr>' + h + '</tr></tbody>'); 5188 } 5189 5190 }); 5191 5192 /* file:jscripts/tiny_mce/classes/AddOnManager.js */ 5193 5194 (function() { 5195 var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each; 5196 5197 tinymce.create('tinymce.AddOnManager', { 5198 items : [], 5199 urls : {}, 5200 lookup : {}, 5201 onAdd : new Dispatcher(this), 5202 5203 get : function(n) { 5204 return this.lookup[n]; 5205 }, 5206 5207 requireLangPack : function(n) { 5208 var u, s; 5209 5210 if (tinymce.EditorManager.settings) { 5211 u = this.urls[n] + '/langs/' + tinymce.EditorManager.settings.language + '.js'; 5212 s = tinymce.EditorManager.settings; 5213 5214 if (s) { 5215 if (!tinymce.dom.Event.domLoaded && !s.strict_mode) 5216 tinymce.ScriptLoader.load(u); 5217 else 5218 tinymce.ScriptLoader.add(u); 5219 } 5220 } 5221 }, 5222 5223 add : function(id, o) { 5224 this.items.push(o); 5225 this.lookup[id] = o; 5226 this.onAdd.dispatch(this, id, o); 5227 5228 return o; 5229 }, 5230 5231 load : function(n, u, cb, s) { 5232 if (u.indexOf('/') != 0 && u.indexOf('://') == -1) 5233 u = tinymce.baseURL + '/' + u; 5234 5235 this.urls[n] = u.substring(0, u.lastIndexOf('/')); 5236 tinymce.ScriptLoader.add(u, cb, s); 5237 } 5238 5239 }); 5240 5241 // Create plugin and theme managers 5242 tinymce.PluginManager = new tinymce.AddOnManager(); 5243 tinymce.ThemeManager = new tinymce.AddOnManager(); 5244 }()); 5245 /* file:jscripts/tiny_mce/classes/EditorManager.js */ 5246 5247 (function() { 5248 // Shorten names 5249 var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager; 5250 5251 tinymce.create('static tinymce.EditorManager', { 5252 editors : {}, 5253 i18n : {}, 5254 activeEditor : null, 5255 5256 init : function(s) { 5257 var t = this, pl, sl = tinymce.ScriptLoader; 5258 5259 function execCallback(se, n, s) { 5260 var f = se[n]; 5261 5262 if (!f) 5263 return; 5264 5265 if (tinymce.is(f, 'string')) { 5266 s = f.replace(/\.\w+$/, ''); 5267 s = s ? tinymce.resolve(s) : 0; 5268 f = tinymce.resolve(f); 5269 } 5270 5271 return f.apply(s || this, Array.prototype.slice.call(arguments, 2)); 5272 }; 5273 5274 s = extend({ 5275 theme : "simple", 5276 language : "en", 5277 strict_loading_mode : document.contentType == 'application/xhtml+xml' 5278 }, s); 5279 5280 t.settings = s; 5281 5282 // If page not loaded and strict mode isn't enabled then load them 5283 if (!Event.domLoaded && !s.strict_loading_mode) { 5284 // Load language 5285 if (s.language) 5286 sl.add(tinymce.baseURL + '/langs/' + s.language + '.js'); 5287 5288 // Load theme 5289 if (s.theme && s.theme.charAt(0) != '-') 5290 ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js'); 5291 5292 // Load plugins 5293 if (s.plugins) { 5294 pl = s.plugins.split(','); 5295 5296 // Load compat2x first 5297 if (tinymce.inArray(pl, 'compat2x') != -1) 5298 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js'); 5299 5300 // Load rest if plugins 5301 each(pl, function(v) { 5302 if (v && v.charAt(0) != '-') { 5303 // Skip safari plugin for other browsers 5304 if (!tinymce.isWebKit && v == 'safari') 5305 return; 5306 5307 PluginManager.load(v, 'plugins/' + v + '/editor_plugin' + tinymce.suffix + '.js'); 5308 } 5309 }); 5310 } 5311 5312 sl.loadQueue(); 5313 } 5314 5315 // Legacy call 5316 Event.add(document, 'init', function() { 5317 var l, co; 5318 5319 execCallback(s, 'onpageload'); 5320 5321 // Verify that it's a valid browser 5322 if (s.browsers) { 5323 l = false; 5324 5325 each(s.browsers.split(','), function(v) { 5326 switch (v) { 5327 case 'ie': 5328 case 'msie': 5329 if (tinymce.isIE) 5330 l = true; 5331 break; 5332 5333 case 'gecko': 5334 if (tinymce.isGecko) 5335 l = true; 5336 break; 5337 5338 case 'safari': 5339 case 'webkit': 5340 if (tinymce.isWebKit) 5341 l = true; 5342 break; 5343 5344 case 'opera': 5345 if (tinymce.isOpera) 5346 l = true; 5347 5348 break; 5349 } 5350 }); 5351 5352 // Not a valid one 5353 if (!l) 5354 return; 5355 } 5356 5357 switch (s.mode) { 5358 case "exact": 5359 l = s.elements || ''; 5360 each(l.split(','), function(v) { 5361 new tinymce.Editor(v, s).render(); 5362 }); 5363 break; 5364 5365 case "textareas": 5366 function hasClass(n, c) { 5367 return new RegExp('\\b' + c + '\\b', 'g').test(n.className); 5368 }; 5369 5370 each(DOM.select('textarea'), function(v) { 5371 if (s.editor_deselector && hasClass(v, s.editor_deselector)) 5372 return; 5373 5374 if (!s.editor_selector || hasClass(v, s.editor_selector)) 5375 new tinymce.Editor(v.id = (v.id || v.name || (v.id = DOM.uniqueId())), s).render(); 5376 }); 5377 break; 5378 } 5379 5380 // Call onInit when all editors are initialized 5381 if (s.oninit) { 5382 l = co = 0; 5383 5384 each (t.editors, function(ed) { 5385 co++; 5386 5387 if (!ed.initialized) { 5388 // Wait for it 5389 ed.onInit.add(function() { 5390 l++; 5391 5392 // All done 5393 if (l == co) 5394 execCallback(s, 'oninit'); 5395 }); 5396 } else 5397 l++; 5398 5399 // All done 5400 if (l == co) 5401 execCallback(s, 'oninit'); 5402 }); 5403 } 5404 }); 5405 }, 5406 5407 get : function(id) { 5408 return this.editors[id]; 5409 }, 5410 5411 getInstanceById : function(id) { 5412 return this.get(id); 5413 }, 5414 5415 add : function(e) { 5416 this.editors[e.id] = e; 5417 this._setActive(e); 5418 5419 return e; 5420 }, 5421 5422 remove : function(e) { 5423 var t = this; 5424 5425 // Not in the collection 5426 if (!t.editors[e.id]) 5427 return null; 5428 5429 delete t.editors[e.id]; 5430 5431 // Select another editor since the active one was removed 5432 if (t.activeEditor == e) { 5433 each(t.editors, function(e) { 5434 t._setActive(e); 5435 return false; // Break 5436 }); 5437 } 5438 5439 e._destroy(); 5440 5441 return e; 5442 }, 5443 5444 execCommand : function(c, u, v) { 5445 var t = this, ed = t.get(v); 5446 5447 // Manager commands 5448 switch (c) { 5449 case "mceFocus": 5450 ed.focus(); 5451 return true; 5452 5453 case "mceAddEditor": 5454 case "mceAddControl": 5455 new tinymce.Editor(v, t.settings).render(); 5456 return true; 5457 5458 case "mceAddFrameControl": 5459 // TODO: Implement this 5460 return true; 5461 5462 case "mceRemoveEditor": 5463 case "mceRemoveControl": 5464 ed.remove(); 5465 return true; 5466 5467 case 'mceToggleEditor': 5468 if (!ed) { 5469 t.execCommand('mceAddControl', 0, v); 5470 return true; 5471 } 5472 5473 if (ed.isHidden()) 5474 ed.show(); 5475 else 5476 ed.hide(); 5477 5478 return true; 5479 } 5480 5481 // Run command on active editor 5482 if (t.activeEditor) 5483 return t.activeEditor.execCommand(c, u, v); 5484 6450 5485 return false; 6451 6452 if (tinyMCE.isSafari && bookmark.rng) { 6453 sel.setBaseAndExtent(bookmark.rng.startContainer, bookmark.rng.startOffset, bookmark.rng.endContainer, bookmark.rng.endOffset); 5486 }, 5487 5488 execInstanceCommand : function(id, c, u, v) { 5489 var ed = this.get(id); 5490 5491 if (ed) 5492 return ed.execCommand(c, u, v); 5493 5494 return false; 5495 }, 5496 5497 triggerSave : function() { 5498 each(this.editors, function(e) { 5499 e.save(); 5500 }); 5501 }, 5502 5503 addI18n : function(p, o) { 5504 var lo, i18n = this.i18n; 5505 5506 if (!tinymce.is(p, 'string')) { 5507 each(p, function(o, lc) { 5508 each(o, function(o, g) { 5509 each(o, function(o, k) { 5510 if (g === 'common') 5511 i18n[lc + '.' + k] = o; 5512 else 5513 i18n[lc + '.' + g + '.' + k] = o; 5514 }); 5515 }); 5516 }); 5517 } else { 5518 each(o, function(o, k) { 5519 i18n[p + '.' + k] = o; 5520 }); 5521 } 5522 }, 5523 5524 // Private methods 5525 5526 _setActive : function(e) { 5527 this.selectedInstance = this.activeEditor = e; 5528 } 5529 5530 }); 5531 5532 // Setup some URLs where the editor API is located and where the document is 5533 tinymce.documentBaseURL = window.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); 5534 if (!/[\/\\]$/.test(tinymce.documentBaseURL)) 5535 tinymce.documentBaseURL += '/'; 5536 5537 tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL); 5538 tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL); 5539 })(); 5540 5541 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call 5542 var tinyMCE = window.tinyMCE = tinymce.EditorManager; 5543 5544 /* file:jscripts/tiny_mce/classes/Editor.js */ 5545 5546 (function() { 5547 var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher; 5548 var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit; 5549 var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager; 5550 var inArray = tinymce.inArray, grep = tinymce.grep; 5551 5552 tinymce.create('tinymce.Editor', { 5553 Editor : function(id, s) { 5554 var t = this; 5555 5556 t.id = t.editorId = id; 5557 t.execCommands = {}; 5558 t.queryStateCommands = {}; 5559 t.queryValueCommands = {}; 5560 t.plugins = {}; 5561 5562 // Add events to the editor 5563 each([ 5564 'onPreInit', 5565 'onBeforeRenderUI', 5566 'onPostRender', 5567 'onInit', 5568 'onRemove', 5569 'onActivate', 5570 'onDeactivate', 5571 'onClick', 5572 'onEvent', 5573 'onMouseUp', 5574 'onMouseDown', 5575 'onDblClick', 5576 'onKeyDown', 5577 'onKeyUp', 5578 'onKeyPress', 5579 'onContextMenu', 5580 'onSubmit', 5581 'onReset', 5582 'onPaste', 5583 'onPreProcess', 5584 'onPostProcess', 5585 'onBeforeSetContent', 5586 'onBeforeGetContent', 5587 'onSetContent', 5588 'onGetContent', 5589 'onLoadContent', 5590 'onSaveContent', 5591 'onNodeChange', 5592 'onChange', 5593 'onBeforeExecCommand', 5594 'onExecCommand', 5595 'onUndo', 5596 'onRedo', 5597 'onVisualAid', 5598 'onSetProgressState' 5599 ], function(e) { 5600 t[e] = new Dispatcher(t); 5601 }); 5602 5603 // Default editor config 5604 t.settings = s = extend({ 5605 id : id, 5606 language : 'en', 5607 docs_language : 'en', 5608 theme : 'simple', 5609 skin : 'default', 5610 delta_width : 0, 5611 delta_height : 0, 5612 popup_css : '', 5613 plugins : '', 5614 document_base_url : tinymce.documentBaseURL, 5615 add_form_submit_trigger : 1, 5616 submit_patch : 1, 5617 add_unload_trigger : 1, 5618 convert_urls : 1, 5619 relative_urls : 1, 5620 remove_script_host : 1, 5621 table_inline_editing : 0, 5622 object_resizing : 1, 5623 cleanup : 1, 5624 accessibility_focus : 1, 5625 custom_shortcuts : 1, 5626 custom_undo_redo_keyboard_shortcuts : 1, 5627 custom_undo_redo_restore_selection : 1, 5628 custom_undo_redo : 1, 5629 doctype : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', 5630 visual_table_class : 'mceItemTable', 5631 visual : 1, 5632 inline_styles : true, 5633 convert_fonts_to_spans : true, 5634 font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', 5635 apply_source_formatting : 1, 5636 directionality : 'ltr', 5637 forced_root_block : 'p', 5638 valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],script[type]', 5639 hidden_input : 1, 5640 padd_empty_editor : 1, 5641 render_ui : 1, 5642 init_theme : 1, 5643 indentation : '30px' 5644 }, s); 5645 5646 // Setup URIs 5647 t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, { 5648 base_uri : tinyMCE.baseURI 5649 }); 5650 t.baseURI = EditorManager.baseURI; 5651 5652 // Call setup 5653 t.execCallback('setup', t); 5654 }, 5655 5656 render : function() { 5657 var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader; 5658 5659 // Element not found, then skip initialization 5660 if (!t.getElement()) 5661 return; 5662 5663 if (s.strict_loading_mode) { 5664 sl.settings.strict_mode = s.strict_loading_mode; 5665 tinymce.DOM.settings.strict = 1; 5666 } 5667 5668 // Add hidden input for non input elements inside form elements 5669 if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form')) 5670 DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id); 5671 5672 t.windowManager = new tinymce.WindowManager(t); 5673 5674 if (s.encoding == 'xml') { 5675 t.onGetContent.add(function(ed, o) { 5676 if (o.get) 5677 o.content = DOM.encode(o.content); 5678 }); 5679 } 5680 5681 if (s.add_form_submit_trigger) { 5682 t.onSubmit.addToTop(function() { 5683 if (t.initialized) { 5684 t.save(); 5685 t.isNotDirty = 1; 5686 } 5687 }); 5688 } 5689 5690 Event.add(document, 'unload', function() { 5691 if (t.initialized && !t.destroyed && s.add_unload_trigger) 5692 t.save({format : 'raw', no_events : true}); 5693 }); 5694 5695 tinymce.addUnload(t._destroy, t); 5696 5697 if (s.submit_patch) { 5698 t.onBeforeRenderUI.add(function() { 5699 var n = t.getElement().form; 5700 5701 if (!n) 5702 return; 5703 5704 // Already patched 5705 if (n._mceOldSubmit) 5706 return; 5707 5708 // Check page uses id="submit" or name="submit" for it's submit button 5709 if (!n.submit.nodeType) { 5710 t.formElement = n; 5711 n._mceOldSubmit = n.submit; 5712 n.submit = function() { 5713 // Save all instances 5714 EditorManager.triggerSave(); 5715 t.isNotDirty = 1; 5716 5717 return this._mceOldSubmit(this); 5718 }; 5719 } 5720 5721 n = null; 5722 }); 5723 } 5724 5725 // Load scripts 5726 function loadScripts() { 5727 sl.add(tinymce.baseURL + '/langs/' + s.language + '.js'); 5728 5729 if (s.theme.charAt(0) != '-') 5730 ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js'); 5731 5732 each(s.plugins.split(','), function(p) { 5733 if (p && p.charAt(0) != '-') { 5734 // Skip safari plugin for other browsers 5735 if (!isWebKit && p == 'safari') 5736 return; 5737 5738 PluginManager.load(p, 'plugins/' + p + '/editor_plugin' + tinymce.suffix + '.js'); 5739 } 5740 }); 5741 5742 // Init when que is loaded 5743 sl.loadQueue(function() { 5744 if (s.ask) { 5745 function ask() { 5746 t.windowManager.confirm(t.getLang('edit_confirm'), function(s) { 5747 if (s) 5748 t.init(); 5749 else 5750 Event.remove(t.id, 'focus', ask); 5751 }); 5752 }; 5753 5754 Event.add(t.id, 'focus', ask); 5755 return; 5756 } 5757 5758 if (!t.removed) 5759 t.init(); 5760 }); 5761 }; 5762 5763 // Load compat2x first 5764 if (s.plugins.indexOf('compat2x') != -1) { 5765 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js'); 5766 sl.loadQueue(loadScripts); 5767 } else 5768 loadScripts(); 5769 }, 5770 5771 init : function() { 5772 var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti; 5773 5774 EditorManager.add(t); 5775 5776 // Create theme 5777 s.theme = s.theme.replace(/-/, ''); 5778 o = ThemeManager.get(s.theme); 5779 t.theme = new o(); 5780 5781 if (t.theme.init && s.init_theme) 5782 t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, '')); 5783 5784 // Create all plugins 5785 each(s.plugins.replace(/\-/g, '').split(','), function(p) { 5786 var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po; 5787 5788 if (c) { 5789 po = new c(t, u); 5790 5791 t.plugins[p] = po; 5792 5793 if (po.init) 5794 po.init(t, u); 5795 } 5796 }); 5797 5798 // Setup popup CSS path(s) 5799 s.popup_css = t.baseURI.toAbsolute(s.popup_css || "themes/" + s.theme + "/skins/" + s.skin + "/dialog.css"); 5800 5801 if (s.popup_css_add) 5802 s.popup_css += ',' + s.popup_css_add; 5803 5804 // Setup control factory 5805 t.controlManager = new tinymce.ControlManager(t); 5806 t.undoManager = new tinymce.UndoManager(t); 5807 5808 // Pass through 5809 t.undoManager.onAdd.add(function(um, l) { 5810 return t.onChange.dispatch(t, l, um); 5811 }); 5812 5813 t.undoManager.onUndo.add(function(um, l) { 5814 return t.onUndo.dispatch(t, l, um); 5815 }); 5816 5817 t.undoManager.onRedo.add(function(um, l) { 5818 return t.onRedo.dispatch(t, l, um); 5819 }); 5820 5821 if (s.custom_undo_redo) { 5822 t.onExecCommand.add(function(ed, cmd) { 5823 if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint') 5824 t.undoManager.add(); 5825 }); 5826 } 5827 5828 t.onExecCommand.add(function(ed, c) { 5829 // Don't refresh the select lists until caret move 5830 if (!/^(FontName|FontSize)$/.test(c)) 5831 t.nodeChanged(); 5832 }); 5833 5834 // Remove ghost selections on images and tables in Gecko 5835 if (isGecko) { 5836 function repaint() { 5837 t.execCommand('mceRepaint'); 5838 }; 5839 5840 t.onUndo.add(repaint); 5841 t.onRedo.add(repaint); 5842 t.onSetContent.add(repaint); 5843 } 5844 5845 // Enables users to override the control factory 5846 t.onBeforeRenderUI.dispatch(t, t.controlManager); 5847 5848 // Measure box 5849 if (s.render_ui) { 5850 w = s.width || e.style.width || e.clientWidth; 5851 h = s.height || e.style.height || e.clientHeight; 5852 t.orgDisplay = e.style.display; 5853 5854 if (('' + w).indexOf('%') == -1) 5855 w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100); 5856 5857 if (('' + h).indexOf('%') == -1) 5858 h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100); 5859 5860 // Render UI 5861 o = t.theme.renderUI({ 5862 targetNode : e, 5863 width : w, 5864 height : h, 5865 deltaWidth : s.delta_width, 5866 deltaHeight : s.delta_height 5867 }); 5868 5869 t.editorContainer = o.editorContainer; 5870 } 5871 5872 5873 // Resize editor 5874 DOM.setStyles(o.sizeContainer || o.editorContainer, { 5875 width : w, 5876 height : h 5877 }); 5878 5879 h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : ''); 5880 if (h < 100) 5881 h = 100; 5882 5883 // Create iframe 5884 n = DOM.add(o.iframeContainer, 'iframe', { 5885 id : s.id + "_ifr", 5886 src : 'javascript:""', // Workaround for HTTPS warning in IE6/7 5887 frameBorder : '0', 5888 style : { 5889 width : '100%', 5890 height : h 5891 } 5892 }); 5893 5894 t.contentAreaContainer = o.iframeContainer; 5895 DOM.get(o.editorContainer).style.display = t.orgDisplay; 5896 DOM.get(s.id).style.display = 'none'; 5897 5898 // Safari 2.x requires us to wait for the load event and load a real HTML doc 5899 if (tinymce.isOldWebKit) { 5900 Event.add(n, 'load', t.setupIframe, t); 5901 n.src = tinymce.baseURL + '/plugins/safari/blank.htm'; 5902 } else { 5903 t.setupIframe(); 5904 e = n = o = null; // Cleanup 5905 } 5906 5907 /* function createIfr() { 5908 h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : ''); 5909 if (h < 100) 5910 h = 100; 5911 5912 // Create iframe 5913 n = DOM.add(o.iframeContainer, 'iframe', { 5914 id : s.id + "_ifr", 5915 src : 'javascript:""', // Workaround for HTTPS warning in IE6/7 5916 frameBorder : '0', 5917 style : { 5918 width : '100%', 5919 height : h 5920 } 5921 }); 5922 5923 t.contentAreaContainer = o.iframeContainer; 5924 DOM.get(o.editorContainer).style.display = t.orgDisplay; 5925 DOM.get(s.id).style.display = 'none'; 5926 5927 // Safari 2.x requires us to wait for the load event and load a real HTML doc 5928 if (tinymce.isOldWebKit) { 5929 Event.add(n, 'load', t.setupIframe, t); 5930 n.src = tinymce.baseURL + '/plugins/safari/blank.htm'; 5931 } else { 5932 t.setupIframe(); 5933 e = n = o = null; // Cleanup 5934 } 5935 }; 5936 */ 5937 // Waits for the editor to become visible, then it will run the init 5938 // This method is somewhat ugly but this is the best way to deal with it without 5939 // forcing the user to add some logic to their application. 5940 /* if (isGecko) { 5941 function check() { 5942 var hi; 5943 5944 DOM.getParent(t.id, function(e) { 5945 if (DOM.getStyle(e, 'display', true) == 'none') { 5946 hi = 1; 5947 return true; 5948 } 5949 }); 5950 5951 return hi; 5952 }; 5953 5954 if (check()) { 5955 ti = window.setInterval(function() { 5956 if (!check()) { 5957 createIfr(); 5958 window.clearInterval(ti); 5959 } 5960 }, 300); 5961 5962 return; 5963 } 5964 } 5965 5966 createIfr(); 5967 */ 5968 }, 5969 5970 setupIframe : function() { 5971 var t = this, s = t.settings, e = DOM.get(s.id), d = t.getDoc(); 5972 5973 // Setup body 5974 d.open(); 5975 d.write(s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body id="tinymce" class="mceContentBody"></body></html>'); 5976 d.close(); 5977 5978 // Design mode needs to be added here Ctrl+A will fail otherwise 5979 if (!isIE) { 5980 try { 5981 d.designMode = 'On'; 5982 } catch (ex) { 5983 // Will fail on Gecko if the editor is placed in an hidden container element 5984 // The design mode will be set ones the editor is focused 5985 } 5986 } 5987 5988 // IE needs to use contentEditable or it will display non secure items for HTTPS 5989 if (isIE) 5990 t.getBody().contentEditable = true; 5991 5992 // Setup objects 5993 t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), { 5994 keep_values : true, 5995 url_converter : t.convertURL, 5996 url_converter_scope : t, 5997 hex_colors : s.force_hex_style_colors, 5998 class_filter : s.class_filter, 5999 update_styles : 1 6000 }); 6001 6002 t.serializer = new tinymce.dom.Serializer({ 6003 entity_encoding : s.entity_encoding, 6004 entities : s.entities, 6005 valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements, 6006 extended_valid_elements : s.extended_valid_elements, 6007 valid_child_elements : s.valid_child_elements, 6008 invalid_elements : s.invalid_elements, 6009 fix_table_elements : s.fix_table_elements, 6010 fix_list_elements : s.fix_list_elements, 6011 fix_content_duplication : s.fix_content_duplication, 6012 convert_fonts_to_spans : s.convert_fonts_to_spans, 6013 font_size_classes : s.font_size_classes, 6014 font_size_style_values : s.font_size_style_values, 6015 apply_source_formatting : s.apply_source_formatting, 6016 remove_linebreaks : s.remove_linebreaks, 6017 dom : t.dom 6018 }); 6019 6020 t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer); 6021 t.forceBlocks = new tinymce.ForceBlocks(t, { 6022 forced_root_block : s.forced_root_block 6023 }); 6024 t.editorCommands = new tinymce.EditorCommands(t); 6025 6026 // Pass through 6027 t.serializer.onPreProcess.add(function(se, o) { 6028 return t.onPreProcess.dispatch(t, o, se); 6029 }); 6030 6031 t.serializer.onPostProcess.add(function(se, o) { 6032 return t.onPostProcess.dispatch(t, o, se); 6033 }); 6034 6035 t.onPreInit.dispatch(t); 6036 6037 if (!s.gecko_spellcheck) 6038 t.getBody().spellcheck = 0; 6039 6040 t._addEvents(); 6041 6042 t.controlManager.onPostRender.dispatch(t, t.controlManager); 6043 t.onPostRender.dispatch(t); 6044 6045 if (s.directionality) 6046 t.getBody().dir = s.directionality; 6047 6048 if (s.nowrap) 6049 t.getBody().style.whiteSpace = "nowrap"; 6050 6051 if (s.auto_resize) 6052 t.onNodeChange.add(t.resizeToContent, t); 6053 6054 if (s.handle_node_change_callback) { 6055 t.onNodeChange.add(function(ed, cm, n) { 6056 t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed()); 6057 }); 6058 } 6059 6060 if (s.save_callback) { 6061 t.onSaveContent.add(function(ed, o) { 6062 var h = t.execCallback('save_callback', t.id, o.content, t.getBody()); 6063 6064 if (h) 6065 o.content = h; 6066 }); 6067 } 6068 6069 if (s.onchange_callback) { 6070 t.onChange.add(function(ed, l) { 6071 t.execCallback('onchange_callback', t, l); 6072 }); 6073 } 6074 6075 if (s.convert_newlines_to_brs) { 6076 t.onBeforeSetContent.add(function(ed, o) { 6077 if (o.initial) 6078 o.content = o.content.replace(/\r?\n/g, '<br />'); 6079 }); 6080 } 6081 6082 if (s.fix_nesting && isIE) { 6083 t.onBeforeSetContent.add(function(ed, o) { 6084 o.content = t._fixNesting(o.content); 6085 }); 6086 } 6087 6088 if (s.preformatted) { 6089 t.onPostProcess.add(function(ed, o) { 6090 o.content = o.content.replace(/^\s*<pre.*?>/, ''); 6091 o.content = o.content.replace(/<\/pre>\s*$/, ''); 6092 6093 if (o.set) 6094 o.content = '<pre class="mceItemHidden">' + o.content + '</pre>'; 6095 }); 6096 } 6097 6098 if (s.verify_css_classes) { 6099 t.serializer.attribValueFilter = function(n, v) { 6100 var s, cl; 6101 6102 if (n == 'class') { 6103 // Build regexp for classes 6104 if (!t.classesRE) { 6105 cl = t.dom.getClasses(); 6106 6107 if (cl.length > 0) { 6108 s = ''; 6109 6110 each (cl, function(o) { 6111 s += (s ? '|' : '') + o['class']; 6112 }); 6113 6114 t.classesRE = new RegExp('(' + s + ')', 'gi'); 6115 } 6116 } 6117 6118 return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : ''; 6119 } 6120 6121 return v; 6122 }; 6123 } 6124 6125 if (s.convert_fonts_to_spans) 6126 t._convertFonts(); 6127 6128 if (s.inline_styles) 6129 t._convertInlineElements(); 6130 6131 if (s.cleanup_callback) { 6132 t.onSetContent.add(function(ed, o) { 6133 if (o.initial) { 6134 t.setContent(t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o), {format : 'raw', no_events : true}); 6135 t.execCallback('cleanup_callback', 'insert_to_editor_dom', t.getDoc(), o); 6136 } 6137 }); 6138 6139 t.onPreProcess.add(function(ed, o) { 6140 if (o.set) 6141 t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o); 6142 6143 if (o.get) 6144 t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o); 6145 }); 6146 6147 t.onPostProcess.add(function(ed, o) { 6148 if (o.set) 6149 o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o); 6150 6151 if (o.get) 6152 o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o); 6153 }); 6154 } 6155 6156 if (s.save_callback) { 6157 t.onGetContent.add(function(ed, o) { 6158 if (o.save) 6159 o.content = t.execCallback('save_callback', t.id, o.content, t.getBody()); 6160 }); 6161 } 6162 6163 if (s.handle_event_callback) { 6164 t.onEvent.add(function(ed, e, o) { 6165 if (t.execCallback('handle_event_callback', e, ed, o) === false) 6166 Event.cancel(e); 6167 }); 6168 } 6169 6170 t.onSetContent.add(function() { 6171 // Safari needs some time, it will crash the browser when a link is created otherwise 6172 // I think this crash issue is resolved in the latest 3.0.4 6173 //window.setTimeout(function() { 6174 t.addVisual(t.getBody()); 6175 //}, 1); 6176 }); 6177 6178 // Remove empty contents 6179 if (s.padd_empty_editor) { 6180 t.onPostProcess.add(function(ed, o) { 6181 o.content = o.content.replace(/^<p>( |#160;|\s)<\/p>$/, ''); 6182 }); 6183 } 6184 6185 // A small timeout was needed since firefox will remove. Bug: #1838304 6186 setTimeout(function () { 6187 if (t.removed) 6188 return; 6189 6190 t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')}); 6191 t.startContent = t.getContent({format : 'raw'}); 6192 t.undoManager.add({initial : true}); 6193 t.initialized = true; 6194 6195 t.onInit.dispatch(t); 6196 t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc()); 6197 t.execCallback('init_instance_callback', t); 6198 t.focus(true); 6199 t.nodeChanged({initial : 1}); 6200 6201 // Load specified content CSS last 6202 if (s.content_css) { 6203 tinymce.each(s.content_css.split(','), function(u) { 6204 t.dom.loadCSS(t.documentBaseURI.toAbsolute(u)); 6205 }); 6206 } 6207 6208 // Handle auto focus 6209 if (s.auto_focus) { 6210 setTimeout(function () { 6211 var ed = EditorManager.get(s.auto_focus); 6212 6213 ed.selection.select(ed.getBody(), 1); 6214 ed.selection.collapse(1); 6215 ed.getWin().focus(); 6216 }, 100); 6217 } 6218 }, 1); 6219 6220 e = null; 6221 }, 6222 6223 6224 focus : function(sf) { 6225 var oed, t = this; 6226 6227 if (!sf) { 6228 t.getWin().focus(); 6229 6230 } 6231 6232 if (EditorManager.activeEditor != t) { 6233 if ((oed = EditorManager.activeEditor) != null) 6234 oed.onDeactivate.dispatch(oed, t); 6235 6236 t.onActivate.dispatch(t, oed); 6237 } 6238 6239 EditorManager._setActive(t); 6240 }, 6241 6242 execCallback : function(n) { 6243 var t = this, f = t.settings[n], s; 6244 6245 if (!f) 6246 return; 6247 6248 // Look through lookup 6249 if (t.callbackLookup && (s = t.callbackLookup[n])) { 6250 f = s.func; 6251 s = s.scope; 6252 } 6253 6254 if (is(f, 'string')) { 6255 s = f.replace(/\.\w+$/, ''); 6256 s = s ? tinymce.resolve(s) : 0; 6257 f = tinymce.resolve(f); 6258 t.callbackLookup = t.callbackLookup || {}; 6259 t.callbackLookup[n] = {func : f, scope : s}; 6260 } 6261 6262 return f.apply(s || t, Array.prototype.slice.call(arguments, 1)); 6263 }, 6264 6265 translate : function(s) { 6266 var c = this.settings.language, i18n = EditorManager.i18n; 6267 6268 if (!s) 6269 return ''; 6270 6271 return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) { 6272 return i18n[c + '.' + b] || '{#' + b + '}'; 6273 }); 6274 }, 6275 6276 getLang : function(n, dv) { 6277 return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}'); 6278 }, 6279 6280 getParam : function(n, dv) { 6281 return is(this.settings[n]) ? this.settings[n] : dv; 6282 }, 6283 6284 nodeChanged : function(o) { 6285 var t = this, s = t.selection, n = s.getNode() || this.getBody(); 6286 6287 this.onNodeChange.dispatch( 6288 t, 6289 o ? o.controlManager || t.controlManager : t.controlManager, 6290 isIE && n.ownerDocument != t.getDoc() ? this.getBody() : n, // Fix for IE initial state 6291 s.isCollapsed(), 6292 o 6293 ); 6294 }, 6295 6296 addButton : function(n, s) { 6297 var t = this; 6298 6299 t.buttons = t.buttons || {}; 6300 t.buttons[n] = s; 6301 }, 6302 6303 addCommand : function(n, f, s) { 6304 this.execCommands[n] = {func : f, scope : s || this}; 6305 }, 6306 6307 addQueryStateHandler : function(n, f, s) { 6308 this.queryStateCommands[n] = {func : f, scope : s || this}; 6309 }, 6310 6311 addQueryValueHandler : function(n, f, s) { 6312 this.queryValueCommands[n] = {func : f, scope : s || this}; 6313 }, 6314 6315 addShortcut : function(pa, desc, cmd_func, sc) { 6316 var t = this, c; 6317 6318 if (!t.settings.custom_shortcuts) 6319 return false; 6320 6321 t.shortcuts = t.shortcuts || {}; 6322 6323 if (is(cmd_func, 'string')) { 6324 c = cmd_func; 6325 6326 cmd_func = function() { 6327 t.execCommand(c, false, null); 6328 }; 6329 } 6330 6331 if (is(cmd_func, 'object')) { 6332 c = cmd_func; 6333 6334 cmd_func = function() { 6335 t.execCommand(c[0], c[1], c[2]); 6336 }; 6337 } 6338 6339 each(pa.split(','), function(pa) { 6340 var o = { 6341 func : cmd_func, 6342 scope : sc || this, 6343 desc : desc, 6344 alt : false, 6345 ctrl : false, 6346 shift : false 6347 }; 6348 6349 each(pa.split('+'), function(v) { 6350 switch (v) { 6351 case 'alt': 6352 case 'ctrl': 6353 case 'shift': 6354 o[v] = true; 6355 break; 6356 6357 default: 6358 o.charCode = v.charCodeAt(0); 6359 o.keyCode = v.toUpperCase().charCodeAt(0); 6360 } 6361 }); 6362 6363 t.shortcuts[(o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode] = o; 6364 }); 6365 6454 6366 return true; 6367 }, 6368 6369 execCommand : function(cmd, ui, val, a) { 6370 var t = this, s = 0, o; 6371 6372 if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd) && (!a || !a.skip_focus)) 6373 t.focus(); 6374 6375 o = {}; 6376 t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o); 6377 if (o.terminate) 6378 return false; 6379 6380 // Comamnd callback 6381 if (t.execCallback('execcommand_callback', null, t.id, t.selection.getNode(), cmd, ui, val)) { 6382 t.onExecCommand.dispatch(t, cmd, ui, val); 6383 return true; 6384 } 6385 6386 // Registred commands 6387 if (o = t.execCommands[cmd]) { 6388 s = o.func.call(o.scope, ui, val); 6389 t.onExecCommand.dispatch(t, cmd, ui, val); 6390 return s; 6391 } 6392 6393 // Plugin commands 6394 each(t.plugins, function(p) { 6395 if (p.execCommand && p.execCommand(cmd, ui, val)) { 6396 t.onExecCommand.dispatch(t, cmd, ui, val); 6397 s = 1; 6398 return false; 6399 } 6400 }); 6401 6402 if (s) 6403 return true; 6404 6405 // Theme commands 6406 if (t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) { 6407 t.onExecCommand.dispatch(t, cmd, ui, val); 6408 return true; 6409 } 6410 6411 // Editor commands 6412 if (t.editorCommands.execCommand(cmd, ui, val)) { 6413 t.onExecCommand.dispatch(t, cmd, ui, val); 6414 return true; 6415 } 6416 6417 // Browser commands 6418 t.getDoc().execCommand(cmd, ui, val); 6419 t.onExecCommand.dispatch(t, cmd, ui, val); 6420 }, 6421 6422 queryCommandState : function(c) { 6423 var t = this, o; 6424 6425 // Is hidden then return undefined 6426 if (t._isHidden()) 6427 return; 6428 6429 // Registred commands 6430 if (o = t.queryStateCommands[c]) 6431 return o.func.call(o.scope); 6432 6433 // Registred commands 6434 o = t.editorCommands.queryCommandState(c); 6435 if (o !== -1) 6436 return o; 6437 6438 // Browser commands 6439 return this.getDoc().queryCommandState(c); 6440 }, 6441 6442 queryCommandValue : function(c) { 6443 var t = this, o; 6444 6445 // Is hidden then return undefined 6446 if (t._isHidden()) 6447 return; 6448 6449 // Registred commands 6450 if (o = t.queryValueCommands[c]) 6451 return o.func.call(o.scope); 6452 6453 // Registred commands 6454 o = t.editorCommands.queryCommandValue(c); 6455 if (is(o)) 6456 return o; 6457 6458 // Browser commands 6459 return this.getDoc().queryCommandValue(c); 6460 }, 6461 6462 show : function() { 6463 var t = this; 6464 6465 DOM.show(t.getContainer()); 6466 DOM.hide(t.id); 6467 t.load(); 6468 }, 6469 6470 hide : function() { 6471 var t = this, s = t.settings, d = t.getDoc(); 6472 6473 // Fixed bug where IE has a blinking cursor left from the editor 6474 if (isIE && d) 6475 d.execCommand('SelectAll'); 6476 6477 DOM.hide(t.getContainer()); 6478 DOM.setStyle(s.id, 'display', t.orgDisplay); 6479 t.save(); 6480 }, 6481 6482 isHidden : function() { 6483 return !DOM.isHidden(this.id); 6484 }, 6485 6486 setProgressState : function(b, ti, o) { 6487 this.onSetProgressState.dispatch(this, b, ti, o); 6488 6489 return b; 6490 }, 6491 6492 remove : function() { 6493 var t = this; 6494 6495 t.removed = 1; // Cancels post remove event execution 6496 t.hide(); 6497 DOM.remove(t.getContainer()); 6498 6499 t.execCallback('remove_instance_callback', t); 6500 t.onRemove.dispatch(t); 6501 6502 EditorManager.remove(t); 6503 }, 6504 6505 resizeToContent : function() { 6506 var t = this; 6507 6508 DOM.setStyle(t.id + "_ifr", 'height', t.getBody().scrollHeight); 6509 }, 6510 6511 load : function(o) { 6512 var t = this, e = t.getElement(), h; 6513 6514 o = o || {}; 6515 o.load = true; 6516 6517 h = t.setContent(is(e.value) ? e.value : e.innerHTML, o); 6518 o.element = e; 6519 6520 if (!o.no_events) 6521 t.onLoadContent.dispatch(t, o); 6522 6523 o.element = e = null; 6524 6525 return h; 6526 }, 6527 6528 save : function(o) { 6529 var t = this, e = t.getElement(), h, f; 6530 6531 if (!t.initialized) 6532 return; 6533 6534 o = o || {}; 6535 o.save = true; 6536 6537 o.element = e; 6538 h = o.content = t.getContent(o); 6539 6540 if (!o.no_events) 6541 t.onSaveContent.dispatch(t, o); 6542 6543 h = o.content; 6544 6545 if (!/TEXTAREA|INPUT/i.test(e.nodeName)) { 6546 e.innerHTML = h; 6547 6548 // Update hidden form element 6549 if (f = DOM.getParent(t.id, 'form')) { 6550 each(f.elements, function(e) { 6551 if (e.name == t.id) { 6552 e.value = h; 6553 return false; 6554 } 6555 }); 6556 } 6557 } else 6558 e.value = h; 6559 6560 o.element = e = null; 6561 6562 return h; 6563 }, 6564 6565 setContent : function(h, o) { 6566 var t = this; 6567 6568 o = o || {}; 6569 o.format = o.format || 'html'; 6570 o.set = true; 6571 o.content = h; 6572 6573 if (!o.no_events) 6574 t.onBeforeSetContent.dispatch(t, o); 6575 6576 // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content 6577 // It will also be impossible to place the caret in the editor unless there is a BR element present 6578 if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) { 6579 o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />', 1); 6580 o.format = 'raw'; 6581 } 6582 6583 o.content = t.dom.setHTML(t.getBody(), o.content); 6584 6585 if (o.format != 'raw' && t.settings.cleanup) { 6586 o.getInner = true; 6587 o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o)); 6588 } 6589 6590 if (!o.no_events) 6591 t.onSetContent.dispatch(t, o); 6592 6593 return o.content; 6594 }, 6595 6596 getContent : function(o) { 6597 var t = this, h; 6598 6599 o = o || {}; 6600 o.format = o.format || 'html'; 6601 o.get = true; 6602 6603 if (!o.no_events) 6604 t.onBeforeGetContent.dispatch(t, o); 6605 6606 if (o.format != 'raw' && t.settings.cleanup) { 6607 o.getInner = true; 6608 h = t.serializer.serialize(t.getBody(), o); 6609 } else 6610 h = t.getBody().innerHTML; 6611 6612 h = h.replace(/^\s*|\s*$/g, ''); 6613 o = {content : h}; 6614 t.onGetContent.dispatch(t, o); 6615 6616 return o.content; 6617 }, 6618 6619 isDirty : function() { 6620 var t = this; 6621 6622 return tinymce.trim(t.startContent) != tinymce.trim(t.getContent({format : 'raw', no_events : 1})) && !t.isNotDirty; 6623 }, 6624 6625 getContainer : function() { 6626 var t = this; 6627 6628 if (!t.container) 6629 t.container = DOM.get(t.editorContainer || t.id + '_parent'); 6630 6631 return t.container; 6632 }, 6633 6634 getContentAreaContainer : function() { 6635 return this.contentAreaContainer; 6636 }, 6637 6638 getElement : function() { 6639 return DOM.get(this.settings.content_element || this.id); 6640 }, 6641 6642 getWin : function() { 6643 var t = this, e; 6644 6645 if (!t.contentWindow) { 6646 e = DOM.get(t.id + "_ifr"); 6647 6648 if (e) 6649 t.contentWindow = e.contentWindow; 6650 } 6651 6652 return t.contentWindow; 6653 }, 6654 6655 getDoc : function() { 6656 var t = this, w; 6657 6658 if (!t.contentDocument) { 6659 w = this.getWin(); 6660 6661 if (w) 6662 t.contentDocument = w.document; 6663 } 6664 6665 return t.contentDocument; 6666 }, 6667 6668 getBody : function() { 6669 return this.bodyElement || this.getDoc().body; 6670 }, 6671 6672 convertURL : function(u, n, e) { 6673 var t = this, s = t.settings; 6674 6675 // Use callback instead 6676 if (s.urlconverter_callback) 6677 return t.execCallback('urlconverter_callback', u, e, true, n); 6678 6679 // Don't convert link href since thats the CSS files that gets loaded into the editor 6680 if (!s.convert_urls || (e && e.nodeName == 'LINK')) 6681 return u; 6682 6683 // Convert to relative 6684 if (s.relative_urls) 6685 return t.documentBaseURI.toRelative(u); 6686 6687 // Convert to absolute 6688 u = t.documentBaseURI.toAbsolute(u, s.remove_script_host); 6689 6690 return u; 6691 }, 6692 6693 addVisual : function(e) { 6694 var t = this, s = t.settings; 6695 6696 e = e || t.getBody(); 6697 6698 if (!is(t.hasVisual)) 6699 t.hasVisual = s.visual; 6700 6701 each(t.dom.select('table,a', e), function(e) { 6702 var v; 6703 6704 switch (e.nodeName) { 6705 case 'TABLE': 6706 v = t.dom.getAttrib(e, 'border'); 6707 6708 if (!v || v == '0') { 6709 if (t.hasVisual) 6710 t.dom.addClass(e, s.visual_table_class); 6711 else 6712 t.dom.removeClass(e, s.visual_table_class); 6713 } 6714 6715 return; 6716 6717 case 'A': 6718 v = t.dom.getAttrib(e, 'name'); 6719 6720 if (v) { 6721 if (t.hasVisual) 6722 t.dom.addClass(e, 'mceItemAnchor'); 6723 else 6724 t.dom.removeClass(e, 'mceItemAnchor'); 6725 } 6726 6727 return; 6728 } 6729 }); 6730 6731 t.onVisualAid.dispatch(t, e, t.hasVisual); 6732 }, 6733 6734 // Internal functions 6735 6736 _addEvents : function() { 6737 // 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset 6738 var t = this, i, s = t.settings, lo = { 6739 mouseup : 'onMouseUp', 6740 mousedown : 'onMouseDown', 6741 click : 'onClick', 6742 keyup : 'onKeyUp', 6743 keydown : 'onKeyDown', 6744 keypress : 'onKeyPress', 6745 submit : 'onSubmit', 6746 reset : 'onReset', 6747 contextmenu : 'onContextMenu', 6748 dblclick : 'onDblClick', 6749 paste : 'onPaste' // Doesn't work in all browsers yet 6750 }; 6751 6752 function eventHandler(e, o) { 6753 var ty = e.type; 6754 6755 // Don't fire events when it's removed 6756 if (t.removed) 6757 return; 6758 6759 // Generic event handler 6760 if (t.onEvent.dispatch(t, e, o) !== false) { 6761 // Specific event handler 6762 t[lo[e.fakeType || e.type]].dispatch(t, e, o); 6763 } 6764 }; 6765 6766 // Add DOM events 6767 each(lo, function(v, k) { 6768 switch (k) { 6769 case 'contextmenu': 6770 if (tinymce.isOpera) { 6771 // Fake contextmenu on Opera 6772 Event.add(t.getDoc(), 'mousedown', function(e) { 6773 if (e.ctrlKey) { 6774 e.fakeType = 'contextmenu'; 6775 eventHandler(e); 6776 } 6777 }); 6778 } else 6779 Event.add(t.getDoc(), k, eventHandler); 6780 break; 6781 6782 case 'paste': 6783 Event.add(t.getBody(), k, function(e) { 6784 var tx, h, el, r; 6785 6786 // Get plain text data 6787 if (e.clipboardData) 6788 tx = e.clipboardData.getData('text/plain'); 6789 else if (tinymce.isIE) 6790 tx = t.getWin().clipboardData.getData('Text'); 6791 6792 // Get HTML data 6793 /*if (tinymce.isIE) { 6794 el = DOM.add(document.body, 'div', {style : 'visibility:hidden;overflow:hidden;position:absolute;width:1px;height:1px'}); 6795 r = document.body.createTextRange(); 6796 r.moveToElementText(el); 6797 r.execCommand('Paste'); 6798 h = el.innerHTML; 6799 DOM.remove(el); 6800 }*/ 6801 6802 eventHandler(e, {text : tx, html : h}); 6803 }); 6804 break; 6805 6806 case 'submit': 6807 case 'reset': 6808 Event.add(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler); 6809 break; 6810 6811 default: 6812 Event.add(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler); 6813 } 6814 }); 6815 6816 Event.add(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) { 6817 t.focus(true); 6818 }); 6819 6820 // Fixes bug where a specified document_base_uri could result in broken images 6821 // This will also fix drag drop of images in Gecko 6822 if (tinymce.isGecko) { 6823 // Convert all images to absolute URLs 6824 /* t.onSetContent.add(function(ed, o) { 6825 each(ed.dom.select('img'), function(e) { 6826 var v; 6827 6828 if (v = e.getAttribute('mce_src')) 6829 e.src = t.documentBaseURI.toAbsolute(v); 6830 }) 6831 });*/ 6832 6833 Event.add(t.getDoc(), 'DOMNodeInserted', function(e) { 6834 var v; 6835 6836 e = e.target; 6837 6838 if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src'))) 6839 e.src = t.documentBaseURI.toAbsolute(v); 6840 }); 6841 } 6842 6843 // Set various midas options in Gecko 6844 if (isGecko) { 6845 function setOpts() { 6846 var t = this, d = t.getDoc(), s = t.settings; 6847 6848 if (isGecko) { 6849 if (t._isHidden()) { 6850 try { 6851 d.designMode = 'On'; 6852 } catch (ex) { 6853 // Fails if it's hidden 6854 } 6855 } 6856 6857 try { 6858 // Try new Gecko method 6859 d.execCommand("styleWithCSS", 0, false); 6860 } catch (ex) { 6861 // Use old method 6862 if (!t._isHidden()) 6863 d.execCommand("useCSS", 0, true); 6864 } 6865 6866 if (!s.table_inline_editing) 6867 try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {} 6868 6869 if (!s.object_resizing) 6870 try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {} 6871 } 6872 }; 6873 6874 t.onBeforeExecCommand.add(setOpts); 6875 t.onMouseDown.add(setOpts); 6876 } 6877 6878 // Add node change handlers 6879 t.onMouseUp.add(t.nodeChanged); 6880 t.onClick.add(t.nodeChanged); 6881 t.onKeyUp.add(function(ed, e) { 6882 if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.keyCode == 46 || e.keyCode == 8 || e.ctrlKey) 6883 t.nodeChanged(); 6884 }); 6885 6886 // Add reset handler 6887 t.onReset.add(function() { 6888 t.setContent(t.startContent, {format : 'raw'}); 6889 }); 6890 6891 if (t.getParam('tab_focus')) { 6892 function tabCancel(ed, e) { 6893 if (e.keyCode === 9) 6894 return Event.cancel(e); 6895 }; 6896 6897 function tabHandler(ed, e) { 6898 var v, f, el; 6899 6900 if (e.keyCode === 9) { 6901 v = ed.getParam('tab_focus'); 6902 6903 if (v == ':next') { 6904 f = DOM.getParent(ed.id, 'form'); 6905 6906 if (f) { 6907 each(f.elements, function(e, i) { 6908 if (e.id == ed.id) 6909 el = f.elements[i + 1]; 6910 }); 6911 } 6912 } else 6913 el = DOM.get(v); 6914 6915 if (el) { 6916 window.setTimeout(function() {window.focus();el.focus();}, 10); 6917 return Event.cancel(e); 6918 } 6919 } 6920 }; 6921 6922 t.onKeyUp.add(tabCancel); 6923 6924 if (isGecko) { 6925 t.onKeyPress.add(tabHandler); 6926 t.onKeyDown.add(tabCancel); 6927 } else 6928 t.onKeyDown.add(tabHandler); 6929 } 6930 6931 // Add shortcuts 6932 if (s.custom_shortcuts) { 6933 if (s.custom_undo_redo_keyboard_shortcuts) { 6934 t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo'); 6935 t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo'); 6936 } 6937 6938 // Add default shortcuts for gecko 6939 if (isGecko) { 6940 t.addShortcut('ctrl+b', t.getLang('bold_desc'), 'Bold'); 6941 t.addShortcut('ctrl+i', t.getLang('italic_desc'), 'Italic'); 6942 t.addShortcut('ctrl+u', t.getLang('underline_desc'), 'Underline'); 6943 } 6944 6945 // BlockFormat shortcuts keys 6946 for (i=1; i<=6; i++) 6947 t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, '<h' + i + '>']); 6948 6949 t.addShortcut('ctrl+7', '', ['FormatBlock', false, '<p>']); 6950 t.addShortcut('ctrl+8', '', ['FormatBlock', false, '<div>']); 6951 t.addShortcut('ctrl+9', '', ['FormatBlock', false, '<address>']); 6952 6953 function find(e) { 6954 var v = null; 6955 6956 if (!e.altKey && !e.ctrlKey && !e.metaKey) 6957 return v; 6958 6959 each(t.shortcuts, function(o) { 6960 if (o.ctrl != e.ctrlKey && (!tinymce.isMac || o.ctrl == e.metaKey)) 6961 return; 6962 6963 if (o.alt != e.altKey) 6964 return; 6965 6966 if (o.shift != e.shiftKey) 6967 return; 6968 6969 if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) { 6970 v = o; 6971 return false; 6972 } 6973 }); 6974 6975 return v; 6976 }; 6977 6978 t.onKeyUp.add(function(ed, e) { 6979 var o = find(e); 6980 6981 if (o) 6982 return Event.cancel(e); 6983 }); 6984 6985 t.onKeyPress.add(function(ed, e) { 6986 var o = find(e); 6987 6988 if (o) 6989 return Event.cancel(e); 6990 }); 6991 6992 t.onKeyDown.add(function(ed, e) { 6993 var o = find(e); 6994 6995 if (o) { 6996 o.func.call(o.scope); 6997 return Event.cancel(e); 6998 } 6999 }); 7000 } 7001 7002 if (tinymce.isIE) { 7003 // Fix so resize will only update the width and height attributes not the styles of an image 7004 // It will also block mceItemNoResize items 7005 Event.add(t.getDoc(), 'controlselect', function(e) { 7006 var re = t.resizeInfo, cb; 7007 7008 e = e.target; 7009 7010 if (re) 7011 Event.remove(re.node, re.ev, re.cb); 7012 7013 if (!t.dom.hasClass(e, 'mceItemNoResize')) { 7014 ev = 'resizeend'; 7015 cb = Event.add(e, ev, function(e) { 7016 var v; 7017 7018 e = e.target; 7019 7020 if (v = t.dom.getStyle(e, 'width')) { 7021 t.dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, '')); 7022 t.dom.setStyle(e, 'width', ''); 7023 } 7024 7025 if (v = t.dom.getStyle(e, 'height')) { 7026 t.dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, '')); 7027 t.dom.setStyle(e, 'height', ''); 7028 } 7029 }); 7030 } else { 7031 ev = 'resizestart'; 7032 cb = Event.add(e, 'resizestart', Event.cancel, Event); 7033 } 7034 7035 re = t.resizeInfo = { 7036 node : e, 7037 ev : ev, 7038 cb : cb 7039 }; 7040 }); 7041 7042 t.onKeyDown.add(function(ed, e) { 7043 switch (e.keyCode) { 7044 case 8: 7045 // Fix IE control + backspace browser bug 7046 if (t.selection.getRng().item) { 7047 t.selection.getRng().item(0).removeNode(); 7048 return Event.cancel(e); 7049 } 7050 } 7051 }); 7052 } 7053 7054 if (tinymce.isOpera) { 7055 t.onClick.add(function(ed, e) { 7056 Event.prevent(e); 7057 }); 7058 } 7059 7060 // Add custom undo/redo handlers 7061 if (s.custom_undo_redo) { 7062 function addUndo() { 7063 t.undoManager.typing = 0; 7064 t.undoManager.add(); 7065 }; 7066 7067 // Add undo level on editor blur 7068 if (tinymce.isIE) { 7069 Event.add(t.getWin(), 'blur', function(e) { 7070 var n; 7071 7072 // Check added for fullscreen bug 7073 if (t.selection) { 7074 n = t.selection.getNode(); 7075 7076 // Add undo level is selection was lost to another document 7077 if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc()) 7078 addUndo(); 7079 } 7080 }); 7081 } else { 7082 Event.add(t.getDoc(), 'blur', function() { 7083 if (t.selection && !t.removed) 7084 addUndo(); 7085 }); 7086 } 7087 7088 t.onMouseDown.add(addUndo); 7089 7090 t.onKeyUp.add(function(ed, e) { 7091 if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey) { 7092 t.undoManager.typing = 0; 7093 t.undoManager.add(); 7094 } 7095 }); 7096 7097 t.onKeyDown.add(function(ed, e) { 7098 // Is caracter positon keys 7099 if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45) { 7100 if (t.undoManager.typing) { 7101 t.undoManager.add(); 7102 t.undoManager.typing = 0; 7103 } 7104 7105 return; 7106 } 7107 7108 if (!t.undoManager.typing) { 7109 t.undoManager.add(); 7110 t.undoManager.typing = 1; 7111 } 7112 }); 7113 } 7114 }, 7115 7116 _destroy : function() { 7117 var t = this; 7118 7119 if (t.formElement) { 7120 t.formElement.submit = t.formElement._mceOldSubmit; 7121 t.formElement._mceOldSubmit = null; 7122 } 7123 7124 t.contentAreaContainer = t.formElement = t.container = t.contentDocument = t.contentWindow = null; 7125 7126 if (t.selection) 7127 t.selection = t.selection.win = t.selection.dom = t.selection.dom.doc = null; 7128 7129 t.destroyed = 1; 7130 }, 7131 7132 _convertInlineElements : function() { 7133 var t = this, s = t.settings, dom = t.dom; 7134 7135 function convert(ed, o) { 7136 if (!s.inline_styles) 7137 return; 7138 7139 if (o.get) { 7140 each(t.dom.select('table,u,strike', o.node), function(n) { 7141 switch (n.nodeName) { 7142 case 'TABLE': 7143 if (v = dom.getAttrib(n, 'height')) { 7144 dom.setStyle(n, 'height', v); 7145 dom.setAttrib(n, 'height', ''); 7146 } 7147 break; 7148 7149 case 'U': 7150 dom.replace(dom.create('span', {style : 'text-decoration: underline;'}), n, 1); 7151 break; 7152 7153 case 'STRIKE': 7154 dom.replace(dom.create('span', {style : 'text-decoration: line-through;'}), n, 1); 7155 break; 7156 } 7157 }); 7158 } else if (o.set) { 7159 each(t.dom.select('table,span', o.node), function(n) { 7160 if (n.nodeName == 'TABLE') { 7161 if (v = dom.getStyle(n, 'height')) 7162 dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, '')); 7163 } else { 7164 // Convert spans to elements 7165 if (n.style.textDecoration == 'underline') 7166 dom.replace(dom.create('u'), n, 1); 7167 else if (n.style.textDecoration == 'line-through') 7168 dom.replace(dom.create('strike'), n, 1); 7169 } 7170 }); 7171 } 7172 }; 7173 7174 t.onPreProcess.add(convert); 7175 7176 if (!s.cleanup_on_startup) { 7177 t.onInit.add(function() { 7178 convert(t, {node : t.getBody(), set : 1}); 7179 }); 7180 } 7181 }, 7182 7183 _convertFonts : function() { 7184 var t = this, s = t.settings, dom = t.dom, sl, cl, fz, fzn, v, i; 7185 7186 // Font pt values and font size names 7187 fz = [8, 10, 12, 14, 18, 24, 36]; 7188 fzn = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large']; 7189 7190 if (sl = s.font_size_style_values) 7191 sl = sl.split(','); 7192 7193 if (cl = s.font_size_classes) 7194 cl = cl.split(','); 7195 7196 t.onPreProcess.add(function(ed, o) { 7197 if (!s.inline_styles) 7198 return; 7199 7200 if (o.set) { 7201 // Convert spans to fonts on non WebKit browsers 7202 if (tinymce.isWebKit) 7203 return; 7204 7205 each(t.dom.select('span', o.node), function(n) { 7206 var f = dom.create('font', { 7207 color : dom.toHex(dom.getStyle(n, 'color')), 7208 face : dom.getStyle(n, 'fontFamily') 7209 }); 7210 7211 if (sl) { 7212 i = inArray(sl, dom.getStyle(n, 'fontSize')); 7213 7214 if (i != -1) 7215 dom.setAttrib(f, 'size', '' + (i + 1 || 1)); 7216 } else if (cl) { 7217 i = inArray(cl, dom.getAttrib(n, 'class')); 7218 7219 v = dom.getStyle(n, 'fontSize'); 7220 7221 if (i == -1 && v.indexOf('pt') > 0) 7222 i = inArray(fz, parseInt(v)); 7223 7224 if (i == -1) 7225 i = inArray(fzn, v); 7226 7227 if (i != -1) 7228 dom.setAttrib(f, 'size', '' + (i + 1 || 1)); 7229 } 7230 7231 if (f.color || f.face || f.size) 7232 dom.replace(f, n, 1); 7233 }); 7234 } else if (o.get) { 7235 each(t.dom.select('font', o.node), function(n) { 7236 var sp = dom.create('span', { 7237 style : { 7238 fontFamily : dom.getAttrib(n, 'face'), 7239 color : dom.getAttrib(n, 'color'), 7240 backgroundColor : n.style.backgroundColor 7241 } 7242 }); 7243 7244 if (n.size) { 7245 if (sl) 7246 dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]); 7247 else 7248 dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]); 7249 } 7250 7251 dom.replace(sp, n, 1); 7252 }); 7253 } 7254 }); 7255 }, 7256 7257 _isHidden : function() { 7258 var s; 7259 7260 if (!isGecko) 7261 return 0; 7262 7263 // Weird, wheres that cursor selection? 7264 s = this.selection.getSel(); 7265 return (!s || !s.rangeCount || s.rangeCount == 0); 7266 }, 7267 7268 _fixNesting : function(s) { 7269 var d = [], i; 7270 7271 s = s.replace(/<(\/)?([^\s>]+)[^>]*?>/g, function(a, b, c) { 7272 var e; 7273 7274 // Handle end element 7275 if (b === '/') { 7276 if (!d.length) 7277 return ''; 7278 7279 if (c !== d[d.length - 1].tag) { 7280 for (i=d.length - 1; i>=0; i--) { 7281 if (d[i].tag === c) { 7282 d[i].close = 1; 7283 break; 7284 } 7285 } 7286 7287 return ''; 7288 } else { 7289 d.pop(); 7290 7291 if (d.length && d[d.length - 1].close) { 7292 a = a + '</' + d[d.length - 1].tag + '>'; 7293 d.pop(); 7294 } 7295 } 7296 } else { 7297 // Ignore these 7298 if (/^(br|hr|input|meta|img|link|param)$/i.test(c)) 7299 return a; 7300 7301 // Ignore closed ones 7302 if (/\/>$/.test(a)) 7303 return a; 7304 7305 d.push({tag : c}); // Push start element 7306 } 7307 7308 return a; 7309 }); 7310 7311 // End all open tags 7312 for (i=d.length - 1; i>=0; i--) 7313 s += '</' + d[i].tag + '>'; 7314 7315 return s; 6455 7316 } 6456 7317 6457 if (tinyMCE.isRealIE) { 6458 if (bookmark.rng) { 7318 }); 7319 })(); 7320 7321 /* file:jscripts/tiny_mce/classes/EditorCommands.js */ 7322 7323 (function() { 7324 var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit; 7325 7326 tinymce.create('tinymce.EditorCommands', { 7327 EditorCommands : function(ed) { 7328 this.editor = ed; 7329 }, 7330 7331 execCommand : function(cmd, ui, val) { 7332 var t = this, ed = t.editor, f; 7333 7334 switch (cmd) { 7335 case 'Cut': 7336 case 'Copy': 7337 case 'Paste': 7338 try { 7339 ed.getDoc().execCommand(cmd, ui, val); 7340 } catch (ex) { 7341 if (isGecko) { 7342 ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) { 7343 if (s) 7344 window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal'); 7345 }); 7346 } else 7347 ed.windowManager.alert(ed.getLang('clipboard_no_support')); 7348 } 7349 7350 return true; 7351 7352 // Ignore these 7353 case 'mceResetDesignMode': 7354 case 'mceBeginUndoLevel': 7355 return true; 7356 7357 // Ignore these 7358 case 'unlink': 7359 t.UnLink(); 7360 return true; 7361 7362 // Bundle these together 7363 case 'JustifyLeft': 7364 case 'JustifyCenter': 7365 case 'JustifyRight': 7366 case 'JustifyFull': 7367 t.mceJustify(cmd, cmd.substring(7).toLowerCase()); 7368 return true; 7369 7370 case 'mceEndUndoLevel': 7371 case 'mceAddUndoLevel': 7372 ed.undoManager.add(); 7373 return true; 7374 7375 default: 7376 f = this[cmd]; 7377 7378 if (f) { 7379 f.call(this, ui, val); 7380 return true; 7381 } 7382 } 7383 7384 return false; 7385 }, 7386 7387 Indent : function() { 7388 var ed = this.editor, d = ed.dom, s = ed.selection, e, iv, iu; 7389 7390 // Setup indent level 7391 iv = ed.settings.indentation; 7392 iu = /[a-z%]+$/i.exec(iv); 7393 iv = parseInt(iv); 7394 7395 if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) { 7396 each(this._getSelectedBlocks(), function(e) { 7397 d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu); 7398 }); 7399 7400 return; 7401 } 7402 7403 ed.getDoc().execCommand('Indent', false, null); 7404 7405 if (isIE) { 7406 d.getParent(s.getNode(), function(n) { 7407 if (n.nodeName == 'BLOCKQUOTE') { 7408 n.dir = n.style.cssText = ''; 7409 } 7410 }); 7411 } 7412 }, 7413 7414 Outdent : function() { 7415 var ed = this.editor, d = ed.dom, s = ed.selection, e, v, iv, iu; 7416 7417 // Setup indent level 7418 iv = ed.settings.indentation; 7419 iu = /[a-z%]+$/i.exec(iv); 7420 iv = parseInt(iv); 7421 7422 if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) { 7423 each(this._getSelectedBlocks(), function(e) { 7424 v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv); 7425 d.setStyle(e, 'paddingLeft', v ? v + iu : ''); 7426 }); 7427 7428 return; 7429 } 7430 7431 ed.getDoc().execCommand('Outdent', false, null); 7432 }, 7433 7434 mceSetAttribute : function(u, v) { 7435 var ed = this.editor, d = ed.dom, e; 7436 7437 if (e = d.getParent(ed.selection.getNode(), d.isBlock)) 7438 d.setAttrib(e, v.name, v.value); 7439 }, 7440 7441 mceSetContent : function(u, v) { 7442 this.editor.setContent(v); 7443 }, 7444 7445 mceToggleVisualAid : function() { 7446 var ed = this.editor; 7447 7448 ed.hasVisual = !ed.hasVisual; 7449 ed.addVisual(); 7450 }, 7451 7452 mceReplaceContent : function(u, v) { 7453 var s = this.editor.selection; 7454 7455 s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'}))); 7456 }, 7457 7458 mceInsertLink : function(u, v) { 7459 var ed = this.editor, e = ed.dom.getParent(ed.selection.getNode(), 'A'); 7460 7461 if (tinymce.is(v, 'string')) 7462 v = {href : v}; 7463 7464 function set(e) { 7465 each(v, function(v, k) { 7466 ed.dom.setAttrib(e, k, v); 7467 }); 7468 }; 7469 7470 if (!e) { 7471 ed.execCommand('CreateLink', false, 'javascript:mctmp(0);'); 7472 each(ed.dom.select('a'), function(e) { 7473 if (e.href == 'javascript:mctmp(0);') 7474 set(e); 7475 }); 7476 } else { 7477 if (v.href) 7478 set(e); 7479 else 7480 ed.dom.remove(e, 1); 7481 } 7482 }, 7483 7484 UnLink : function() { 7485 var ed = this.editor, s = ed.selection; 7486 7487 if (s.isCollapsed()) 7488 s.select(s.getNode()); 7489 7490 ed.getDoc().execCommand('unlink', false, null); 7491 s.collapse(0); 7492 }, 7493 7494 FontName : function(u, v) { 7495 var t = this, ed = t.editor, s = ed.selection, e; 7496 7497 if (!v) { 7498 if (s.isCollapsed()) 7499 s.select(s.getNode()); 7500 7501 t.RemoveFormat(); 7502 } else 7503 ed.getDoc().execCommand('FontName', false, v); 7504 }, 7505 7506 queryCommandValue : function(c) { 7507 var f = this['queryValue' + c]; 7508 7509 if (f) 7510 return f.call(this, c); 7511 7512 return false; 7513 }, 7514 7515 queryCommandState : function(cmd) { 7516 var f; 7517 7518 switch (cmd) { 7519 // Bundle these together 7520 case 'JustifyLeft': 7521 case 'JustifyCenter': 7522 case 'JustifyRight': 7523 case 'JustifyFull': 7524 return this.queryStateJustify(cmd, cmd.substring(7).toLowerCase()); 7525 7526 default: 7527 if (f = this['queryState' + cmd]) 7528 return f.call(this, cmd); 7529 } 7530 7531 return -1; 7532 }, 7533 7534 queryValueFontSize : function() { 7535 var ed = this.editor, v = 0, p; 7536 7537 if (isOpera || isWebKit) { 7538 if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT')) 7539 v = p.size; 7540 7541 return v; 7542 } 7543 7544 return ed.getDoc().queryCommandValue('FontSize'); 7545 }, 7546 7547 queryValueFontName : function() { 7548 var ed = this.editor, v = 0, p; 7549 7550 if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT')) 7551 v = p.face; 7552 7553 if (!v) 7554 v = ed.getDoc().queryCommandValue('FontName'); 7555 7556 return v; 7557 }, 7558 7559 mceJustify : function(c, v) { 7560 var ed = this.editor, se = ed.selection, n = se.getNode(), nn = n.nodeName, bl, nb, dom = ed.dom, rm; 7561 7562 if (ed.settings.inline_styles && this.queryStateJustify(c, v)) 7563 rm = 1; 7564 7565 bl = dom.getParent(n, ed.dom.isBlock); 7566 7567 if (nn == 'IMG') { 7568 if (v == 'full') 7569 return; 7570 7571 if (rm) { 7572 dom.setStyle(n, 'float', ''); 7573 this.mceRepaint(); 7574 return; 7575 } 7576 7577 if (v == 'center') { 7578 if (!bl || bl.childNodes.length > 1) { 7579 nb = dom.create('p'); 7580 nb.appendChild(n.cloneNode(false)); 7581 7582 if (bl) 7583 dom.insertAfter(nb, bl); 7584 else 7585 dom.insertAfter(nb, n); 7586 7587 dom.remove(n); 7588 n = nb.firstChild; 7589 bl = nb; 7590 } 7591 7592 dom.setStyle(bl, 'textAlign', v); 7593 dom.setStyle(n, 'float', ''); 7594 } else 7595 dom.setStyle(n, 'float', v); 7596 7597 this.mceRepaint(); 7598 return; 7599 } 7600 7601 // Handle the alignment outselfs, less quirks in all browsers 7602 if (ed.settings.inline_styles && ed.settings.forced_root_block) { 7603 if (rm) 7604 v = ''; 7605 7606 each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) { 7607 dom.setAttrib(e, 'align', ''); 7608 dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v); 7609 }); 7610 7611 return; 7612 } else if (!rm) 7613 ed.getDoc().execCommand(c, false, null); 7614 7615 if (ed.settings.inline_styles) { 7616 if (rm) { 7617 dom.getParent(ed.selection.getNode(), function(n) { 7618 if (n.style && n.style.textAlign) 7619 dom.setStyle(n, 'textAlign', ''); 7620 }); 7621 7622 return; 7623 } 7624 7625 each(dom.select('*'), function(n) { 7626 var v = n.align; 7627 7628 if (v) { 7629 if (v == 'full') 7630 v = 'justify'; 7631 7632 dom.setStyle(n, 'textAlign', v); 7633 dom.setAttrib(n, 'align', ''); 7634 } 7635 }); 7636 } 7637 }, 7638 7639 mceSetCSSClass : function(u, v) { 7640 this.mceSetStyleInfo(0, {command : 'setattrib', name : 'class', value : v}); 7641 }, 7642 7643 getSelectedElement : function() { 7644 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; 7645 7646 if (se.isCollapsed() || r.item) 7647 return se.getNode(); 7648 7649 // Setup regexp 7650 re = ed.settings.merge_styles_invalid_parents; 7651 if (tinymce.is(re, 'string')) 7652 re = new RegExp(re, 'i'); 7653 7654 if (isIE) { 7655 r1 = r.duplicate(); 7656 r1.collapse(true); 7657 sc = r1.parentElement(); 7658 7659 r2 = r.duplicate(); 7660 r2.collapse(false); 7661 ec = r2.parentElement(); 7662 7663 if (sc != ec) { 7664 r1.move('character', 1); 7665 sc = r1.parentElement(); 7666 } 7667 7668 if (sc == ec) { 7669 r1 = r.duplicate(); 7670 r1.moveToElementText(sc); 7671 7672 if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0) 7673 return re && re.test(sc.nodeName) ? null : sc; 7674 } 7675 } else { 7676 function getParent(n) { 7677 return dom.getParent(n, function(n) {return n.nodeType == 1;}); 7678 }; 7679 7680 sc = r.startContainer; 7681 ec = r.endContainer; 7682 so = r.startOffset; 7683 eo = r.endOffset; 7684 7685 if (!r.collapsed) { 7686 if (sc == ec) { 7687 if (so - eo < 2) { 7688 if (sc.hasChildNodes()) { 7689 sp = sc.childNodes[so]; 7690 return re && re.test(sp.nodeName) ? null : sp; 7691 } 7692 } 7693 } 7694 } 7695 7696 if (sc.nodeType != 3 || ec.nodeType != 3) 7697 return null; 7698 7699 if (so == 0) { 7700 sp = getParent(sc); 7701 7702 if (sp && sp.firstChild != sc) 7703 sp = null; 7704 } 7705 7706 if (so == sc.nodeValue.length) { 7707 e = sc.nextSibling; 7708 7709 if (e && e.nodeType == 1) 7710 sp = sc.nextSibling; 7711 } 7712 7713 if (eo == 0) { 7714 e = ec.previousSibling; 7715 7716 if (e && e.nodeType == 1) 7717 ep = e; 7718 } 7719 7720 if (eo == ec.nodeValue.length) { 7721 ep = getParent(ec); 7722 7723 if (ep && ep.lastChild != ec) 7724 ep = null; 7725 } 7726 7727 // Same element 7728 if (sp == ep) 7729 return re && sp && re.test(sp.nodeName) ? null : sp; 7730 } 7731 7732 return null; 7733 }, 7734 7735 InsertHorizontalRule : function() { 7736 // Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]"); 7737 if (isGecko || isIE) 7738 this.editor.selection.setContent('<hr />'); 7739 else 7740 this.editor.getDoc().execCommand('InsertHorizontalRule', false, ''); 7741 }, 7742 7743 RemoveFormat : function() { 7744 var t = this, ed = t.editor, s = ed.selection, b; 7745 7746 // Safari breaks tables 7747 if (isWebKit) 7748 s.setContent(s.getContent({format : 'raw'}).replace(/(<(span|b|i|strong|em|strike) [^>]+>|<(span|b|i|strong|em|strike)>|<\/(span|b|i|strong|em|strike)>|)/g, ''), {format : 'raw'}); 7749 else 7750 ed.getDoc().execCommand('RemoveFormat', false, null); 7751 7752 t.mceSetStyleInfo(0, {command : 'removeformat'}); 7753 ed.addVisual(); 7754 }, 7755 7756 mceSetStyleInfo : function(u, v) { 7757 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; 7758 7759 function set(n, e) { 7760 if (n.nodeType == 1) { 7761 switch (v.command) { 7762 case 'setattrib': 7763 return dom.setAttrib(n, v.name, v.value); 7764 7765 case 'setstyle': 7766 return dom.setStyle(n, v.name, v.value); 7767 7768 case 'removeformat': 7769 return dom.setAttrib(n, 'class', ''); 7770 } 7771 } 7772 }; 7773 7774 // Setup regexp 7775 re = ed.settings.merge_styles_invalid_parents; 7776 if (tinymce.is(re, 'string')) 7777 re = new RegExp(re, 'i'); 7778 7779 // Set style info on selected element 7780 if (e = t.getSelectedElement()) 7781 set(e, 1); 7782 else { 7783 // Generate wrappers and set styles on them 7784 d.execCommand('FontName', false, '__'); 7785 each(isWebKit ? dom.select('span') : dom.select('font'), function(n) { 7786 var sp, e; 7787 7788 if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') { 7789 sp = dom.create(nn, {mce_new : '1'}); 7790 7791 set(sp); 7792 7793 each (n.childNodes, function(n) { 7794 sp.appendChild(n.cloneNode(true)); 7795 }); 7796 7797 dom.replace(sp, n); 7798 } 7799 }); 7800 } 7801 7802 // Remove wrappers inside new ones 7803 each(dom.select(nn).reverse(), function(n) { 7804 var p = n.parentNode; 7805 7806 dom.setAttrib(n, 'mce_new', ''); 7807 7808 // Check if it's an old span in a new wrapper 7809 if (!dom.getAttrib(n, 'mce_new')) { 7810 // Find new wrapper 7811 p = dom.getParent(n, function(n) { 7812 return n.nodeType == 1 && dom.getAttrib(n, 'mce_new'); 7813 }); 7814 7815 if (p) 7816 dom.remove(n, 1); 7817 } 7818 }); 7819 7820 // Merge wrappers with parent wrappers 7821 each(dom.select(nn).reverse(), function(n) { 7822 var p = n.parentNode; 7823 7824 if (!p) 7825 return; 7826 7827 // Has parent of the same type and only child 7828 if (p.nodeName == nn.toUpperCase() && p.childNodes.length == 1) 7829 return dom.remove(p, 1); 7830 7831 // Has parent that is more suitable to have the class and only child 7832 if (n.nodeType == 1 && (!re || !re.test(p.nodeName)) && p.childNodes.length == 1) { 7833 set(p); // Set style info on parent instead 7834 dom.setAttrib(n, 'class', ''); 7835 } 7836 }); 7837 7838 // Remove empty wrappers 7839 each(dom.select(nn).reverse(), function(n) { 7840 if (!dom.getAttrib(n, 'class') && !dom.getAttrib(n, 'style')) 7841 return dom.remove(n, 1); 7842 }); 7843 7844 s.moveToBookmark(b); 7845 }, 7846 7847 queryStateJustify : function(c, v) { 7848 var ed = this.editor, n = ed.selection.getNode(), dom = ed.dom; 7849 7850 if (n && n.nodeName == 'IMG') 7851 return dom.getStyle(n, 'float') == v; 7852 7853 n = dom.getParent(ed.selection.getStart(), function(n) { 7854 return n.nodeType == 1 && n.style.textAlign; 7855 }); 7856 7857 if (v == 'full') 7858 v = 'justify'; 7859 7860 if (ed.settings.inline_styles) 7861 return (n && n.style.textAlign == v); 7862 7863 return ed.getDoc().queryCommandState(c); 7864 }, 7865 7866 HiliteColor : function(ui, val) { 7867 var t = this, ed = t.editor, d = ed.getDoc(); 7868 7869 function set(s) { 7870 if (!isGecko) 7871 return; 7872 6459 7873 try { 6460 bookmark.rng.select(); 7874 // Try new Gecko method 7875 d.execCommand("styleWithCSS", 0, s); 7876 } catch (ex) { 7877 // Use old 7878 d.execCommand("useCSS", 0, !s); 7879 } 7880 }; 7881 7882 if (isGecko || isOpera) { 7883 set(true); 7884 d.execCommand('hilitecolor', false, val); 7885 set(false); 7886 } else 7887 d.execCommand('BackColor', false, val); 7888 }, 7889 7890 Undo : function() { 7891 var ed = this.editor; 7892 7893 if (ed.settings.custom_undo_redo) { 7894 ed.undoManager.undo(); 7895 ed.nodeChanged(); 7896 } else 7897 ed.getDoc().execCommand('Undo', false, null); 7898 }, 7899 7900 Redo : function() { 7901 var ed = this.editor; 7902 7903 if (ed.settings.custom_undo_redo) { 7904 ed.undoManager.redo(); 7905 ed.nodeChanged(); 7906 } else 7907 ed.getDoc().execCommand('Redo', false, null); 7908 }, 7909 7910 FormatBlock : function(ui, val) { 7911 var t = this, ed = t.editor; 7912 7913 val = ed.settings.forced_root_block ? (val || '<p>') : val; 7914 t.mceRemoveNode(); 7915 7916 if (val.indexOf('<') == -1) 7917 val = '<' + val + '>'; 7918 7919 if (tinymce.isGecko) 7920 val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1'); 7921 7922 ed.getDoc().execCommand('FormatBlock', false, val); 7923 }, 7924 7925 mceCleanup : function() { 7926 var ed = this.editor, s = ed.selection, b = s.getBookmark(); 7927 ed.setContent(ed.getContent()); 7928 s.moveToBookmark(b); 7929 }, 7930 7931 mceRemoveNode : function(ui, val) { 7932 var ed = this.editor, s = ed.selection, b, n = val || s.getNode(); 7933 7934 // Make sure that the body node isn't removed 7935 if (n == ed.getBody()) 7936 return; 7937 7938 b = s.getBookmark(); 7939 ed.dom.remove(n, 1); 7940 s.moveToBookmark(b); 7941 ed.nodeChanged(); 7942 }, 7943 7944 mceSelectNodeDepth : function(ui, val) { 7945 var ed = this.editor, s = ed.selection, c = 0; 7946 7947 ed.dom.getParent(s.getNode(), function(n) { 7948 if (n.nodeType == 1 && c++ == val) { 7949 s.select(n); 7950 ed.nodeChanged(); 7951 return false; 7952 } 7953 }, ed.getBody()); 7954 }, 7955 7956 mceSelectNode : function(u, v) { 7957 this.editor.selection.select(v); 7958 }, 7959 7960 mceInsertContent : function(ui, val) { 7961 this.editor.selection.setContent(val); 7962 }, 7963 7964 mceInsertRawHTML : function(ui, val) { 7965 var ed = this.editor; 7966 7967 ed.execCommand('mceInsertContent', false, 'tiny_mce_marker'); 7968 ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val)); 7969 }, 7970 7971 mceRepaint : function() { 7972 var s, b, e = this.editor; 7973 7974 if (tinymce.isGecko) { 7975 try { 7976 s = e.selection; 7977 b = s.getBookmark(true); 7978 7979 if (s.getSel()) 7980 s.getSel().selectAllChildren(e.getBody()); 7981 7982 s.collapse(true); 7983 s.moveToBookmark(b); 6461 7984 } catch (ex) { 6462 7985 // Ignore 6463 7986 } 6464 7987 } 7988 }, 7989 7990 queryStateUnderline : function() { 7991 var ed = this.editor, n; 7992 7993 if (n && n.nodeName == 'A') 7994 return false; 7995 7996 return ed.getDoc().queryCommandState('Underline'); 7997 }, 7998 7999 queryStateOutdent : function() { 8000 var ed = this.editor, n; 8001 8002 if (ed.settings.inline_styles) { 8003 if ((n = ed.dom.getParent(ed.selection.getStart(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0) 8004 return true; 8005 8006 if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0) 8007 return true; 8008 } else 8009 return !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE'); 8010 8011 return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList(); 8012 }, 8013 8014 queryStateInsertUnorderedList : function() { 8015 return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL'); 8016 }, 8017 8018 queryStateInsertOrderedList : function() { 8019 return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL'); 8020 }, 8021 8022 queryStatemceBlockQuote : function() { 8023 return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';}); 8024 }, 8025 8026 mceBlockQuote : function() { 8027 var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom; 8028 8029 function findBQ(e) { 8030 return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';}); 8031 }; 8032 8033 // Remove blockquote(s) 8034 if (findBQ(s.getStart())) { 8035 each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) { 8036 // Found BQ lets remove it 8037 if (e.nodeName == 'BLOCKQUOTE') 8038 dom.remove(e, 1); 8039 }); 8040 8041 t.editor.selection.moveToBookmark(b); 8042 return; 8043 } 8044 8045 each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) { 8046 var n; 8047 8048 // Found existing BQ add to this one 8049 if (e.nodeName == 'BLOCKQUOTE' && !bq) { 8050 bq = e; 8051 return; 8052 } 8053 8054 // No BQ found, create one 8055 if (!bq) { 8056 bq = dom.create('blockquote'); 8057 e.parentNode.insertBefore(bq, e); 8058 } 8059 8060 // Add children from existing BQ 8061 if (e.nodeName == 'BLOCKQUOTE' && bq) { 8062 n = e.firstChild; 8063 8064 while (n) { 8065 bq.appendChild(n.cloneNode(true)); 8066 n = n.nextSibling; 8067 } 8068 8069 dom.remove(e); 8070 8071 return; 8072 } 8073 8074 // Add non BQ element to BQ 8075 bq.appendChild(dom.remove(e)); 8076 }); 8077 8078 t.editor.selection.moveToBookmark(b); 8079 }, 8080 8081 _getSelectedBlocks : function(st, en) { 8082 var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = []; 8083 8084 sb = dom.getParent(st || s.getStart(), dom.isBlock); 8085 eb = dom.getParent(en || s.getEnd(), dom.isBlock); 8086 8087 if (sb) 8088 bl.push(sb); 8089 8090 if (sb && eb && sb != eb) { 8091 n = sb; 8092 8093 while ((n = n.nextSibling) && n != eb) { 8094 if (dom.isBlock(n)) 8095 bl.push(n); 8096 } 8097 } 8098 8099 if (eb && sb != eb) 8100 bl.push(eb); 8101 8102 return bl; 8103 } 8104 }); 8105 })(); 8106 8107 8108 /* file:jscripts/tiny_mce/classes/UndoManager.js */ 8109 8110 tinymce.create('tinymce.UndoManager', { 8111 index : 0, 8112 data : null, 8113 typing : 0, 8114 8115 UndoManager : function(ed) { 8116 var t = this, Dispatcher = tinymce.util.Dispatcher; 8117 8118 t.editor = ed; 8119 t.data = []; 8120 t.onAdd = new Dispatcher(this); 8121 t.onUndo = new Dispatcher(this); 8122 t.onRedo = new Dispatcher(this); 8123 }, 8124 8125 add : function(l) { 8126 var t = this, i, ed = t.editor, b, s = ed.settings, la; 8127 8128 l = l || {}; 8129 l.content = l.content || ed.getContent({format : 'raw', no_events : 1}); 8130 8131 // Add undo level if needed 8132 l.content = l.content.replace(/^\s*|\s*$/g, ''); 8133 la = t.data[t.index > 0 ? t.index - 1 : 0]; 8134 if (!l.initial && la && l.content == la.content) 8135 return null; 8136 8137 // Time to compress 8138 if (s.custom_undo_redo_levels) { 8139 if (t.data.length > s.custom_undo_redo_levels) { 8140 for (i = 0; i < t.data.length - 1; i++) 8141 t.data[i] = t.data[i + 1]; 8142 8143 t.data.length--; 8144 t.index = t.data.length; 8145 } 8146 } 8147 8148 if (s.custom_undo_redo_restore_selection) 8149 l.bookmark = b = l.bookmark || ed.selection.getBookmark(); 8150 8151 if (t.index < t.data.length && t.data[t.index].initial) 8152 t.index++; 8153 8154 // Add level 8155 t.data.length = t.index + 1; 8156 t.data[t.index++] = l; 8157 8158 if (l.initial) 8159 t.index = 0; 8160 8161 // Set initial bookmark use first real undo level 8162 if (t.data.length == 2 && t.data[0].initial) 8163 t.data[0].bookmark = b; 8164 8165 t.onAdd.dispatch(t, l); 8166 8167 //console.dir(t.data); 8168 8169 return l; 8170 }, 8171 8172 undo : function() { 8173 var t = this, ed = t.editor, l = l, i; 8174 8175 if (t.typing) { 8176 t.add(); 8177 t.typing = 0; 8178 } 8179 8180 if (t.index > 0) { 8181 // If undo on last index then take snapshot 8182 if (t.index == t.data.length && t.index > 1) { 8183 i = t.index; 8184 t.typing = 0; 8185 8186 if (!t.add()) 8187 t.index = i; 8188 8189 --t.index; 8190 } 8191 8192 l = t.data[--t.index]; 8193 ed.setContent(l.content, {format : 'raw'}); 8194 ed.selection.moveToBookmark(l.bookmark); 8195 8196 t.onUndo.dispatch(t, l); 8197 } 8198 8199 return l; 8200 }, 8201 8202 redo : function() { 8203 var t = this, ed = t.editor, l = null; 8204 8205 if (t.index < t.data.length - 1) { 8206 l = t.data[++t.index]; 8207 ed.setContent(l.content, {format : 'raw'}); 8208 ed.selection.moveToBookmark(l.bookmark); 8209 8210 t.onRedo.dispatch(t, l); 8211 } 8212 8213 return l; 8214 }, 8215 8216 clear : function() { 8217 var t = this; 8218 8219 t.data = []; 8220 t.index = 0; 8221 t.typing = 0; 8222 t.add({initial : true}); 8223 }, 8224 8225 hasUndo : function() { 8226 return this.index != 0 || this.typing; 8227 }, 8228 8229 hasRedo : function() { 8230 return this.index < this.data.length - 1; 8231 } 8232 8233 }); 8234 /* file:jscripts/tiny_mce/classes/ForceBlocks.js */ 8235 8236 (function() { 8237 // Shorten names 8238 var Event, isIE, isGecko, isOpera, each, extend; 8239 8240 Event = tinymce.dom.Event; 8241 isIE = tinymce.isIE; 8242 isGecko = tinymce.isGecko; 8243 isOpera = tinymce.isOpera; 8244 each = tinymce.each; 8245 extend = tinymce.extend; 8246 8247 tinymce.create('tinymce.ForceBlocks', { 8248 ForceBlocks : function(ed) { 8249 var t = this, s; 8250 8251 t.editor = ed; 8252 t.dom = ed.dom; 8253 8254 // Default settings 8255 t.settings = s = extend({ 8256 element : 'P', 8257 forced_root_block : 'p', 8258 force_p_newlines : true 8259 }, ed.settings); 8260 8261 ed.onPreInit.add(t.setup, t); 8262 8263 if (!isIE) { 8264 ed.onSetContent.add(function(ed, o) { 8265 o.content = o.content.replace(/<p>[\s\u00a0]+<\/p>/g, '<p><br /></p>'); 8266 }); 8267 } 8268 8269 ed.onPostProcess.add(function(ed, o) { 8270 if (isOpera) 8271 o.content = o.content.replace(/(\u00a0| | )<\/p>/g, '</p>'); 8272 8273 o.content = o.content.replace(/<p><\/p>/g, '<p>\u00a0</p>'); 8274 8275 // Use BR instead of padded paragraphs 8276 o.content = o.content.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>\u00a0</p>'); 8277 o.content = o.content.replace(/\s*<br \/>\s*<\/p>/g, '</p>'); 8278 }); 8279 8280 if (s.forced_root_block) { 8281 ed.onInit.add(t.forceRoots, t); 8282 ed.onSetContent.add(t.forceRoots, t); 8283 ed.onBeforeGetContent.add(t.forceRoots, t); 8284 } 8285 }, 8286 8287 setup : function() { 8288 var t = this, ed = t.editor, s = t.settings; 8289 8290 // Force root blocks when typing and when getting output 8291 if (s.forced_root_block) { 8292 ed.onKeyUp.add(t.forceRoots, t); 8293 ed.onPreProcess.add(t.forceRoots, t); 8294 } 8295 8296 if (s.force_br_newlines) { 8297 // Force IE to produce BRs on enter 8298 if (isIE) { 8299 ed.onKeyPress.add(function(ed, e) { 8300 var n, s = ed.selection; 8301 8302 if (e.keyCode == 13) { 8303 s.setContent('<br id="__" /> ', {format : 'raw'}); 8304 n = ed.dom.get('__'); 8305 n.removeAttribute('id'); 8306 s.select(n); 8307 s.collapse(); 8308 return Event.cancel(e); 8309 } 8310 }); 8311 } 8312 8313 return; 8314 } 8315 8316 if (!isIE && s.force_p_newlines) { 8317 ed.onPreProcess.add(function(ed, o) { 8318 each(ed.dom.select('br', o.node), function(n) { 8319 var p = n.parentNode; 8320 8321 // Replace <p><br /></p> with <p> </p> 8322 if (p && p.nodeName == 'p' && (p.childNodes.length == 1 || p.lastChild == n)) 8323 p.replaceChild(ed.getDoc().createTextNode('\u00a0'), n); 8324 }); 8325 }); 8326 8327 ed.onKeyPress.add(function(ed, e) { 8328 if (e.keyCode == 13 && !e.shiftKey) { 8329 if (!t.insertPara(e)) 8330 Event.cancel(e); 8331 } 8332 }); 8333 8334 if (isGecko) { 8335 ed.onKeyDown.add(function(ed, e) { 8336 if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) 8337 t.backspaceDelete(e, e.keyCode == 8); 8338 }); 8339 } 8340 } 8341 }, 8342 8343 find : function(n, t, s) { 8344 var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1; 8345 8346 while (n = w.nextNode()) { 8347 c++; 8348 8349 // Index by node 8350 if (t == 0 && n == s) 8351 return c; 8352 8353 // Node by index 8354 if (t == 1 && c == s) 8355 return n; 8356 } 8357 8358 return -1; 8359 }, 8360 8361 forceRoots : function(ed, e) { 8362 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; 8363 var nx, bl, bp, sp, le, nl = b.childNodes, i; 8364 8365 // Fix for bug #1863847 8366 if (e && e.keyCode == 13) 6465 8367 return true; 6466 } 6467 6468 win.focus(); 6469 6470 if (bookmark.tag) { 6471 rng = b.createControlRange(); 6472 6473 nl = b.getElementsByTagName(bookmark.tag); 6474 6475 if (nl.length > bookmark.index) { 8368 8369 // Wrap non blocks into blocks 8370 for (i = nl.length - 1; i >= 0; i--) { 8371 nx = nl[i]; 8372 8373 // Is text or non block element 8374 if (nx.nodeType == 3 || !t.dom.isBlock(nx)) { 8375 if (!bl) { 8376 // Create new block but ignore whitespace 8377 if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) { 8378 // Store selection 8379 if (si == -2 && r) { 8380 if (!isIE) { 8381 so = r.startOffset; 8382 eo = r.endOffset; 8383 si = t.find(b, 0, r.startContainer); 8384 ei = t.find(b, 0, r.endContainer); 8385 } else { 8386 tr = d.body.createTextRange(); 8387 tr.moveToElementText(b); 8388 tr.collapse(1); 8389 bp = tr.move('character', c) * -1; 8390 8391 tr = r.duplicate(); 8392 tr.collapse(1); 8393 sp = tr.move('character', c) * -1; 8394 8395 tr = r.duplicate(); 8396 tr.collapse(0); 8397 le = (tr.move('character', c) * -1) - sp; 8398 8399 si = sp - bp; 8400 ei = le; 8401 } 8402 } 8403 8404 bl = ed.dom.create(t.settings.forced_root_block); 8405 bl.appendChild(nx.cloneNode(1)); 8406 b.replaceChild(bl, nx); 8407 } 8408 } else { 8409 if (bl.hasChildNodes()) 8410 bl.insertBefore(nx, bl.firstChild); 8411 else 8412 bl.appendChild(nx); 8413 } 8414 } else 8415 bl = null; // Time to create new block 8416 } 8417 8418 // Restore selection 8419 if (si != -2) { 8420 if (!isIE) { 8421 bl = d.getElementsByTagName(t.settings.element)[0]; 8422 r = d.createRange(); 8423 8424 // Select last location or generated block 8425 if (si != -1) 8426 r.setStart(t.find(b, 1, si), so); 8427 else 8428 r.setStart(bl, 0); 8429 8430 // Select last location or generated block 8431 if (ei != -1) 8432 r.setEnd(t.find(b, 1, ei), eo); 8433 else 8434 r.setEnd(bl, 0); 8435 8436 if (s) { 8437 s.removeAllRanges(); 8438 s.addRange(r); 8439 } 8440 } else { 6476 8441 try { 6477 rng.addElement(nl[bookmark.index]); 8442 r = s.createRange(); 8443 r.moveToElementText(b); 8444 r.collapse(1); 8445 r.moveStart('character', si); 8446 r.moveEnd('character', ei); 8447 r.select(); 6478 8448 } catch (ex) { 6479 // Might be thrown if the node no longer exists8449 // Ignore 6480 8450 } 6481 8451 } 8452 } 8453 }, 8454 8455 getParentBlock : function(n) { 8456 var d = this.dom; 8457 8458 return d.getParent(n, d.isBlock); 8459 }, 8460 8461 insertPara : function(e) { 8462 var t = this, ed = t.editor, d = ed.getDoc(), se = t.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body; 8463 var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n; 8464 8465 function isEmpty(n) { 8466 n = n.innerHTML; 8467 n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars 8468 n = n.replace(/<[^>]+>/g, ''); // Remove all tags 8469 8470 return n.replace(/[ \t\r\n]+/g, '') == ''; 8471 }; 8472 8473 // If root blocks are forced then use Operas default behavior since it's really good 8474 // Removed due to bug: #1853816 8475 // if (se.forced_root_block && isOpera) 8476 // return true; 8477 8478 // Setup before range 8479 rb = d.createRange(); 8480 8481 // If is before the first block element and in body, then move it into first block element 8482 rb.setStart(s.anchorNode, s.anchorOffset); 8483 rb.collapse(true); 8484 8485 // Setup after range 8486 ra = d.createRange(); 8487 8488 // If is before the first block element and in body, then move it into first block element 8489 ra.setStart(s.focusNode, s.focusOffset); 8490 ra.collapse(true); 8491 8492 // Setup start/end points 8493 dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0; 8494 sn = dir ? s.anchorNode : s.focusNode; 8495 so = dir ? s.anchorOffset : s.focusOffset; 8496 en = dir ? s.focusNode : s.anchorNode; 8497 eo = dir ? s.focusOffset : s.anchorOffset; 8498 8499 // If the caret is in an invalid location in FF we need to move it into the first block 8500 if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) { 8501 sn = en = sn.firstChild; 8502 so = eo = 0; 8503 rb = d.createRange(); 8504 rb.setStart(sn, 0); 8505 ra = d.createRange(); 8506 ra.setStart(en, 0); 8507 } 8508 8509 // Never use body as start or end node 8510 sn = sn.nodeName == "BODY" ? sn.firstChild : sn; 8511 en = en.nodeName == "BODY" ? en.firstChild : en; 8512 8513 // Get start and end blocks 8514 sb = t.getParentBlock(sn); 8515 eb = t.getParentBlock(en); 8516 bn = sb ? sb.nodeName : se.element; // Get block name to create 8517 8518 // Return inside list use default browser behavior 8519 if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); })) 8520 return true; 8521 8522 // If caption or absolute layers then always generate new blocks within 8523 if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) { 8524 bn = se.element; 8525 sb = null; 8526 } 8527 8528 // If caption or absolute layers then always generate new blocks within 8529 if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) { 8530 bn = se.element; 8531 eb = null; 8532 } 8533 8534 // Use P instead 8535 if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) { 8536 bn = se.element; 8537 sb = eb = null; 8538 } 8539 8540 // Setup new before and after blocks 8541 bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn); 8542 aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn); 8543 8544 // Remove id from after clone 8545 aft.removeAttribute('id'); 8546 8547 // Is header and cursor is at the end, then force paragraph under 8548 if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length) 8549 aft = ed.dom.create(se.element); 8550 8551 // Find start chop node 8552 n = sc = sn; 8553 do { 8554 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) 8555 break; 8556 8557 sc = n; 8558 } while ((n = n.previousSibling ? n.previousSibling : n.parentNode)); 8559 8560 // Find end chop node 8561 n = ec = en; 8562 do { 8563 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) 8564 break; 8565 8566 ec = n; 8567 } while ((n = n.nextSibling ? n.nextSibling : n.parentNode)); 8568 8569 // Place first chop part into before block element 8570 if (sc.nodeName == bn) 8571 rb.setStart(sc, 0); 8572 else 8573 rb.setStartBefore(sc); 8574 8575 rb.setEnd(sn, so); 8576 bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari 8577 8578 // Place secnd chop part within new block element 8579 try { 8580 ra.setEndAfter(ec); 8581 } catch(ex) { 8582 //console.debug(s.focusNode, s.focusOffset); 8583 } 8584 8585 ra.setStart(en, eo); 8586 aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari 8587 8588 // Create range around everything 8589 r = d.createRange(); 8590 if (!sc.previousSibling && sc.parentNode.nodeName == bn) { 8591 r.setStartBefore(sc.parentNode); 6482 8592 } else { 6483 // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs 6484 try { 6485 // Incorrect bookmark 6486 if (bookmark.start < 0) 6487 return true; 6488 6489 rng = inst.getSel().createRange(); 6490 rng.moveToElementText(inst.getBody()); 6491 rng.collapse(true); 6492 rng.moveStart('character', bookmark.start); 6493 rng.moveEnd('character', bookmark.length); 6494 } catch (ex) { 6495 return true; 6496 } 6497 } 6498 6499 rng.select(); 6500 6501 win.scrollTo(bookmark.scrollX, bookmark.scrollY); 6502 return true; 8593 if (rb.startContainer.nodeName == bn && rb.startOffset == 0) 8594 r.setStartBefore(rb.startContainer); 8595 else 8596 r.setStart(rb.startContainer, rb.startOffset); 8597 } 8598 8599 if (!ec.nextSibling && ec.parentNode.nodeName == bn) 8600 r.setEndAfter(ec.parentNode); 8601 else 8602 r.setEnd(ra.endContainer, ra.endOffset); 8603 8604 // Delete and replace it with new block elements 8605 r.deleteContents(); 8606 8607 // Never wrap blocks in blocks 8608 if (bef.firstChild && bef.firstChild.nodeName == bn) 8609 bef.innerHTML = bef.firstChild.innerHTML; 8610 8611 if (aft.firstChild && aft.firstChild.nodeName == bn) 8612 aft.innerHTML = aft.firstChild.innerHTML; 8613 8614 // Padd empty blocks 8615 if (isEmpty(bef)) 8616 bef.innerHTML = '<br />'; 8617 8618 if (isEmpty(aft)) 8619 aft.innerHTML = isOpera ? ' ' : '<br />'; // Extra space for Opera so that the caret can move there 8620 8621 // Opera needs this one backwards 8622 if (isOpera) { 8623 r.insertNode(bef); 8624 r.insertNode(aft); 8625 } else { 8626 r.insertNode(aft); 8627 r.insertNode(bef); 8628 } 8629 8630 // Normalize 8631 aft.normalize(); 8632 bef.normalize(); 8633 8634 // Move cursor and scroll into view 8635 r = d.createRange(); 8636 r.selectNodeContents(aft); 8637 r.collapse(1); 8638 s.removeAllRanges(); 8639 s.addRange(r); 8640 aft.scrollIntoView(0); 8641 8642 return false; 8643 }, 8644 8645 backspaceDelete : function(e, bs) { 8646 var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n; 8647 8648 // The caret sometimes gets stuck in Gecko if you delete empty paragraphs 8649 // This workaround removes the element by hand and moves the caret to the previous element 8650 if (sc && ed.dom.isBlock(sc) && bs) { 8651 if (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR') { 8652 n = sc.previousSibling; 8653 if (n) { 8654 ed.dom.remove(sc); 8655 se.select(n, 1); 8656 se.collapse(0); 8657 return Event.cancel(e); 8658 } 8659 } 8660 } 8661 8662 // Gecko generates BR elements here and there, we don't like those so lets remove them 8663 function handler(e) { 8664 e = e.target; 8665 8666 // A new BR was created in a block element, remove it 8667 if (e && e.parentNode && e.nodeName == 'BR' && t.getParentBlock(e)) { 8668 ed.dom.remove(e); 8669 Event.remove(b, 'DOMNodeInserted', handler); 8670 } 8671 }; 8672 8673 // Listen for new nodes 8674 Event._add(b, 'DOMNodeInserted', handler); 8675 8676 // Remove listener 8677 window.setTimeout(function() { 8678 Event._remove(b, 'DOMNodeInserted', handler); 8679 }, 1); 6503 8680 } 6504 6505 if (tinyMCE.isGecko || tinyMCE.isOpera) { 6506 if (!sel) 6507 return false; 6508 6509 if (bookmark.rng) { 6510 sel.removeAllRanges(); 6511 sel.addRange(bookmark.rng); 6512 } 6513 6514 if (bookmark.start != -1 && bookmark.end != -1) { 6515 try { 6516 sd = this._getTextPos(b, bookmark.start, bookmark.end); 6517 rng = doc.createRange(); 6518 rng.setStart(sd.startNode, sd.startOffset); 6519 rng.setEnd(sd.endNode, sd.endOffset); 6520 sel.removeAllRanges(); 6521 sel.addRange(rng); 6522 6523 if (!tinyMCE.isOpera) 6524 win.focus(); 6525 } catch (ex) { 6526 // Ignore 6527 } 6528 } 6529 6530 /* 6531 if (typeof(bookmark.index) != 'undefined') { 6532 tinyMCE.selectElements(b, 'IMG', function (n) { 6533 if (bookmark.index-- == 0) { 6534 // Select image in Gecko here 6535 } 6536 6537 return false; 8681 }); 8682 })(); 8683 8684 /* file:jscripts/tiny_mce/classes/ControlManager.js */ 8685 8686 (function() { 8687 // Shorten names 8688 var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend; 8689 8690 tinymce.create('tinymce.ControlManager', { 8691 ControlManager : function(ed, s) { 8692 var t = this, i; 8693 8694 s = s || {}; 8695 t.editor = ed; 8696 t.controls = {}; 8697 t.onAdd = new tinymce.util.Dispatcher(t); 8698 t.onPostRender = new tinymce.util.Dispatcher(t); 8699 t.prefix = s.prefix || ed.id + '_'; 8700 8701 t.onPostRender.add(function() { 8702 each(t.controls, function(c) { 8703 c.postRender(); 6538 8704 }); 6539 } 6540 */ 6541 6542 win.scrollTo(bookmark.scrollX, bookmark.scrollY); 6543 return true; 8705 }); 8706 }, 8707 8708 get : function(id) { 8709 return this.controls[this.prefix + id] || this.controls[id]; 8710 }, 8711 8712 setActive : function(id, s) { 8713 var c = null; 8714 8715 if (c = this.get(id)) 8716 c.setActive(s); 8717 8718 return c; 8719 }, 8720 8721 setDisabled : function(id, s) { 8722 var c = null; 8723 8724 if (c = this.get(id)) 8725 c.setDisabled(s); 8726 8727 return c; 8728 }, 8729 8730 add : function(c) { 8731 var t = this; 8732 8733 if (c) { 8734 t.controls[c.id] = c; 8735 t.onAdd.dispatch(c, t); 8736 } 8737 8738 return c; 8739 }, 8740 8741 createControl : function(n) { 8742 var c, t = this, ed = t.editor; 8743 8744 each(ed.plugins, function(p) { 8745 if (p.createControl) { 8746 c = p.createControl(n, t); 8747 8748 if (c) 8749 return false; 8750 } 8751 }); 8752 8753 switch (n) { 8754 case "|": 8755 case "separator": 8756 return t.createSeparator(); 8757 } 8758 8759 if (!c && ed.buttons && (c = ed.buttons[n])) 8760 return t.createButton(n, c); 8761 8762 return t.add(c); 8763 }, 8764 8765 createDropMenu : function(id, s) { 8766 var t = this, ed = t.editor, c; 8767 8768 s = extend({ 8769 'class' : 'mceDropDown' 8770 }, s); 8771 8772 s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin'; 8773 8774 id = t.prefix + id; 8775 c = t.controls[id] = new tinymce.ui.DropMenu(id, s); 8776 c.onAddItem.add(function(c, o) { 8777 var s = o.settings; 8778 8779 s.title = ed.getLang(s.title, s.title); 8780 8781 if (!s.onclick) { 8782 s.onclick = function(v) { 8783 ed.execCommand(s.cmd, s.ui || false, v || s.value); 8784 }; 8785 } 8786 }); 8787 8788 ed.onRemove.add(function() { 8789 c.destroy(); 8790 }); 8791 8792 return t.add(c); 8793 }, 8794 8795 createListBox : function(id, s) { 8796 var t = this, ed = t.editor, cmd, c; 8797 8798 if (t.get(id)) 8799 return null; 8800 8801 s.title = ed.translate(s.title); 8802 s.scope = s.scope || ed; 8803 8804 if (!s.onselect) { 8805 s.onselect = function(v) { 8806 ed.execCommand(s.cmd, s.ui || false, v || s.value); 8807 }; 8808 } 8809 8810 s = extend({ 8811 title : s.title, 8812 'class' : id, 8813 scope : s.scope, 8814 control_manager : t 8815 }, s); 8816 8817 id = t.prefix + id; 8818 8819 if (ed.settings.use_native_selects) 8820 c = new tinymce.ui.NativeListBox(id, s); 8821 else 8822 c = new tinymce.ui.ListBox(id, s); 8823 8824 t.controls[id] = c; 8825 8826 // Fix focus problem in Safari 8827 if (tinymce.isWebKit) { 8828 c.onPostRender.add(function(c, n) { 8829 // Store bookmark on mousedown 8830 Event.add(n, 'mousedown', function() { 8831 ed.bookmark = ed.selection.getBookmark('simple'); 8832 }); 8833 8834 // Restore on focus, since it might be lost 8835 Event.add(n, 'focus', function() { 8836 ed.selection.moveToBookmark(ed.bookmark); 8837 ed.bookmark = null; 8838 }); 8839 }); 8840 } 8841 8842 if (c.hideMenu) 8843 ed.onMouseDown.add(c.hideMenu, c); 8844 8845 return t.add(c); 8846 }, 8847 8848 createButton : function(id, s) { 8849 var t = this, ed = t.editor, o, c; 8850 8851 if (t.get(id)) 8852 return null; 8853 8854 s.title = ed.translate(s.title); 8855 s.scope = s.scope || ed; 8856 8857 if (!s.onclick && !s.menu_button) { 8858 s.onclick = function() { 8859 ed.execCommand(s.cmd, s.ui || false, s.value); 8860 }; 8861 } 8862 8863 s = extend({ 8864 title : s.title, 8865 'class' : id, 8866 unavailable_prefix : ed.getLang('unavailable', ''), 8867 scope : s.scope, 8868 control_manager : t 8869 }, s); 8870 8871 id = t.prefix + id; 8872 8873 if (s.menu_button) { 8874 c = new tinymce.ui.MenuButton(id, s); 8875 ed.onMouseDown.add(c.hideMenu, c); 8876 } else 8877 c = new tinymce.ui.Button(id, s); 8878 8879 return t.add(c); 8880 }, 8881 8882 createMenuButton : function(id, s) { 8883 s = s || {}; 8884 s.menu_button = 1; 8885 8886 return this.createButton(id, s); 8887 }, 8888 8889 createSplitButton : function(id, s) { 8890 var t = this, ed = t.editor, cmd, c; 8891 8892 if (t.get(id)) 8893 return null; 8894 8895 s.title = ed.translate(s.title); 8896 s.scope = s.scope || ed; 8897 8898 if (!s.onclick) { 8899 s.onclick = function(v) { 8900 ed.execCommand(s.cmd, s.ui || false, v || s.value); 8901 }; 8902 } 8903 8904 if (!s.onselect) { 8905 s.onselect = function(v) { 8906 ed.execCommand(s.cmd, s.ui || false, v || s.value); 8907 }; 8908 } 8909 8910 s = extend({ 8911 title : s.title, 8912 'class' : id, 8913 scope : s.scope, 8914 control_manager : t 8915 }, s); 8916 8917 id = t.prefix + id; 8918 c = t.add(new tinymce.ui.SplitButton(id, s)); 8919 ed.onMouseDown.add(c.hideMenu, c); 8920 8921 return c; 8922 }, 8923 8924 createColorSplitButton : function(id, s) { 8925 var t = this, ed = t.editor, cmd, c; 8926 8927 if (t.get(id)) 8928 return null; 8929 8930 s.title = ed.translate(s.title); 8931 s.scope = s.scope || ed; 8932 8933 if (!s.onclick) { 8934 s.onclick = function(v) { 8935 ed.execCommand(s.cmd, s.ui || false, v || s.value); 8936 }; 8937 } 8938 8939 if (!s.onselect) { 8940 s.onselect = function(v) { 8941 ed.execCommand(s.cmd, s.ui || false, v || s.value); 8942 }; 8943 } 8944 8945 s = extend({ 8946 title : s.title, 8947 'class' : id, 8948 'menu_class' : ed.getParam('skin') + 'Skin', 8949 scope : s.scope, 8950 more_colors_title : ed.getLang('more_colors') 8951 }, s); 8952 8953 id = t.prefix + id; 8954 c = new tinymce.ui.ColorSplitButton(id, s); 8955 ed.onMouseDown.add(c.hideMenu, c); 8956 8957 return t.add(c); 8958 }, 8959 8960 createToolbar : function(id, s) { 8961 var c, t = this; 8962 8963 id = t.prefix + id; 8964 c = new tinymce.ui.Toolbar(id, s); 8965 8966 if (t.get(id)) 8967 return null; 8968 8969 return t.add(c); 8970 }, 8971 8972 createSeparator : function() { 8973 return new tinymce.ui.Separator(); 6544 8974 } 6545 8975 6546 return false; 6547 }, 6548 6549 _getPosText : function(r, sn, en) { 6550 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; 6551 6552 while ((n = w.nextNode()) != null) { 6553 if (n == sn) 6554 d.start = p; 6555 6556 if (n == en) { 6557 d.end = p; 6558 return d; 6559 } 6560 6561 p += n.nodeValue ? n.nodeValue.length : 0; 8976 }); 8977 })(); 8978 8979 /* file:jscripts/tiny_mce/classes/WindowManager.js */ 8980 8981 (function() { 8982 var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera; 8983 8984 tinymce.create('tinymce.WindowManager', { 8985 WindowManager : function(ed) { 8986 var t = this; 8987 8988 t.editor = ed; 8989 t.onOpen = new Dispatcher(t); 8990 t.onClose = new Dispatcher(t); 8991 t.params = {}; 8992 t.features = {}; 8993 }, 8994 8995 open : function(s, p) { 8996 var t = this, f = '', x, y, mo = t.editor.settings.dialog_type == 'modal', w, sw, sh, vp = tinymce.DOM.getViewPort(); 8997 8998 // Default some options 8999 s = s || {}; 9000 p = p || {}; 9001 sw = isOpera ? vp.w : screen.width; // Opera uses windows inside the Opera window 9002 sh = isOpera ? vp.h : screen.height; 9003 s.name = s.name || 'mc_' + new Date().getTime(); 9004 s.width = parseInt(s.width || 320); 9005 s.height = parseInt(s.height || 240); 9006 s.resizable = true; 9007 s.left = s.left || parseInt(sw / 2.0) - (s.width / 2.0); 9008 s.top = s.top || parseInt(sh / 2.0) - (s.height / 2.0); 9009 p.inline = false; 9010 p.mce_width = s.width; 9011 p.mce_height = s.height; 9012 9013 if (mo) { 9014 if (isIE) { 9015 s.center = true; 9016 s.help = false; 9017 s.dialogWidth = s.width + 'px'; 9018 s.dialogHeight = s.height + 'px'; 9019 s.scroll = s.scrollbars || false; 9020 } else 9021 s.modal = s.alwaysRaised = s.dialog = s.centerscreen = s.dependent = true; 9022 } 9023 9024 // Build features string 9025 each(s, function(v, k) { 9026 if (tinymce.is(v, 'boolean')) 9027 v = v ? 'yes' : 'no'; 9028 9029 if (!/^(name|url)$/.test(k)) { 9030 if (isIE && mo) 9031 f += (f ? ';' : '') + k + ':' + v; 9032 else 9033 f += (f ? ',' : '') + k + '=' + v; 9034 } 9035 }); 9036 9037 t.features = s; 9038 t.params = p; 9039 t.onOpen.dispatch(t, s, p); 9040 9041 try { 9042 if (isIE && mo) { 9043 w = 1; 9044 window.showModalDialog(s.url || s.file, window, f); 9045 } else 9046 w = window.open(s.url || s.file, s.name, f); 9047 } catch (ex) { 9048 // Ignore 9049 } 9050 9051 if (!w) 9052 alert(t.editor.getLang('popup_blocked')); 9053 }, 9054 9055 close : function(w) { 9056 w.close(); 9057 this.onClose.dispatch(this); 9058 }, 9059 9060 createInstance : function(cl) { 9061 var a = arguments, i, f = tinymce.resolve(cl), s = ''; 9062 9063 // Is there a better way to dynamically create 9064 // a class with a dynamic number of arguments 9065 for (i=1; i<a.length; i++) 9066 s += (i > 1 ? ',' : '') + 'a[' + i + ']'; 9067 9068 return eval('(new f(' + s + '))'); 9069 }, 9070 9071 confirm : function(t, cb, s) { 9072 cb.call(s || this, confirm(this._decode(this.editor.getLang(t, t)))); 9073 }, 9074 9075 alert : function(t, cb, s) { 9076 alert(this._decode(t)); 9077 9078 if (cb) 9079 cb.call(s || this); 9080 }, 9081 9082 // Internal functions 9083 9084 _decode : function(s) { 9085 return tinymce.DOM.decode(s).replace(/\\n/g, '\n'); 6562 9086 } 6563 9087 6564 return null; 6565 }, 6566 6567 _getTextPos : function(r, sp, ep) { 6568 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; 6569 6570 while ((n = w.nextNode()) != null) { 6571 p += n.nodeValue ? n.nodeValue.length : 0; 6572 6573 if (p >= sp && !d.startNode) { 6574 d.startNode = n; 6575 d.startOffset = sp - (p - n.nodeValue.length); 6576 } 6577 6578 if (p >= ep) { 6579 d.endNode = n; 6580 d.endOffset = ep - (p - n.nodeValue.length); 6581 6582 return d; 6583 } 6584 } 6585 6586 return null; 6587 }, 6588 6589 selectNode : function(node, collapse, select_text_node, to_start) { 6590 var inst = this.instance, sel, rng, nodes; 6591 6592 if (!node) 6593 return; 6594 6595 if (typeof(collapse) == "undefined") 6596 collapse = true; 6597 6598 if (typeof(select_text_node) == "undefined") 6599 select_text_node = false; 6600 6601 if (typeof(to_start) == "undefined") 6602 to_start = true; 6603 6604 if (inst.settings.auto_resize) 6605 inst.resizeToContent(); 6606 6607 if (tinyMCE.isRealIE) { 6608 rng = inst.getDoc().body.createTextRange(); 6609 6610 try { 6611 rng.moveToElementText(node); 6612 6613 if (collapse) 6614 rng.collapse(to_start); 6615 6616 rng.select(); 6617 } catch (e) { 6618 // Throws illigal agrument in MSIE some times 6619 } 6620 } else { 6621 sel = this.getSel(); 6622 6623 if (!sel) 6624 return; 6625 6626 if (tinyMCE.isSafari) { 6627 sel.setBaseAndExtent(node, 0, node, node.innerText.length); 6628 6629 if (collapse) { 6630 if (to_start) 6631 sel.collapseToStart(); 6632 else 6633 sel.collapseToEnd(); 6634 } 6635 6636 this.scrollToNode(node); 6637 6638 return; 6639 } 6640 6641 rng = inst.getDoc().createRange(); 6642 6643 if (select_text_node) { 6644 // Find first textnode in tree 6645 nodes = tinyMCE.getNodeTree(node, [], 3); 6646 if (nodes.length > 0) 6647 rng.selectNodeContents(nodes[0]); 6648 else 6649 rng.selectNodeContents(node); 6650 } else 6651 rng.selectNode(node); 6652 6653 if (collapse) { 6654 // Special treatment of textnode collapse 6655 if (!to_start && node.nodeType == 3) { 6656 rng.setStart(node, node.nodeValue.length); 6657 rng.setEnd(node, node.nodeValue.length); 6658 } else 6659 rng.collapse(to_start); 6660 } 6661 6662 sel.removeAllRanges(); 6663 sel.addRange(rng); 6664 } 6665 6666 this.scrollToNode(node); 6667 6668 // Set selected element 6669 tinyMCE.selectedElement = null; 6670 if (node.nodeType == 1) 6671 tinyMCE.selectedElement = node; 6672 }, 6673 6674 scrollToNode : function(node) { 6675 var inst = this.instance, w = inst.getWin(), vp = inst.getViewPort(), pos = tinyMCE.getAbsPosition(node), cvp, p, cwin; 6676 6677 // Only scroll if out of visible area 6678 if (pos.absLeft < vp.left || pos.absLeft > vp.left + vp.width || pos.absTop < vp.top || pos.absTop > vp.top + (vp.height-25)) 6679 w.scrollTo(pos.absLeft, pos.absTop - vp.height + 25); 6680 6681 // Scroll container window 6682 if (inst.settings.auto_resize) { 6683 cwin = inst.getContainerWin(); 6684 cvp = tinyMCE.getViewPort(cwin); 6685 p = this.getAbsPosition(node); 6686 6687 if (p.absLeft < cvp.left || p.absLeft > cvp.left + cvp.width || p.absTop < cvp.top || p.absTop > cvp.top + cvp.height) 6688 cwin.scrollTo(p.absLeft, p.absTop - cvp.height + 25); 6689 } 6690 }, 6691 6692 getAbsPosition : function(n) { 6693 var pos = tinyMCE.getAbsPosition(n), ipos = tinyMCE.getAbsPosition(this.instance.iframeElement); 6694 6695 return { 6696 absLeft : ipos.absLeft + pos.absLeft, 6697 absTop : ipos.absTop + pos.absTop 6698 }; 6699 }, 6700 6701 getSel : function() { 6702 var inst = this.instance; 6703 6704 if (tinyMCE.isRealIE) 6705 return inst.getDoc().selection; 6706 6707 return inst.contentWindow.getSelection(); 6708 }, 6709 6710 getRng : function() { 6711 var s = this.getSel(); 6712 6713 if (s == null) 6714 return null; 6715 6716 if (tinyMCE.isRealIE) 6717 return s.createRange(); 6718 6719 if (tinyMCE.isSafari && !s.getRangeAt) 6720 return '' + window.getSelection(); 6721 6722 if (s.rangeCount > 0) 6723 return s.getRangeAt(0); 6724 6725 return null; 6726 }, 6727 6728 isCollapsed : function() { 6729 var r = this.getRng(); 6730 6731 if (r.item) 6732 return false; 6733 6734 return r.boundingWidth == 0 || this.getSel().isCollapsed; 6735 }, 6736 6737 collapse : function(b) { 6738 var r = this.getRng(), s = this.getSel(); 6739 6740 if (r.select) { 6741 r.collapse(b); 6742 r.select(); 6743 } else { 6744 if (b) 6745 s.collapseToStart(); 6746 else 6747 s.collapseToEnd(); 6748 } 6749 }, 6750 6751 getFocusElement : function() { 6752 var inst = this.instance, doc, rng, sel, elm; 6753 6754 if (tinyMCE.isRealIE) { 6755 doc = inst.getDoc(); 6756 rng = doc.selection.createRange(); 6757 6758 // if (rng.collapse) 6759 // rng.collapse(true); 6760 6761 elm = rng.item ? rng.item(0) : rng.parentElement(); 6762 } else { 6763 if (!tinyMCE.isSafari && inst.isHidden()) 6764 return inst.getBody(); 6765 6766 sel = this.getSel(); 6767 rng = this.getRng(); 6768 6769 if (!sel || !rng) 6770 return null; 6771 6772 elm = rng.commonAncestorContainer; 6773 //elm = (sel && sel.anchorNode) ? sel.anchorNode : null; 6774 6775 // Handle selection a image or other control like element such as anchors 6776 if (!rng.collapsed) { 6777 // Is selection small 6778 if (rng.startContainer == rng.endContainer) { 6779 if (rng.startOffset - rng.endOffset < 2) { 6780 if (rng.startContainer.hasChildNodes()) 6781 elm = rng.startContainer.childNodes[rng.startOffset]; 6782 } 6783 } 6784 } 6785 6786 // Get the element parent of the node 6787 elm = tinyMCE.getParentElement(elm); 6788 6789 //if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") 6790 // elm = tinyMCE.selectedElement; 6791 } 6792 6793 return elm; 6794 } 6795 6796 }; 6797 6798 /* file:jscripts/tiny_mce/classes/TinyMCE_UndoRedo.class.js */ 6799 6800 function TinyMCE_UndoRedo(inst) { 6801 this.instance = inst; 6802 this.undoLevels = []; 6803 this.undoIndex = 0; 6804 this.typingUndoIndex = -1; 6805 this.undoRedo = true; 6806 }; 6807 6808 TinyMCE_UndoRedo.prototype = { 6809 add : function(l) { 6810 var b, customUndoLevels, newHTML, inst = this.instance, i, ul, ur; 6811 6812 if (l) { 6813 this.undoLevels[this.undoLevels.length] = l; 6814 return true; 6815 } 6816 6817 if (this.typingUndoIndex != -1) { 6818 this.undoIndex = this.typingUndoIndex; 6819 6820 if (tinyMCE.typingUndoIndex != -1) 6821 tinyMCE.undoIndex = tinyMCE.typingUndoIndex; 6822 } 6823 6824 newHTML = tinyMCE.trim(inst.getBody().innerHTML); 6825 if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) { 6826 //tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content); 6827 6828 // Is dirty again 6829 inst.isNotDirty = false; 6830 6831 tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst); 6832 6833 // Time to compress 6834 customUndoLevels = tinyMCE.settings.custom_undo_redo_levels; 6835 if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) { 6836 for (i=0; i<this.undoLevels.length-1; i++) 6837 this.undoLevels[i] = this.undoLevels[i+1]; 6838 6839 this.undoLevels.length--; 6840 this.undoIndex--; 6841 6842 // Todo: Implement global undo/redo logic here 6843 } 6844 6845 b = inst.undoBookmark; 6846 6847 if (!b) 6848 b = inst.selection.getBookmark(); 6849 6850 this.undoIndex++; 6851 this.undoLevels[this.undoIndex] = { 6852 content : newHTML, 6853 bookmark : b 6854 }; 6855 6856 // Remove all above from global undo/redo 6857 ul = tinyMCE.undoLevels; 6858 for (i=tinyMCE.undoIndex + 1; i<ul.length; i++) { 6859 ur = ul[i].undoRedo; 6860 6861 if (ur.undoIndex == ur.undoLevels.length -1) 6862 ur.undoIndex--; 6863 6864 ur.undoLevels.length--; 6865 } 6866 6867 // Add global undo level 6868 tinyMCE.undoLevels[tinyMCE.undoIndex++] = inst; 6869 tinyMCE.undoLevels.length = tinyMCE.undoIndex; 6870 6871 this.undoLevels.length = this.undoIndex + 1; 6872 6873 return true; 6874 } 6875 6876 return false; 6877 }, 6878 6879 undo : function() { 6880 var inst = this.instance; 6881 6882 // Do undo 6883 if (this.undoIndex > 0) { 6884 this.undoIndex--; 6885 6886 tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); 6887 inst.repaint(); 6888 6889 if (inst.settings.custom_undo_redo_restore_selection) 6890 inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); 6891 } 6892 }, 6893 6894 redo : function() { 6895 var inst = this.instance; 6896 6897 tinyMCE.execCommand("mceEndTyping"); 6898 6899 if (this.undoIndex < (this.undoLevels.length-1)) { 6900 this.undoIndex++; 6901 6902 tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); 6903 inst.repaint(); 6904 6905 if (inst.settings.custom_undo_redo_restore_selection) 6906 inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); 6907 } 6908 6909 tinyMCE.triggerNodeChange(); 6910 } 6911 6912 }; 6913 6914 /* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */ 6915 6916 var TinyMCE_ForceParagraphs = { 6917 _insertPara : function(inst, e) { 6918 var doc = inst.getDoc(), sel = inst.getSel(), body = inst.getBody(), win = inst.contentWindow, rng = sel.getRangeAt(0); 6919 var rootElm = doc.documentElement, blockName = "P", startNode, endNode, startBlock, endBlock; 6920 var rngBefore, rngAfter, direct, startNode, startOffset, endNode, endOffset, b = tinyMCE.isOpera ? inst.selection.getBookmark() : null; 6921 var paraBefore, paraAfter, startChop, endChop, contents, i; 6922 6923 function isEmpty(para) { 6924 var nodes; 6925 6926 function isEmptyHTML(html) { 6927 return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == ''; 6928 } 6929 6930 // Check for images 6931 if (para.getElementsByTagName("img").length > 0) 6932 return false; 6933 6934 // Check for tables 6935 if (para.getElementsByTagName("table").length > 0) 6936 return false; 6937 6938 // Check for HRs 6939 if (para.getElementsByTagName("hr").length > 0) 6940 return false; 6941 6942 // Check all textnodes 6943 nodes = tinyMCE.getNodeTree(para, [], 3); 6944 for (i=0; i<nodes.length; i++) { 6945 if (!isEmptyHTML(nodes[i].nodeValue)) 6946 return false; 6947 } 6948 6949 // No images, no tables, no hrs, no text content then it's empty 6950 return true; 6951 } 6952 6953 // tinyMCE.debug(body.innerHTML); 6954 6955 // debug(e.target, sel.anchorNode.nodeName, sel.focusNode.nodeName, rng.startContainer, rng.endContainer, rng.commonAncestorContainer, sel.anchorOffset, sel.focusOffset, rng.toString()); 6956 6957 // Setup before range 6958 rngBefore = doc.createRange(); 6959 rngBefore.setStart(sel.anchorNode, sel.anchorOffset); 6960 rngBefore.collapse(true); 6961 6962 // Setup after range 6963 rngAfter = doc.createRange(); 6964 rngAfter.setStart(sel.focusNode, sel.focusOffset); 6965 rngAfter.collapse(true); 6966 6967 // Setup start/end points 6968 direct = rngBefore.compareBoundaryPoints(rngBefore.START_TO_END, rngAfter) < 0; 6969 startNode = direct ? sel.anchorNode : sel.focusNode; 6970 startOffset = direct ? sel.anchorOffset : sel.focusOffset; 6971 endNode = direct ? sel.focusNode : sel.anchorNode; 6972 endOffset = direct ? sel.focusOffset : sel.anchorOffset; 6973 6974 startNode = startNode.nodeName == "BODY" ? startNode.firstChild : startNode; 6975 endNode = endNode.nodeName == "BODY" ? endNode.firstChild : endNode; 6976 6977 // Get block elements 6978 startBlock = inst.getParentBlockElement(startNode); 6979 endBlock = inst.getParentBlockElement(endNode); 6980 6981 // If absolute force paragraph generation within 6982 if (startBlock && (startBlock.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(startBlock.style.position))) 6983 startBlock = null; 6984 6985 if (endBlock && (endBlock.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(endBlock.style.position))) 6986 endBlock = null; 6987 6988 // Use current block name 6989 if (startBlock != null) { 6990 blockName = startBlock.nodeName; 6991 6992 // Use P instead 6993 if (/(TD|TABLE|TH|CAPTION)/.test(blockName) || (blockName == "DIV" && /left|right/gi.test(startBlock.style.cssFloat))) 6994 blockName = "P"; 6995 } 6996 6997 // Within a list use normal behaviour 6998 if (tinyMCE.getParentElement(startBlock, "OL,UL", null, body) != null) 6999 return false; 7000 7001 // Within a table create new paragraphs 7002 if ((startBlock != null && startBlock.nodeName == "TABLE") || (endBlock != null && endBlock.nodeName == "TABLE")) 7003 startBlock = endBlock = null; 7004 7005 // Setup new paragraphs 7006 paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName); 7007 paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName); 7008 7009 // Is header, then force paragraph under 7010 if (/^(H[1-6])$/.test(blockName)) 7011 paraAfter = doc.createElement("p"); 7012 7013 // Setup chop nodes 7014 startChop = startNode; 7015 endChop = endNode; 7016 7017 // Get startChop node 7018 node = startChop; 7019 do { 7020 if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node)) 7021 break; 7022 7023 startChop = node; 7024 } while ((node = node.previousSibling ? node.previousSibling : node.parentNode)); 7025 7026 // Get endChop node 7027 node = endChop; 7028 do { 7029 if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node)) 7030 break; 7031 7032 endChop = node; 7033 } while ((node = node.nextSibling ? node.nextSibling : node.parentNode)); 7034 7035 // Fix when only a image is within the TD 7036 if (startChop.nodeName == "TD") 7037 startChop = startChop.firstChild; 7038 7039 if (endChop.nodeName == "TD") 7040 endChop = endChop.lastChild; 7041 7042 // If not in a block element 7043 if (startBlock == null) { 7044 // Delete selection 7045 rng.deleteContents(); 7046 7047 if (!tinyMCE.isSafari) 7048 sel.removeAllRanges(); 7049 7050 if (startChop != rootElm && endChop != rootElm) { 7051 // Insert paragraph before 7052 rngBefore = rng.cloneRange(); 7053 7054 if (startChop == body) 7055 rngBefore.setStart(startChop, 0); 7056 else 7057 rngBefore.setStartBefore(startChop); 7058 7059 paraBefore.appendChild(rngBefore.cloneContents()); 7060 7061 // Insert paragraph after 7062 if (endChop.parentNode.nodeName == blockName) 7063 endChop = endChop.parentNode; 7064 7065 // If not after image 7066 //if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY") 7067 rng.setEndAfter(endChop); 7068 7069 if (endChop.nodeName != "#text" && endChop.nodeName != "BODY") 7070 rngBefore.setEndAfter(endChop); 7071 7072 contents = rng.cloneContents(); 7073 if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY")) 7074 paraAfter.innerHTML = contents.firstChild.innerHTML; 7075 else 7076 paraAfter.appendChild(contents); 7077 7078 // Check if it's a empty paragraph 7079 if (isEmpty(paraBefore)) 7080 paraBefore.innerHTML = " "; 7081 7082 // Check if it's a empty paragraph 7083 if (isEmpty(paraAfter)) 7084 paraAfter.innerHTML = " "; 7085 7086 // Delete old contents 7087 rng.deleteContents(); 7088 rngAfter.deleteContents(); 7089 rngBefore.deleteContents(); 7090 7091 // Insert new paragraphs 7092 if (tinyMCE.isOpera) { 7093 paraBefore.normalize(); 7094 rngBefore.insertNode(paraBefore); 7095 paraAfter.normalize(); 7096 rngBefore.insertNode(paraAfter); 7097 } else { 7098 paraAfter.normalize(); 7099 rngBefore.insertNode(paraAfter); 7100 paraBefore.normalize(); 7101 rngBefore.insertNode(paraBefore); 7102 } 7103 7104 //tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML); 7105 } else { 7106 body.innerHTML = "<" + blockName + "> </" + blockName + "><" + blockName + "> </" + blockName + ">"; 7107 paraAfter = body.childNodes[1]; 7108 } 7109 7110 inst.selection.moveToBookmark(b); 7111 inst.selection.selectNode(paraAfter, true, true); 7112 7113 return true; 7114 } 7115 7116 // Place first part within new paragraph 7117 if (startChop.nodeName == blockName) 7118 rngBefore.setStart(startChop, 0); 7119 else 7120 rngBefore.setStartBefore(startChop); 7121 7122 rngBefore.setEnd(startNode, startOffset); 7123 paraBefore.appendChild(rngBefore.cloneContents()); 7124 7125 // Place secound part within new paragraph 7126 rngAfter.setEndAfter(endChop); 7127 rngAfter.setStart(endNode, endOffset); 7128 contents = rngAfter.cloneContents(); 7129 7130 if (contents.firstChild && contents.firstChild.nodeName == blockName) { 7131 /* var nodes = contents.firstChild.childNodes; 7132 for (i=0; i<nodes.length; i++) { 7133 //tinyMCE.debug(nodes[i].nodeName); 7134 if (nodes[i].nodeName != "BODY") 7135 paraAfter.appendChild(nodes[i]); 7136 } 7137 */ 7138 paraAfter.innerHTML = contents.firstChild.innerHTML; 7139 } else 7140 paraAfter.appendChild(contents); 7141 7142 // Check if it's a empty paragraph 7143 if (isEmpty(paraBefore)) 7144 paraBefore.innerHTML = " "; 7145 7146 // Check if it's a empty paragraph 7147 if (isEmpty(paraAfter)) 7148 paraAfter.innerHTML = " "; 7149 7150 // Create a range around everything 7151 rng = doc.createRange(); 7152 7153 if (!startChop.previousSibling && startChop.parentNode.nodeName.toUpperCase() == blockName) { 7154 rng.setStartBefore(startChop.parentNode); 7155 } else { 7156 if (rngBefore.startContainer.nodeName.toUpperCase() == blockName && rngBefore.startOffset == 0) 7157 rng.setStartBefore(rngBefore.startContainer); 7158 else 7159 rng.setStart(rngBefore.startContainer, rngBefore.startOffset); 7160 } 7161 7162 if (!endChop.nextSibling && endChop.parentNode.nodeName.toUpperCase() == blockName) 7163 rng.setEndAfter(endChop.parentNode); 7164 else 7165 rng.setEnd(rngAfter.endContainer, rngAfter.endOffset); 7166 7167 // Delete all contents and insert new paragraphs 7168 rng.deleteContents(); 7169 7170 if (tinyMCE.isOpera) { 7171 rng.insertNode(paraBefore); 7172 rng.insertNode(paraAfter); 7173 } else { 7174 rng.insertNode(paraAfter); 7175 rng.insertNode(paraBefore); 7176 } 7177 7178 //tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML); 7179 7180 // Normalize 7181 paraAfter.normalize(); 7182 paraBefore.normalize(); 7183 7184 inst.selection.moveToBookmark(b); 7185 inst.selection.selectNode(paraAfter, true, true); 7186 7187 return true; 7188 }, 7189 7190 _handleBackSpace : function(inst) { 7191 var r = inst.getRng(), sn = r.startContainer, nv, s = false; 7192 7193 // Added body check for bug #1527787 7194 if (sn && sn.nextSibling && sn.nextSibling.nodeName == "BR" && sn.parentNode.nodeName != "BODY") { 7195 nv = sn.nodeValue; 7196 7197 // Handle if a backspace is pressed after a space character #bug 1466054 removed since fix for #1527787 7198 /*if (nv != null && nv.length >= r.startOffset && nv.charAt(r.startOffset - 1) == ' ') 7199 s = true;*/ 7200 7201 // Only remove BRs if we are at the end of line #bug 1464152 7202 if (nv != null && r.startOffset == nv.length) 7203 sn.nextSibling.parentNode.removeChild(sn.nextSibling); 7204 } 7205 7206 if (inst.settings.auto_resize) 7207 inst.resizeToContent(); 7208 7209 return s; 7210 } 7211 7212 }; 7213 7214 /* file:jscripts/tiny_mce/classes/TinyMCE_Layer.class.js */ 7215 7216 function TinyMCE_Layer(id, bm) { 7217 this.id = id; 7218 this.blockerElement = null; 7219 this.events = false; 7220 this.element = null; 7221 this.blockMode = typeof(bm) != 'undefined' ? bm : true; 7222 this.doc = document; 7223 }; 7224 7225 TinyMCE_Layer.prototype = { 7226 moveRelativeTo : function(re, p) { 7227 var rep = this.getAbsPosition(re), e = this.getElement(), x, y; 7228 var w = parseInt(re.offsetWidth), h = parseInt(re.offsetHeight); 7229 var ew = parseInt(e.offsetWidth), eh = parseInt(e.offsetHeight); 7230 7231 switch (p) { 7232 case "tl": 7233 x = rep.absLeft; 7234 y = rep.absTop; 7235 break; 7236 7237 case "tr": 7238 x = rep.absLeft + w; 7239 y = rep.absTop; 7240 break; 7241 7242 case "bl": 7243 x = rep.absLeft; 7244 y = rep.absTop + h; 7245 break; 7246 7247 case "br": 7248 x = rep.absLeft + w; 7249 y = rep.absTop + h; 7250 break; 7251 7252 case "cc": 7253 x = rep.absLeft + (w / 2) - (ew / 2); 7254 y = rep.absTop + (h / 2) - (eh / 2); 7255 break; 7256 } 7257 7258 this.moveTo(x, y); 7259 }, 7260 7261 moveBy : function(x, y) { 7262 var e = this.getElement(); 7263 this.moveTo(parseInt(e.style.left) + x, parseInt(e.style.top) + y); 7264 }, 7265 7266 moveTo : function(x, y) { 7267 var e = this.getElement(); 7268 7269 e.style.left = x + "px"; 7270 e.style.top = y + "px"; 7271 7272 this.updateBlocker(); 7273 }, 7274 7275 resizeBy : function(w, h) { 7276 var e = this.getElement(); 7277 this.resizeTo(parseInt(e.style.width) + w, parseInt(e.style.height) + h); 7278 }, 7279 7280 resizeTo : function(w, h) { 7281 var e = this.getElement(); 7282 7283 if (w != null) 7284 e.style.width = w + "px"; 7285 7286 if (h != null) 7287 e.style.height = h + "px"; 7288 7289 this.updateBlocker(); 7290 }, 7291 7292 show : function() { 7293 var el = this.getElement(); 7294 7295 if (el) { 7296 el.style.display = 'block'; 7297 this.updateBlocker(); 7298 } 7299 }, 7300 7301 hide : function() { 7302 var el = this.getElement(); 7303 7304 if (el) { 7305 el.style.display = 'none'; 7306 this.updateBlocker(); 7307 } 7308 }, 7309 7310 isVisible : function() { 7311 return this.getElement().style.display == 'block'; 7312 }, 7313 7314 getElement : function() { 7315 if (!this.element) 7316 this.element = this.doc.getElementById(this.id); 7317 7318 return this.element; 7319 }, 7320 7321 setBlockMode : function(s) { 7322 this.blockMode = s; 7323 }, 7324 7325 updateBlocker : function() { 7326 var e, b, x, y, w, h; 7327 7328 b = this.getBlocker(); 7329 if (b) { 7330 if (this.blockMode) { 7331 e = this.getElement(); 7332 x = this.parseInt(e.style.left); 7333 y = this.parseInt(e.style.top); 7334 w = this.parseInt(e.offsetWidth); 7335 h = this.parseInt(e.offsetHeight); 7336 7337 b.style.left = x + 'px'; 7338 b.style.top = y + 'px'; 7339 b.style.width = w + 'px'; 7340 b.style.height = h + 'px'; 7341 b.style.display = e.style.display; 7342 } else 7343 b.style.display = 'none'; 7344 } 7345 }, 7346 7347 getBlocker : function() { 7348 var d, b; 7349 7350 if (!this.blockerElement && this.blockMode) { 7351 d = this.doc; 7352 b = d.getElementById(this.id + "_blocker"); 7353 7354 if (!b) { 7355 b = d.createElement("iframe"); 7356 7357 b.setAttribute('id', this.id + "_blocker"); 7358 b.style.cssText = 'display: none; position: absolute; left: 0; top: 0'; 7359 b.src = 'javascript:false;'; 7360 b.frameBorder = '0'; 7361 b.scrolling = 'no'; 7362 7363 d.body.appendChild(b); 7364 } 7365 7366 this.blockerElement = b; 7367 } 7368 7369 return this.blockerElement; 7370 }, 7371 7372 getAbsPosition : function(n) { 7373 var p = {absLeft : 0, absTop : 0}; 7374 7375 while (n) { 7376 p.absLeft += n.offsetLeft; 7377 p.absTop += n.offsetTop; 7378 n = n.offsetParent; 7379 } 7380 7381 return p; 7382 }, 7383 7384 create : function(n, c, p, h) { 7385 var d = this.doc, e = d.createElement(n); 7386 7387 e.setAttribute('id', this.id); 7388 7389 if (c) 7390 e.className = c; 7391 7392 if (!p) 7393 p = d.body; 7394 7395 if (h) 7396 e.innerHTML = h; 7397 7398 p.appendChild(e); 7399 7400 return this.element = e; 7401 }, 7402 7403 exists : function() { 7404 return this.doc.getElementById(this.id) != null; 7405 }, 7406 7407 parseInt : function(s) { 7408 if (s == null || s == '') 7409 return 0; 7410 7411 return parseInt(s); 7412 }, 7413 7414 remove : function() { 7415 var e = this.getElement(), b = this.getBlocker(); 7416 7417 if (e) 7418 e.parentNode.removeChild(e); 7419 7420 if (b) 7421 b.parentNode.removeChild(b); 7422 } 7423 7424 }; 7425 7426 /* file:jscripts/tiny_mce/classes/TinyMCE_Menu.class.js */ 7427 7428 function TinyMCE_Menu() { 7429 var id; 7430 7431 if (typeof(tinyMCE.menuCounter) == "undefined") 7432 tinyMCE.menuCounter = 0; 7433 7434 id = "mc_menu_" + tinyMCE.menuCounter++; 7435 7436 TinyMCE_Layer.call(this, id, true); 7437 7438 this.id = id; 7439 this.items = []; 7440 this.needsUpdate = true; 7441 }; 7442 7443 TinyMCE_Menu.prototype = tinyMCE.extend(TinyMCE_Layer.prototype, { 7444 init : function(s) { 7445 var n; 7446 7447 // Default params 7448 this.settings = { 7449 separator_class : 'mceMenuSeparator', 7450 title_class : 'mceMenuTitle', 7451 disabled_class : 'mceMenuDisabled', 7452 menu_class : 'mceMenu', 7453 drop_menu : true 7454 }; 7455 7456 for (n in s) 7457 this.settings[n] = s[n]; 7458 7459 this.create('div', this.settings.menu_class); 7460 }, 7461 7462 clear : function() { 7463 this.items = []; 7464 }, 7465 7466 addTitle : function(t) { 7467 this.add({type : 'title', text : t}); 7468 }, 7469 7470 addDisabled : function(t) { 7471 this.add({type : 'disabled', text : t}); 7472 }, 7473 7474 addSeparator : function() { 7475 this.add({type : 'separator'}); 7476 }, 7477 7478 addItem : function(t, js) { 7479 this.add({text : t, js : js}); 7480 }, 7481 7482 add : function(mi) { 7483 this.items[this.items.length] = mi; 7484 this.needsUpdate = true; 7485 }, 7486 7487 update : function() { 7488 var e = this.getElement(), h = '', i, t, m = this.items, s = this.settings; 7489 7490 if (this.settings.drop_menu) 7491 h += '<span class="mceMenuLine"></span>'; 7492 7493 h += '<table border="0" cellpadding="0" cellspacing="0">'; 7494 7495 for (i=0; i<m.length; i++) { 7496 t = tinyMCE.xmlEncode(m[i].text); 7497 c = m[i].class_name ? ' class="' + m[i].class_name + '"' : ''; 7498 7499 switch (m[i].type) { 7500 case 'separator': 7501 h += '<tr class="' + s.separator_class + '"><td>'; 7502 break; 7503 7504 case 'title': 7505 h += '<tr class="' + s.title_class + '"><td><span' + c +'>' + t + '</span>'; 7506 break; 7507 7508 case 'disabled': 7509 h += '<tr class="' + s.disabled_class + '"><td><span' + c +'>' + t + '</span>'; 7510 break; 7511 7512 default: 7513 h += '<tr><td><a href="' + tinyMCE.xmlEncode(m[i].js) + '" onmousedown="' + tinyMCE.xmlEncode(m[i].js) + ';return tinyMCE.cancelEvent(event);" onclick="return tinyMCE.cancelEvent(event);" onmouseup="return tinyMCE.cancelEvent(event);"><span' + c +'>' + t + '</span></a>'; 7514 } 7515 7516 h += '</td></tr>'; 7517 } 7518 7519 h += '</table>'; 7520 7521 e.innerHTML = h; 7522 7523 this.needsUpdate = false; 7524 this.updateBlocker(); 7525 }, 7526 7527 show : function() { 7528 var nl, i; 7529 7530 if (tinyMCE.lastMenu == this) 7531 return; 7532 7533 if (this.needsUpdate) 7534 this.update(); 7535 7536 if (tinyMCE.lastMenu && tinyMCE.lastMenu != this) 7537 tinyMCE.lastMenu.hide(); 7538 7539 TinyMCE_Layer.prototype.show.call(this); 7540 7541 if (!tinyMCE.isOpera) { 7542 // Accessibility stuff 7543 /* nl = this.getElement().getElementsByTagName("a"); 7544 if (nl.length > 0) 7545 nl[0].focus();*/ 7546 } 7547 7548 tinyMCE.lastMenu = this; 7549 } 7550 7551 }); 7552 7553 /* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */ 7554 7555 tinyMCE.add(TinyMCE_Engine, { 7556 debug : function() { 7557 var m = "", a, i, l = tinyMCE.log.length; 7558 7559 for (i=0, a = this.debug.arguments; i<a.length; i++) { 7560 m += a[i]; 7561 7562 if (i<a.length-1) 7563 m += ', '; 7564 } 7565 7566 if (l < 1000) 7567 tinyMCE.log[l] = "[debug] " + m; 7568 } 7569 7570 }); 7571 9088 }); 9089 }()); -
trunk/wp-includes/js/tinymce/tiny_mce_config.php
r6575 r6632 28 28 $invalid_elements = apply_filters('mce_invalid_elements', ''); 29 29 30 $plugins = array( 'inlinepopups', 'autosave', 'spellchecker', 'paste', 'wordpress');30 $plugins = array( 'safari', 'inlinepopups', 'autosave', 'spellchecker', 'paste', 'wordpress', 'media' ); 31 31 $plugins = apply_filters('mce_plugins', $plugins); 32 32 $plugins = implode($plugins, ','); 33 33 34 $mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'separator', 'bullist', 'numlist', 'outdent', 'indent', 'separator', 'justifyleft', 'justifycenter', 'justifyright', 'separator', 'link', 'unlink', 'image', 'wp_more', 'separator', 'spellchecker', 'separator', 'wp_help', 'wp_adv', 'wp_adv_start', ' formatselect', 'underline', 'justifyfull', 'forecolor', 'separator', 'pastetext', 'pasteword', 'separator', 'removeformat', 'cleanup', 'separator', 'charmap', 'separator', 'undo', 'redo', 'wp_adv_end'));34 $mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'separator', 'bullist', 'numlist', 'outdent', 'indent', 'separator', 'justifyleft', 'justifycenter', 'justifyright', 'separator', 'link', 'unlink', 'image', 'wp_more', 'separator', 'spellchecker', 'separator', 'wp_help', 'wp_adv', 'wp_adv_start', 'wp_adv_end')); 35 35 $mce_buttons = implode($mce_buttons, ','); 36 36 37 $mce_buttons_2 = apply_filters('mce_buttons_2', array( ));37 $mce_buttons_2 = apply_filters('mce_buttons_2', array('formatselect', 'underline', 'justifyfull', 'forecolor', 'media', 'separator', 'pastetext', 'pasteword', 'separator', 'removeformat', 'cleanup', 'separator', 'charmap', 'separator', 'undo', 'redo')); 38 38 $mce_buttons_2 = implode($mce_buttons_2, ','); 39 39 … … 55 55 ?> 56 56 57 /* 57 58 wpEditorInit = function() { 58 59 // Activate tinyMCE if it's the user's default editor 59 60 if ( ( 'undefined' == typeof wpTinyMCEConfig ) || 'tinymce' == wpTinyMCEConfig.defaultEditor ) 60 tinyMCE.execCommand( "mceAddControl", true, 'content');61 tinyMCE.execCommand('mceAddControl', false, 'content'); 61 62 }; 63 */ 64 65 wpEditorInit = function() { 66 if ( ( 'undefined' != typeof wpTinyMCEConfig ) && 'tinymce' != wpTinyMCEConfig.defaultEditor ) 67 tinyMCE.get('content').hide(); 68 } 62 69 63 70 initArray = { 64 mode : "specific_textareas", 65 editor_selector : "mceEditor", 71 mode : "exact", 72 elements : "content", 73 // editor_selector : "mceEditor", 66 74 oninit : "wpEditorInit", 67 75 width : "100%", 68 76 theme : "advanced", 77 skin : "o2k7", 69 78 theme_advanced_buttons1 : "<?php echo $mce_buttons; ?>", 70 79 theme_advanced_buttons2 : "<?php echo $mce_buttons_2; ?>", … … 73 82 theme_advanced_toolbar_location : "top", 74 83 theme_advanced_toolbar_align : "left", 75 theme_advanced_ path_location : "bottom",84 theme_advanced_statusbar_location : "bottom", 76 85 theme_advanced_resizing : true, 77 86 browsers : "<?php echo $mce_browsers; ?>", -
trunk/wp-includes/js/tinymce/tiny_mce_gzip.php
r5700 r6632 10 10 * Notice: This script defaults the button_tile_map option to true for extra performance. 11 11 */ 12 13 @require_once('../../../wp-config.php'); // For get_bloginfo(). 14 12 13 @require_once('../../../wp-config.php'); // For get_bloginfo(). 14 ?> 15 var scriptURL = '<?php echo get_bloginfo('wpurl') . '/' . WPINC; ?>/js/tinymce/tiny_mce.js'; 16 document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + scriptURL + '"></script>'); 17 <?php 18 exit; // tiny_mce_gzip.php needs changes, but also it's much easier to test the js when it's not in one big file 19 15 20 // Get input 16 21 $plugins = explode(',', getParam("plugins", "")); -
trunk/wp-includes/js/tinymce/tiny_mce_popup.js
r5577 r6632 1 // Some global instances, this will be filled later 2 var tinyMCE = null, tinyMCELang = null; 3 4 function TinyMCE_Popup() { 5 }; 6 7 TinyMCE_Popup.prototype = { 8 findWin : function(w) { 9 var c; 10 11 // Check parents 12 c = w; 13 while (c && (c = c.parent) != null) { 14 if (typeof(c.tinyMCE) != "undefined") 15 return c; 1 // Some global instances 2 var tinymce = null, tinyMCEPopup, tinyMCE; 3 4 tinyMCEPopup = { 5 init : function() { 6 var t = this, w = t.getWin(), ti; 7 8 // Find API 9 tinymce = w.tinymce; 10 tinyMCE = w.tinyMCE; 11 t.editor = tinymce.EditorManager.activeEditor; 12 t.params = t.editor.windowManager.params; 13 14 // Setup local DOM 15 t.dom = t.editor.windowManager.createInstance('tinymce.dom.DOMUtils', document); 16 t.dom.loadCSS(t.editor.settings.popup_css); 17 18 // Setup on init listeners 19 t.listeners = []; 20 t.onInit = { 21 add : function(f, s) { 22 t.listeners.push({func : f, scope : s}); 23 } 24 }; 25 26 t.isWindow = !t.getWindowArg('mce_inline'); 27 t.id = t.getWindowArg('mce_window_id'); 28 t.editor.windowManager.onOpen.dispatch(t.editor.windowManager, window); 29 }, 30 31 getWin : function() { 32 return window.dialogArguments || opener || parent || top; 33 }, 34 35 getWindowArg : function(n, dv) { 36 var v = this.params[n]; 37 38 return tinymce.is(v) ? v : dv; 39 }, 40 41 getParam : function(n, dv) { 42 return this.editor.getParam(n, dv); 43 }, 44 45 getLang : function(n, dv) { 46 return this.editor.getLang(n, dv); 47 }, 48 49 execCommand : function(cmd, ui, val) { 50 this.restoreSelection(); 51 return this.editor.execCommand(cmd, ui, val); 52 }, 53 54 resizeToInnerSize : function() { 55 var t = this, n, b = document.body, vp = t.dom.getViewPort(window), dw, dh; 56 57 dw = t.getWindowArg('mce_width') - vp.w; 58 dh = t.getWindowArg('mce_height') - vp.h; 59 60 if (t.isWindow) 61 window.resizeBy(dw, dh); 62 else 63 t.editor.windowManager.resizeBy(dw, dh, t.id); 64 }, 65 66 executeOnLoad : function(s) { 67 this.onInit.add(function() { 68 eval(s); 69 }); 70 }, 71 72 storeSelection : function() { 73 this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark('simple'); 74 }, 75 76 restoreSelection : function() { 77 var t = tinyMCEPopup; 78 79 if (!t.isWindow && tinymce.isIE) 80 t.editor.selection.moveToBookmark(t.editor.windowManager.bookmark); 81 }, 82 83 requireLangPack : function() { 84 var u = this.getWindowArg('plugin_url') || this.getWindowArg('theme_url'); 85 86 if (u) 87 document.write('<script type="text/javascript" src="' + u + '/langs/' + this.editor.settings.language + '_dlg.js' + '"></script>'); 88 }, 89 90 pickColor : function(e, element_id) { 91 this.execCommand('mceColorPicker', true, { 92 color : document.getElementById(element_id).value, 93 func : function(c) { 94 document.getElementById(element_id).value = c; 95 96 if (tinymce.is(document.getElementById(element_id).onchange, 'function')) 97 document.getElementById(element_id).onchange(); 98 } 99 }); 100 }, 101 102 openBrowser : function(element_id, type, option) { 103 tinyMCEPopup.restoreSelection(); 104 this.editor.execCallback('file_browser_callback', element_id, document.getElementById(element_id).value, type, window); 105 }, 106 107 close : function() { 108 var t = this; 109 110 t.dom = t.dom.doc = null; // Cleanup 111 t.editor.windowManager.close(window, t.id); 112 }, 113 114 // Internal functions 115 116 _restoreSelection : function() { 117 var e = window.event.srcElement; 118 119 if (e.nodeName == 'INPUT' && (e.type == 'submit' || e.type == 'button')) 120 tinyMCEPopup.restoreSelection(); 121 }, 122 123 /* _restoreSelection : function() { 124 var e = window.event.srcElement; 125 126 // If user focus a non text input or textarea 127 if ((e.nodeName != 'INPUT' && e.nodeName != 'TEXTAREA') || e.type != 'text') 128 tinyMCEPopup.restoreSelection(); 129 },*/ 130 131 _onDOMLoaded : function() { 132 var t = this, ti = document.title, bm, h; 133 134 // Translate page 135 h = document.body.innerHTML; 136 137 // Replace a=x with a="x" in IE 138 if (tinymce.isIE) 139 h = h.replace(/ (value|title|alt)=([^\s>]+)/gi, ' $1="$2"'); 140 141 document.body.innerHTML = t.editor.translate(h); 142 document.title = ti = t.editor.translate(ti); 143 document.body.style.display = ''; 144 145 // Restore selection in IE when focus is placed on a non textarea or input element of the type text 146 if (tinymce.isIE) 147 document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection); 148 149 t.restoreSelection(); 150 151 // Call onInit 152 tinymce.each(t.listeners, function(o) { 153 o.func.call(o.scope, t.editor); 154 }); 155 156 t.resizeToInnerSize(); 157 158 if (t.isWindow) 159 window.focus(); 160 else 161 t.editor.windowManager.setTitle(ti, t.id); 162 163 if (!tinymce.isIE && !t.isWindow) { 164 tinymce.dom.Event._add(document, 'focus', function() { 165 t.editor.windowManager.focus(t.id) 166 }); 16 167 } 17 168 18 // Check openers 19 c = w; 20 while (c && (c = c.opener) != null) { 21 if (typeof(c.tinyMCE) != "undefined") 22 return c; 169 // Patch for accessibility 170 tinymce.each(t.dom.select('select'), function(e) { 171 e.onkeydown = tinyMCEPopup._accessHandler; 172 }); 173 174 // Move focus to window 175 window.focus(); 176 }, 177 178 _accessHandler : function(e) { 179 var e = e || window.event; 180 181 if (e.keyCode == 13 || e.keyCode == 32) { 182 e = e.target || e.srcElement; 183 184 if (e.onchange) 185 e.onchange(); 186 187 return tinymce.dom.Event.cancel(e); 23 188 } 24 25 // Try top 26 if (typeof(top.tinyMCE) != "undefined") 27 return top; 28 29 return null; 30 }, 31 32 init : function() { 33 var win = window.opener ? window.opener : window.dialogArguments, c; 34 var inst, re, title, divElm; 35 36 if (!win) 37 win = this.findWin(window); 38 39 if (!win) { 40 alert("tinyMCE object reference not found from popup."); 41 return; 42 } 43 44 window.opener = win; 45 this.windowOpener = win; 46 this.onLoadEval = ""; 47 48 // Setup parent references 49 tinyMCE = win.tinyMCE; 50 tinyMCELang = win.tinyMCELang; 51 52 inst = tinyMCE.selectedInstance; 53 this.isWindow = tinyMCE.getWindowArg('mce_inside_iframe', false) == false; 54 this.storeSelection = (tinyMCE.isRealIE) && !this.isWindow && tinyMCE.getWindowArg('mce_store_selection', true); 55 56 if (this.isWindow) 57 window.focus(); 58 59 // Store selection 60 if (this.storeSelection) 61 inst.selectionBookmark = inst.selection.getBookmark(true); 62 63 // Setup dir 64 if (tinyMCELang.lang_dir) 65 document.dir = tinyMCELang.lang_dir; 66 67 // Setup title 68 re = new RegExp('{|\\\$|}', 'g'); 69 title = document.title.replace(re, ""); 70 if (typeof(tinyMCELang[title]) != "undefined") { 71 divElm = document.createElement("div"); 72 divElm.innerHTML = tinyMCELang[title]; 73 document.title = divElm.innerHTML; 74 75 if (typeof(tinyMCE.setWindowTitle) != 'undefined') 76 tinyMCE.setWindowTitle(window, divElm.innerHTML); 77 } 78 79 // Output Popup CSS class 80 document.write('<link href="' + tinyMCE.getParam("popups_css") + '" rel="stylesheet" type="text/css">'); 81 82 if (tinyMCE.getParam("popups_css_add")) { 83 c = tinyMCE.getParam("popups_css_add"); 84 85 // Is relative 86 if (c.indexOf('://') == -1 && c.charAt(0) != '/') 87 c = tinyMCE.documentBasePath + "/" + c; 88 89 document.write('<link href="' + c + '" rel="stylesheet" type="text/css">'); 90 } 91 92 tinyMCE.addEvent(window, "load", this.onLoad); 93 }, 94 95 onLoad : function() { 96 var dir, i, elms, body = document.body; 97 98 if (tinyMCE.getWindowArg('mce_replacevariables', true)) 99 body.innerHTML = tinyMCE.applyTemplate(body.innerHTML, tinyMCE.windowArgs); 100 101 dir = tinyMCE.selectedInstance.settings.directionality; 102 if (dir == "rtl" && document.forms && document.forms.length > 0) { 103 elms = document.forms[0].elements; 104 for (i=0; i<elms.length; i++) { 105 if ((elms[i].type == "text" || elms[i].type == "textarea") && elms[i].getAttribute("dir") != "ltr") 106 elms[i].dir = dir; 189 }, 190 191 _wait : function() { 192 var t = this, ti; 193 194 if (tinymce.isIE && document.location.protocol != 'https:') { 195 // Fake DOMContentLoaded on IE 196 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>'); 197 document.getElementById("__ie_onload").onreadystatechange = function() { 198 if (this.readyState == "complete") { 199 t._onDOMLoaded(); 200 document.getElementById("__ie_onload").onreadystatechange = null; // Prevent leak 201 } 202 }; 203 } else { 204 if (tinymce.isIE || tinymce.isWebKit) { 205 ti = setInterval(function() { 206 if (/loaded|complete/.test(document.readyState)) { 207 clearInterval(ti); 208 t._onDOMLoaded(); 209 } 210 }, 10); 211 } else { 212 window.addEventListener('DOMContentLoaded', function() { 213 t._onDOMLoaded(); 214 }, false); 107 215 } 108 216 } 109 110 if (body.style.display == 'none')111 body.style.display = 'block';112 113 // Execute real onload (Opera fix)114 if (tinyMCEPopup.onLoadEval !== '')115 eval(tinyMCEPopup.onLoadEval);116 },117 118 executeOnLoad : function(str) {119 if (tinyMCE.isOpera)120 this.onLoadEval = str;121 else122 eval(str);123 },124 125 resizeToInnerSize : function() {126 var i, doc, body, oldMargin, wrapper, iframe, nodes, dx, dy;127 128 // Netscape 7.1 workaround129 if (this.isWindow && tinyMCE.isNS71) {130 window.resizeBy(0, 10);131 return;132 }133 134 if (this.isWindow) {135 doc = document;136 body = doc.body;137 138 if (body.style.display == 'none')139 body.style.display = 'block';140 141 // Remove margin142 oldMargin = body.style.margin;143 body.style.margin = '0';144 145 // Create wrapper146 wrapper = doc.createElement("div");147 wrapper.id = 'mcBodyWrapper';148 wrapper.style.display = 'none';149 wrapper.style.margin = '0';150 151 // Wrap body elements152 nodes = doc.body.childNodes;153 for (i=nodes.length-1; i>=0; i--) {154 if (wrapper.hasChildNodes())155 wrapper.insertBefore(nodes[i].cloneNode(true), wrapper.firstChild);156 else157 wrapper.appendChild(nodes[i].cloneNode(true));158 159 nodes[i].parentNode.removeChild(nodes[i]);160 }161 162 // Add wrapper163 doc.body.appendChild(wrapper);164 165 // Create iframe166 iframe = document.createElement("iframe");167 iframe.id = "mcWinIframe";168 iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings.default_document;169 iframe.width = "100%";170 iframe.height = "100%";171 iframe.style.margin = '0';172 173 // Add iframe174 doc.body.appendChild(iframe);175 176 // Measure iframe177 iframe = document.getElementById('mcWinIframe');178 dx = tinyMCE.getWindowArg('mce_width') - iframe.clientWidth;179 dy = tinyMCE.getWindowArg('mce_height') - iframe.clientHeight;180 181 // Resize window182 // tinyMCE.debug(tinyMCE.getWindowArg('mce_width') + "," + tinyMCE.getWindowArg('mce_height') + " - " + dx + "," + dy);183 window.resizeBy(dx, dy);184 185 // Hide iframe and show wrapper186 body.style.margin = oldMargin;187 iframe.style.display = 'none';188 wrapper.style.display = 'block';189 }190 },191 192 resizeToContent : function() {193 var isMSIE = (navigator.appName == "Microsoft Internet Explorer");194 var isOpera = (navigator.userAgent.indexOf("Opera") != -1);195 var elm, width, height, x, y, dx, dy;196 197 if (isOpera)198 return;199 200 if (isMSIE) {201 try { window.resizeTo(10, 10); } catch (e) {}202 203 elm = document.body;204 width = elm.offsetWidth;205 height = elm.offsetHeight;206 dx = (elm.scrollWidth - width) + 4;207 dy = elm.scrollHeight - height;208 209 try { window.resizeBy(dx, dy); } catch (e) {}210 } else {211 window.scrollBy(1000, 1000);212 if (window.scrollX > 0 || window.scrollY > 0) {213 window.resizeBy(window.innerWidth * 2, window.innerHeight * 2);214 window.sizeToContent();215 window.scrollTo(0, 0);216 x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);217 y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);218 window.moveTo(x, y);219 }220 }221 },222 223 getWindowArg : function(name, default_value) {224 return tinyMCE.getWindowArg(name, default_value);225 },226 227 restoreSelection : function() {228 var inst;229 230 if (this.storeSelection) {231 inst = tinyMCE.selectedInstance;232 233 inst.getWin().focus();234 235 if (inst.selectionBookmark)236 inst.selection.moveToBookmark(inst.selectionBookmark);237 }238 },239 240 execCommand : function(command, user_interface, value) {241 var inst = tinyMCE.selectedInstance;242 243 this.restoreSelection();244 inst.execCommand(command, user_interface, value);245 246 // Store selection247 if (this.storeSelection)248 inst.selectionBookmark = inst.selection.getBookmark(true);249 },250 251 close : function() {252 tinyMCE.closeWindow(window);253 },254 255 pickColor : function(e, element_id) {256 tinyMCE.selectedInstance.execCommand('mceColorPicker', true, {257 element_id : element_id,258 document : document,259 window : window,260 store_selection : false261 });262 },263 264 openBrowser : function(element_id, type, option) {265 var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback"));266 var url = document.getElementById(element_id).value;267 268 tinyMCE.setWindowArg("window", window);269 tinyMCE.setWindowArg("document", document);270 271 // Call to external callback272 if (eval('typeof(tinyMCEPopup.windowOpener.' + cb + ')') == "undefined")273 alert("Callback function: " + cb + " could not be found.");274 else275 eval("tinyMCEPopup.windowOpener." + cb + "(element_id, url, type, window);");276 },277 278 importClass : function(c) {279 var n;280 281 window[c] = function() {};282 283 for (n in window.opener[c].prototype)284 window[c].prototype[n] = window.opener[c].prototype[n];285 286 window[c].constructor = window.opener[c].constructor;287 217 } 288 289 }; 290 291 // Setup global instance 292 var tinyMCEPopup = new TinyMCE_Popup(); 218 }; 293 219 294 220 tinyMCEPopup.init(); 221 tinyMCEPopup._wait(); // Wait for DOM Content Loaded -
trunk/wp-includes/js/tinymce/utils/editable_selects.js
-
Property
svn:eol-style
set to
native
r4799 r6632 1 1 /** 2 * $Id: editable_selects.js 162 2007-01-03 16:16:52Z spocke $2 * $Id: editable_selects.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * Makes select boxes editable. 5 5 * 6 6 * @author Moxiecode 7 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 8 8 */ 9 9 … … 21 21 22 22 nl[i].options[nl[i].options.length] = o; 23 nl[i]. setAttribute('onchange', 'TinyMCE_EditableSelects.onChangeEditableSelect(this);');23 nl[i].onchange = TinyMCE_EditableSelects.onChangeEditableSelect; 24 24 } 25 25 } 26 26 }, 27 27 28 onChangeEditableSelect : function( se) {29 var d = document, ne ;28 onChangeEditableSelect : function(e) { 29 var d = document, ne, se = window.event ? window.event.srcElement : e.target; 30 30 31 31 if (se.options[se.selectedIndex].value == '__mce_add_custom__') { … … 35 35 ne.type = "text"; 36 36 37 ne.style.width = se. clientWidth;37 ne.style.width = se.offsetWidth + 'px'; 38 38 se.parentNode.insertBefore(ne, se); 39 39 se.style.display = 'none'; -
Property
svn:eol-style
set to
-
trunk/wp-includes/js/tinymce/utils/form_utils.js
r4799 r6632 1 1 /** 2 * $Id: form_utils.js 162 2007-01-03 16:16:52Z spocke $2 * $Id: form_utils.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * Various form utilitiy functions. 5 5 * 6 6 * @author Moxiecode 7 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 8 8 */ 9 9 10 var themeBaseURL = tinyMCE .baseURL + '/themes/' + tinyMCE.getParam("theme");10 var themeBaseURL = tinyMCEPopup.editor.baseURI.toAbsolute('themes/' + tinyMCEPopup.getParam("theme")); 11 11 12 12 function getColorPickerHTML(id, target_form_element) { 13 13 var h = ""; 14 14 15 h += '<a id="' + id + '_link" href="javascript:void(0);" onkeydown="pickColor(event,\'' + target_form_element +'\');" onmousedown="pickColor(event,\'' + target_form_element +'\');return false;">'; 16 h += '<img id="' + id + '" src="' + themeBaseURL + '/images/color.gif"'; 17 h += ' onmouseover="this.className=\'mceButtonOver\'"'; 18 h += ' onmouseout="this.className=\'mceButtonNormal\'"'; 19 h += ' onmousedown="this.className=\'mceButtonDown\'"'; 20 h += ' width="20" height="16" border="0" title="' + tinyMCE.getLang('lang_browse') + '"'; 21 h += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>'; 15 h += '<a id="' + id + '_link" href="javascript:;" onclick="tinyMCEPopup.pickColor(event,\'' + target_form_element +'\');" onmousedown="return false;" class="pickcolor">'; 16 h += '<span id="' + id + '" title="' + tinyMCEPopup.getLang('browse') + '"></span></a>'; 22 17 23 18 return h; 24 }25 26 function pickColor(e, target_form_element) {27 if ((e.keyCode == 32 || e.keyCode == 13) || e.type == "mousedown")28 tinyMCEPopup.pickColor(e, target_form_element);29 19 } 30 20 … … 41 31 lnk.setAttribute("realhref", lnk.getAttribute("href")); 42 32 lnk.removeAttribute("href"); 43 tinyMCE .switchClass(img, 'mceButtonDisabled', true);33 tinyMCEPopup.dom.addClass(img, 'disabled'); 44 34 } else { 45 35 lnk.setAttribute("href", lnk.getAttribute("realhref")); 46 tinyMCE .switchClass(img, 'mceButtonNormal', false);36 tinyMCEPopup.dom.removeClass(img, 'disabled'); 47 37 } 48 38 } … … 50 40 51 41 function getBrowserHTML(id, target_form_element, type, prefix) { 52 var option = prefix + "_" + type + "_browser_callback"; 53 var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback")); 54 if (cb == null) 42 var option = prefix + "_" + type + "_browser_callback", cb, html; 43 44 cb = tinyMCEPopup.getParam(option, tinyMCEPopup.getParam("file_browser_callback")); 45 46 if (!cb) 55 47 return ""; 56 48 57 var html = ""; 58 59 html += '<a id="' + id + '_link" href="javascript:openBrower(\'' + id + '\',\'' + target_form_element + '\', \'' + type + '\',\'' + option + '\');" onmousedown="return false;">'; 60 html += '<img id="' + id + '" src="' + themeBaseURL + '/images/browse.gif"'; 61 html += ' onmouseover="this.className=\'mceButtonOver\';"'; 62 html += ' onmouseout="this.className=\'mceButtonNormal\';"'; 63 html += ' onmousedown="this.className=\'mceButtonDown\';"'; 64 html += ' width="20" height="18" border="0" title="' + tinyMCE.getLang('lang_browse') + '"'; 65 html += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>'; 49 html = ""; 50 html += '<a id="' + id + '_link" href="javascript:openBrowser(\'' + id + '\',\'' + target_form_element + '\', \'' + type + '\',\'' + option + '\');" onmousedown="return false;" class="browse">'; 51 html += '<span id="' + id + '" title="' + tinyMCEPopup.getLang('browse') + '"></span></a>'; 66 52 67 53 return html; 68 54 } 69 55 70 function openBrow er(img_id, target_form_element, type, option) {56 function openBrowser(img_id, target_form_element, type, option) { 71 57 var img = document.getElementById(img_id); 72 58 … … 120 106 // Setup class droplist 121 107 var styleSelectElm = document.getElementById(list_id); 122 var styles = tinyMCE .getParam('theme_advanced_styles', false);123 styles = tinyMCE .getParam(specific_option, styles);108 var styles = tinyMCEPopup.getParam('theme_advanced_styles', false); 109 styles = tinyMCEPopup.getParam(specific_option, styles); 124 110 125 111 if (styles) { … … 137 123 } 138 124 } else { 139 // Use auto impored classes 140 var csses = tinyMCE.getCSSClasses(tinyMCE.getWindowArg('editor_id')); 141 for (var i=0; i<csses.length; i++) 142 styleSelectElm.options[styleSelectElm.length] = new Option(csses[i], csses[i]); 125 tinymce.each(tinyMCEPopup.editor.dom.getClasses(), function(o) { 126 styleSelectElm.options[styleSelectElm.length] = new Option(o.title || o['class'], o['class']); 127 }); 143 128 } 144 129 } … … 197 182 198 183 function getStyle(elm, attrib, style) { 199 var val = tinyMCE .getAttrib(elm, attrib);184 var val = tinyMCEPopup.dom.getAttrib(elm, attrib); 200 185 201 186 if (val != '') … … 205 190 style = attrib; 206 191 207 val = eval('elm.style.' + style); 208 209 return val == null ? '' : '' + val; 192 return tinyMCEPopup.dom.getStyle(elm, style); 210 193 } -
trunk/wp-includes/js/tinymce/utils/mclayer.js
r4799 r6632 1 1 /** 2 * $Id: mclayer.js 162 2007-01-03 16:16:52Z spocke $2 * $Id: mclayer.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * Moxiecode floating layer script. 5 5 * 6 6 * @author Moxiecode 7 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 8 8 */ 9 9 -
trunk/wp-includes/js/tinymce/utils/mctabs.js
r4799 r6632 1 1 /** 2 * $Id: mctabs.js 162 2007-01-03 16:16:52Z spocke $2 * $Id: mctabs.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * Moxiecode DHTML Tabs script. 5 5 * 6 6 * @author Moxiecode 7 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 8 8 */ 9 9 -
trunk/wp-includes/js/tinymce/utils/validate.js
r4799 r6632 1 1 /** 2 * $Id: validate.js 162 2007-01-03 16:16:52Z spocke $2 * $Id: validate.js 520 2008-01-07 16:30:32Z spocke $ 3 3 * 4 4 * Various form validation methods. 5 5 * 6 6 * @author Moxiecode 7 * @copyright Copyright © 2004-200 7, Moxiecode Systems AB, All rights reserved.7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. 8 8 */ 9 9
Note: See TracChangeset
for help on using the changeset viewer.