Make WordPress Core

Changeset 6632


Ignore:
Timestamp:
01/17/2008 03:44:05 PM (19 years ago)
Author:
ryan
Message:

TinyMCE 3.0 RC1. First cut, eexpect regressions. Props azaozz. see #5674

Location:
trunk/wp-includes
Files:
80 added
42 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/formatting.php

    r6613 r6632  
    6868        $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
    6969        $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        }
    7074        $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
    7175        $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  
    953953        <script type="text/javascript">
    954954        // <![CDATA[
    955                 if ( typeof tinyMCE != "undefined" && tinyMCE.configs.length > 0 )
     955                if ( typeof tinyMCE != "undefined" )
    956956                        document.getElementById('editor-toolbar').style.display = 'block';
    957957        // ]]>
     
    968968        <script type="text/javascript">
    969969        // <![CDATA[
    970                 if ( typeof tinyMCE != "undefined" && tinyMCE.configs.length > 0 )
     970                if ( typeof tinyMCE != "undefined" )
    971971                        document.getElementById("quicktags").style.display="none";
    972972        // ]]>
  • 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 });
     1tinyMCE.addI18n({en:{
     2common:{
     3edit_confirm:"Do you want to use the WYSIWYG mode for this textarea?",
     4apply:"Apply",
     5insert:"Insert",
     6update:"Update",
     7cancel:"Cancel",
     8close:"Close",
     9browse:"Browse",
     10class_name:"Class",
     11not_set:"-- Not set --",
     12clipboard_msg:"Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?",
     13clipboard_no_support:"Currently not supported by your browser, use keyboard shortcuts instead.",
     14popup_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.",
     15invalid_data:"Error: Invalid values entered, these are marked in red.",
     16more_colors:"More colors"
     17},
     18contextmenu:{
     19align:"Alignment",
     20left:"Left",
     21center:"Center",
     22right:"Right",
     23full:"Full"
     24},
     25insertdatetime:{
     26date_fmt:"%Y-%m-%d",
     27time_fmt:"%H:%M:%S",
     28insertdate_desc:"Insert date",
     29inserttime_desc:"Insert time",
     30months_long:"January,February,March,April,May,June,July,August,September,October,November,December",
     31months_short:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",
     32day_long:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday",
     33day_short:"Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun"
     34},
     35print:{
     36print_desc:"Print"
     37},
     38preview:{
     39preview_desc:"Preview"
     40},
     41directionality:{
     42ltr_desc:"Direction left to right",
     43rtl_desc:"Direction right to left"
     44},
     45layer:{
     46insertlayer_desc:"Insert new layer",
     47forward_desc:"Move forward",
     48backward_desc:"Move backward",
     49absolute_desc:"Toggle absolute positioning",
     50content:"New layer..."
     51},
     52save:{
     53save_desc:"Save",
     54cancel_desc:"Cancel all changes"
     55},
     56nonbreaking:{
     57nonbreaking_desc:"Insert non-breaking space character"
     58},
     59iespell:{
     60iespell_desc:"Run spell checking",
     61download:"ieSpell not detected. Do you want to install it now?"
     62},
     63advhr:{
     64advhr_desc:"Horizontale rule"
     65},
     66emotions:{
     67emotions_desc:"Emotions"
     68},
     69searchreplace:{
     70search_desc:"Find",
     71replace_desc:"Find/Replace"
     72},
     73advimage:{
     74image_desc:"Insert/edit image"
     75},
     76advlink:{
     77link_desc:"Insert/edit link"
     78},
     79xhtmlxtras:{
     80cite_desc:"Citation",
     81abbr_desc:"Abbreviation",
     82acronym_desc:"Acronym",
     83del_desc:"Deletion",
     84ins_desc:"Insertion",
     85attribs_desc:"Insert/Edit Attributes"
     86},
     87style:{
     88desc:"Edit CSS Style"
     89},
     90paste:{
     91paste_text_desc:"Paste as Plain Text",
     92paste_word_desc:"Paste from Word",
     93selectall_desc:"Select All"
     94},
     95paste_dlg:{
     96text_title:"Use CTRL+V on your keyboard to paste the text into the window.",
     97text_linebreaks:"Keep linebreaks",
     98word_title:"Use CTRL+V on your keyboard to paste the text into the window."
     99},
     100table:{
     101desc:"Inserts a new table",
     102row_before_desc:"Insert row before",
     103row_after_desc:"Insert row after",
     104delete_row_desc:"Delete row",
     105col_before_desc:"Insert column before",
     106col_after_desc:"Insert column after",
     107delete_col_desc:"Remove column",
     108split_cells_desc:"Split merged table cells",
     109merge_cells_desc:"Merge table cells",
     110row_desc:"Table row properties",
     111cell_desc:"Table cell properties",
     112props_desc:"Table properties",
     113paste_row_before_desc:"Paste table row before",
     114paste_row_after_desc:"Paste table row after",
     115cut_row_desc:"Cut table row",
     116copy_row_desc:"Copy table row",
     117del:"Delete table",
     118row:"Row",
     119col:"Column",
     120cell:"Cell"
     121},
     122autosave:{
     123unload_msg:"The changes you made will be lost if you navigate away from this page."
     124},
     125fullscreen:{
     126desc:"Toggle fullscreen mode"
     127},
     128media:{
     129desc:"Insert / edit embedded media",
     130edit:"Edit embedded media"
     131},
     132fullpage:{
     133desc:"Document properties"
     134},
     135template:{
     136desc:"Insert predefined template content"
     137},
     138visualchars:{
     139desc:"Visual control characters on/off."
     140},
     141spellchecker:{
     142desc:"Toggle spellchecker",
     143menu:"Spellchecker settings",
     144ignore_word:"Ignore word",
     145ignore_words:"Ignore all",
     146langs:"Languages",
     147wait:"Please wait...",
     148sug:"Suggestions",
     149no_sug:"No suggestions",
     150no_mpell:"No misspellings found."
     151},
     152pagebreak:{
     153desc:"Insert page break."
     154}}});
  • trunk/wp-includes/js/tinymce/plugins/autosave/editor_plugin.js

    r5256 r6632  
    11/**
    2  * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
     2 * $Id$
    33 *
    44 * @author Moxiecode
    5  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    66 */
    77
    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;
    1012
    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;
    2114
    22         // Private plugin internal methods
     15                        window.onbeforeunload = tinymce.plugins.AutoSavePlugin._beforeUnloadHandler;
     16                },
    2317
    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                },
    2627
    27                 if (tinyMCE.getParam("fullscreen_is_enabled"))
    28                         return;
     28                // Private plugin internal methods
    2929
    30                 for (n in tinyMCE.instances) {
    31                         inst = tinyMCE.instances[n];
     30                'static' : {
     31                        _beforeUnloadHandler : function() {
     32                                var msg;
    3233
    33                         if (!tinyMCE.isInstance(inst))
    34                                 continue;
     34                                tinymce.each(tinyMCE.editors, function(ed) {
     35                                        if (ed.getParam("fullscreen_is_enabled"))
     36                                                return;
    3537
    36                         if (inst.isDirty())
     38                                        if (ed.isDirty()) {
     39                                                msg = ed.getLang("autosave.unload_msg");
     40                                                return false;
     41                                        }
     42                                });
     43
    3744                                return msg;
     45                        }
    3846                }
     47        });
    3948
    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  
    11/**
    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 $
    33 *
    44 * @author Moxiecode
    5  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    66 */
    77
    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;
    1012
    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;
    2114
    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);
    2617
    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);
    2974                }
     75        });
    3076
    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
  • trunk/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js

    r6568 r6632  
    11/**
    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 $
    53 *
    64 * @author Moxiecode
    7  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    86 */
    97
    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                                }
    85391       
    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                        }
    104553                }
    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  
    11<html xmlns="http://www.w3.org/1999/xhtml">
    22<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">
     8function 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>
    1518</head>
    1619<body onload="init();">
  • trunk/wp-includes/js/tinymce/plugins/paste/css/blank.css

    • Property svn:eol-style set to native
    r3664 r6632  
     1html, body {height:98%}
    12body {
    2         background-color: #FFFFFF;
    3         font-family: Verdana, Arial, Helvetica, sans-serif;
    4         font-size: 10px;
    5         scrollbar-3dlight-color: #F0F0EE;
    6         scrollbar-arrow-color: #676662;
    7         scrollbar-base-color: #F0F0EE;
    8         scrollbar-darkshadow-color: #DDDDDD;
    9         scrollbar-face-color: #E0E0DD;
    10         scrollbar-highlight-color: #F0F0EE;
    11         scrollbar-shadow-color: #F0F0EE;
    12         scrollbar-track-color: #F5F5F5;
     3background-color: #FFFFFF;
     4font-family: Verdana, Arial, Helvetica, sans-serif;
     5font-size: 10px;
     6scrollbar-3dlight-color: #F0F0EE;
     7scrollbar-arrow-color: #676662;
     8scrollbar-base-color: #F0F0EE;
     9scrollbar-darkshadow-color: #DDDDDD;
     10scrollbar-face-color: #E0E0DD;
     11scrollbar-highlight-color: #F0F0EE;
     12scrollbar-shadow-color: #F0F0EE;
     13scrollbar-track-color: #F5F5F5;
    1314}
  • trunk/wp-includes/js/tinymce/plugins/paste/css/pasteword.css

    • Property svn:eol-style set to native
  • trunk/wp-includes/js/tinymce/plugins/paste/editor_plugin.js

    r5256 r6632  
    11/**
    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 $
    33 *
    44 * @author Moxiecode
    5  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    66 */
    77
    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>&nbsp;<\/p>/gi, ""); // Remove pagebreaks
     207                                content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks
     208
     209                //              content = content.replace(/\/?&nbsp;*/gi, ""); &nbsp;
     210                //              content = content.replace(/<p>&nbsp;<\/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]>&nbsp;<\/h[1-6]>/gi, '<p>&nbsp;&nbsp;</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>&nbsp;<\/b>/gi, '<b>&nbsp;&nbsp;</b>');
     243                                        content = content.replace(/^(&nbsp;)*/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--|&nbsp;', "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+|&nbsp;)').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--|&nbsp;', "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;
    32378                }
    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>&nbsp;<\/p>/gi, ""); // Remove pagebreaks
    225                         content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks
    226 
    227         //              content = content.replace(/\/?&nbsp;*/gi, ""); &nbsp;
    228         //              content = content.replace(/<p>&nbsp;<\/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]>&nbsp;<\/h[1-6]>/gi, '<p>&nbsp;&nbsp;</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>&nbsp;<\/b>/gi, '<b>&nbsp;&nbsp;</b>');
    262                                 content = content.replace(/^(&nbsp;)*/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--|&nbsp;', "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+|&nbsp;)').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--|&nbsp;', "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  
    11<html xmlns="http://www.w3.org/1999/xhtml">
    22<head>
    3         <title>{$lang_paste_text_desc}</title>
     3        <title>{#paste.paste_text_desc}</title>
    44        <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>
    77        <base target="_self" />
    88</head>
    9 <body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');" onresize="resizeInputs();" style="display: none">
     9<body onresize="resizeInputs();" style="display:none; overflow:hidden;">
    1010<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>
    1212
    1313        <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>
    1515        </div>
    1616
    1717        <br style="clear: both" />
    1818
    19         <div>{$lang_paste_text_title}</div>
     19        <div>{#paste_dlg.text_title}</div>
    2020
    2121        <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>
     
    2323        <div class="mceActionPanel">
    2424                <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" />
    2626                </div>
    2727
    2828                <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" />
    3030                </div>
    3131        </div>
  • trunk/wp-includes/js/tinymce/plugins/paste/pasteword.htm

    • Property svn:eol-style set to native
    r3664 r6632  
    22<head>
    33        <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>
    77        <link href="css/pasteword.css" rel="stylesheet" type="text/css" />
    88        <base target="_self" />
    99</head>
    10 <body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');" onresize="resizeInputs();" style="display: none">
     10<body onresize="resizeInputs();" style="display:none; overflow:hidden;">
    1111        <form name="source" onsubmit="saveContent();" action="#">
    12                 <div class="title">{$lang_paste_word_desc}</div>
     12                <div class="title">{#paste.paste_word_desc}</div>
    1313
    14                 <div>{$lang_paste_word_title}</div>
     14                <div>{#paste_dlg.word_title}</div>
    1515
    1616                <div id="iframecontainer"></div>
     
    1818                <div class="mceActionPanel">
    1919                        <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();" />
    2121                        </div>
    2222
    2323                        <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();" />
    2525                        </div>
    2626                </div>
  • trunk/wp-includes/js/tinymce/plugins/spellchecker/config.php

    r6360 r6632  
    11<?php
    2         $spellCheckerConfig = array();
     2        // General settings
     3        $config['general.engine'] = 'GoogleSpell';
     4        //$config['general.engine'] = 'PSpell';
     5        //$config['general.engine'] = 'PSpellShell';
    36
    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'] = "";
    812
    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';
    1117
    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';
    2421?>
  • 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;}
  • trunk/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css

    • Property svn:eol-style set to native
  • trunk/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js

    r6360 r6632  
    11/**
    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 $
    33 *
    44 * @author Moxiecode
    5  * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
     5 * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
    66 */
    77
    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;
    135117                        }
    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                        });
    549188
    550189                        r1 = new RegExp('([' + re + '])(' + w + ')([' + re + '])', 'g');
     
    554193                        r5 = new RegExp('(' + w + ')([' + re + '])', 'g');
    555194
    556                         if (r1.test(nv) || r2.test(nv) || r3.test(nv) || r4.test(nv)) {
    557                                 nv = tinyMCE.xmlEncode(nv).replace('&#39;', "'");
    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;
    567236                        }
     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                        });
    568331                }
    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  
    11/* Import plugin specific language pack */
    2 tinyMCE.importPluginLanguagePack('wordpress', 'en');
     2//tinyMCE.importPluginLanguagePack('wordpress', 'en');
    33
    44var TinyMCE_wordpressPlugin = {
     
    288288                // We have a TON of cleanup to do.
    289289
     290        if ( tinyMCE.activeEditor.isHidden() ) {
     291    //        return content;           
     292        }
     293   
    290294                // Mark </p> if it has any attributes.
    291295                content = content.replace(new RegExp('(<p[^>]+>.*?)</p>', 'mg'), '$1</p#>');
     
    295299
    296300                // Get it ready for wpautop.
    297                 content = content.replace(new RegExp('\\s*<p>', 'mgi'), '');
     301        content = content.replace(new RegExp('\\s*<p>', 'mgi'), '');
    298302                content = content.replace(new RegExp('\\s*</p>\\s*', 'mgi'), '\n\n');
    299303                content = content.replace(new RegExp('\\n\\s*\\n', 'mgi'), '\n\n');
     
    305309                content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
    306310                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               
    308317                // Unmark special paragraph closing tags
    309318                content = content.replace(new RegExp('</p#>', 'g'), '</p>\n');
     
    366375};
    367376
    368 tinyMCE.addPlugin("wordpress", TinyMCE_wordpressPlugin);
     377//tinyMCE.addPlugin("wordpress", TinyMCE_wordpressPlugin);
    369378
    370379/* This little hack protects our More and Page placeholders from the removeformat command */
     
    477486        var pdr = ta.parentNode;
    478487
    479         if ( inst ) {
     488        if ( ! inst.isHidden(id) ) {
    480489                edToggle(H, P);
    481490
     
    493502                var y1 = table.offsetTop + table.offsetHeight;
    494503
    495                 if ( TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_height") == null ) {
     504                if ( tinymce.util.Cookie.get("TinyMCE_" + inst.editorId + "_height") == null ) {
    496505                        var expires = new Date();
    497506                        expires.setTime(expires.getTime() + 3600000 * 24 * 30);
    498507                        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);
    500509                }
    501510
    502511                // 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;
    508517
    509518                // Reveal Quicktags and textarea
     
    544553
    545554                // 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 {
    547559                        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                //}
    554563
    555564                if ( tinyMCE.isMSIE && !tinyMCE.isOpera ) {
  • trunk/wp-includes/js/tinymce/plugins/wordpress/popups.css

    • Property svn:eol-style set to native
  • trunk/wp-includes/js/tinymce/plugins/wordpress/wordpress.css

    • Property svn:eol-style set to native
  • 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">
    12<html xmlns="http://www.w3.org/1999/xhtml">
    23<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>
    88</head>
    9 <body id="about" onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
     9<body id="about" style="display: none">
    1010                <div class="tabs">
    1111                        <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>
    1515                        </ul>
    1616                </div>
     
    1818                <div class="panel_wrapper">
    1919                        <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>
    2222                                <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>
    2323                                by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.</p>
     
    2525                                <p>For more information about this software visit the <a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE website</a>.</p>
    2626
    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>
    2832                        </div>
    2933
    3034                        <div id="plugins_panel" class="panel">
    3135                                <div id="pluginscontainer">
    32                                         <h3>{$lang_loaded_plugins}</h3>
     36                                        <h3>{#advanced_dlg.about_loaded}</h3>
    3337
    3438                                        <div id="plugintablecontainer">
     
    4650                <div class="mceActionPanel">
    4751                        <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();" />
    4953                        </div>
    5054                </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">
    12<html xmlns="http://www.w3.org/1999/xhtml">
    23<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>
    67        <base target="_self" />
    78</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="#">
    1111        <table border="0" cellpadding="4" cellspacing="0">
    1212                <tr>
    13                         <td colspan="2" class="title">{$lang_insert_anchor_title}</td>
     13                        <td colspan="2" class="title">{#advanced_dlg.anchor_title}</td>
    1414                </tr>
    1515                <tr>
    16                         <td nowrap="nowrap">{$lang_insert_anchor_name}:</td>
     16                        <td nowrap="nowrap">{#advanced_dlg.anchor_name}:</td>
    1717                        <td><input name="anchorName" type="text" id="anchorName" value="" style="width: 200px" /></td>
    1818                </tr>
     
    2121        <div class="mceActionPanel">
    2222                <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();" />
    2424                </div>
    2525
    2626                <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();" />
    2828                </div>
    2929        </div>
    30 
    3130</form>
    3231</body>
  • trunk/wp-includes/js/tinymce/themes/advanced/charmap.htm

    r4506 r6632  
    11<html xmlns="http://www.w3.org/1999/xhtml">
    22<head>
    3         <title>{$lang_theme_charmap_title}</title>
     3        <title>{#advanced_dlg.charmap_title}</title>
    44        <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>
    77        <base target="_self" />
    88</head>
    9 <body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
     9<body style="display: none">
    1010<table align="center" border="0" cellspacing="0" cellpadding="2">
    1111    <tr>
    12         <td colspan="2" class="title">{$lang_theme_charmap_title}</td>
     12        <td colspan="2" class="title">{#advanced_dlg.charmap_title}</td>
    1313    </tr>
    1414    <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 -->
    1717        </td>
    1818        <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">
    12<html xmlns="http://www.w3.org/1999/xhtml">
    23<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>
    88        <base target="_self" />
    99</head>
    10 <body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
     10<body id="colorpicker" style="display: none">
    1111        <div class="tabs">
    1212                <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>
    1616                </ul>
    1717        </div>
     
    2020                <div id="picker_panel" class="panel current">
    2121                        <fieldset>
    22                                 <legend>{$lang_color_picker}</legend>
     22                                <legend>{#advanced_dlg.colorpicker_picker_title}</legend>
    2323                                <div id="picker">
    24                                         <img id="colorpicker" 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;" />
    2525
    2626                                        <div id="light">
     
    3535                <div id="rgb_panel" class="panel">
    3636                        <fieldset>
    37                                 <legend>{$lang_web_colors}</legend>
     37                                <legend>{#advanced_dlg.colorpicker_palette_title}</legend>
    3838                                <div id="webcolors">
    3939                                        <!-- Gets filled with web safe colors-->
     
    4646                <div id="named_panel" class="panel">
    4747                        <fieldset>
    48                                 <legend>{$lang_named_colors}</legend>
     48                                <legend>{#advanced_dlg.colorpicker_named_title}</legend>
    4949                                <div id="namedcolors">
    5050                                        <!-- Gets filled with named colors-->
     
    5454
    5555                                <div id="colornamecontainer">
    56                                         {$lang_color_name} <span id="colorname"></span>
     56                                        {#advanced_dlg.colorpicker_name} <span id="colorname"></span>
    5757                                </div>
    5858                        </fieldset>
     
    6262        <div class="mceActionPanel">
    6363                <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();" />
    6565                </div>
    6666
     
    6868
    6969                <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" />
    7171                </div>
    7272        </div>
  • trunk/wp-includes/js/tinymce/themes/advanced/css/colorpicker.css

    • Property svn:eol-style set to native
  • trunk/wp-includes/js/tinymce/themes/advanced/css/editor_content.css

    • Property svn:eol-style set to native
  • trunk/wp-includes/js/tinymce/themes/advanced/css/editor_popup.css

    • Property svn:eol-style set to native
  • trunk/wp-includes/js/tinymce/themes/advanced/css/editor_ui.css

    • Property svn:eol-style set to native
  • trunk/wp-includes/js/tinymce/themes/advanced/editor_template.js

    r5577 r6632  
    11/**
    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 $
    33 *
    44 * @author Moxiecode
    5  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    66 */
    77
    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="&lt;' + lookup[x][0] + '&gt;">' + 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);
    104370                                        }
     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;
    105499                                }
    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') + ': ' : '&nbsp;');
     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;
    123823                                        }
    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") + '">&#160;</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 += " &raquo; ";
    939                                 }
    940                         }
    941 
    942                         pathElm.innerHTML = '<a href="#" accesskey="x"></a>' + tinyMCE.getLang('lang_theme_path') + ": " + html + '&#160;';
    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;
    1013836                                                }
    1014837                                        }
     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);
    1015976                                }
    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                        });
    1019988                }
    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">
    12<html xmlns="http://www.w3.org/1999/xhtml">
    23<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>
    89        <base target="_self" />
    910</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="#">
    1313        <div class="tabs">
    1414                <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>
    1616                </ul>
    1717        </div>
     
    2121     <table border="0" cellpadding="4" cellspacing="0">
    2222          <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>
    2424            <td><table border="0" cellspacing="0" cellpadding="0">
    2525                <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>
    2727                  <td id="srcbrowsercontainer">&nbsp;</td>
    2828                </tr>
    2929              </table></td>
    3030          </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>
    4935          <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>
    5137            <td><input id="alt" name="alt" type="text" value="" style="width: 200px" /></td>
    5238          </tr>
    5339          <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>
    6651              </select></td>
    6752          </tr>
    6853          <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>
    7055            <td><input id="width" name="width" type="text" value="" size="3" maxlength="5" />
    7156              x
     
    7358          </tr>
    7459          <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>
    7762          </tr>
    7863          <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>
    8166          </tr>
    8267          <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>
    8570          </tr>
    8671        </table>
     
    8974
    9075        <div class="mceActionPanel">
    91                 <!-- WordPress: buttons reversed! -->
    9276                <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();" />
    9478                </div>
    9579
    9680                <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();" />
    9882                </div>
    9983        </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?'
     1tinyMCE.addI18n('en.advanced',{
     2style_select:"Styles",
     3font_size:"Font size",
     4fontdefault:"Font family",
     5block:"Format",
     6paragraph:"Paragraph",
     7div:"Div",
     8address:"Address",
     9pre:"Preformatted",
     10h1:"Heading 1",
     11h2:"Heading 2",
     12h3:"Heading 3",
     13h4:"Heading 4",
     14h5:"Heading 5",
     15h6:"Heading 6",
     16blockquote:"Blockquote",
     17code:"Code",
     18samp:"Code sample",
     19dt:"Definition term ",
     20dd:"Definition description",
     21bold_desc:"Bold (Ctrl+B)",
     22italic_desc:"Italic (Ctrl+I)",
     23underline_desc:"Underline (Ctrl+U)",
     24striketrough_desc:"Strikethrough",
     25justifyleft_desc:"Align left",
     26justifycenter_desc:"Align center",
     27justifyright_desc:"Align right",
     28justifyfull_desc:"Align full",
     29bullist_desc:"Unordered list",
     30numlist_desc:"Ordered list",
     31outdent_desc:"Outdent",
     32indent_desc:"Indent",
     33undo_desc:"Undo (Ctrl+Z)",
     34redo_desc:"Redo (Ctrl+Y)",
     35link_desc:"Insert/edit link",
     36unlink_desc:"Unlink",
     37image_desc:"Insert/edit image",
     38cleanup_desc:"Cleanup messy code",
     39code_desc:"Edit HTML Source",
     40sub_desc:"Subscript",
     41sup_desc:"Superscript",
     42hr_desc:"Insert horizontal ruler",
     43removeformat_desc:"Remove formatting",
     44custom1_desc:"Your custom description here",
     45forecolor_desc:"Select text color",
     46backcolor_desc:"Select background color",
     47charmap_desc:"Insert custom character",
     48visualaid_desc:"Toggle guidelines/invisible elements",
     49anchor_desc:"Insert/edit anchor",
     50cut_desc:"Cut",
     51copy_desc:"Copy",
     52paste_desc:"Paste",
     53image_props_desc:"Image properties",
     54newdocument_desc:"New document",
     55help_desc:"Help",
     56blockquote_desc:"Blockquote",
     57clipboard_msg:"Copy/Cut/Paste is not available in Mozilla and Firefox.\r\nDo you want more information about this issue?",
     58path:"Path",
     59newdocument:"Are you sure you want clear all contents?",
     60toolbar_focus:"Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X",
     61more_colors:"More colors"
    9362});
  • 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">
    12<html xmlns="http://www.w3.org/1999/xhtml">
    23<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>
    910        <base target="_self" />
    1011</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="#">
    1414        <div class="tabs">
    1515                <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>
    1717                </ul>
    1818        </div>
     
    2323                <table border="0" cellpadding="4" cellspacing="0">
    2424          <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>
    2626            <td><table border="0" cellspacing="0" cellpadding="0">
    2727                                  <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>
    2929                                        <td id="hrefbrowsercontainer">&nbsp;</td>
    3030                                  </tr>
    3131                                </table></td>
    3232          </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>
    5141          <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>
    7544          </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>
    8749        </table>
    8850                </div>
     
    9052
    9153        <div class="mceActionPanel">
    92                 <!-- WordPress: Buttons are reversed! -->
    9354                <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();" />
    9556                </div>
    9657
    9758                <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();" />
    9960                </div>
    10061        </div>
  • trunk/wp-includes/js/tinymce/themes/advanced/source_editor.htm

    r5577 r6632  
    22<head>
    33        <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>
    77        <base target="_self" />
    88</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;">
    1110        <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>
    1312
    1413                <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>
    1615                </div>
    1716
    1817                <br style="clear: both" />
    1918
    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>
    2120
    2221                <div class="mceActionPanel">
    23                         <!-- WordPress: reversed buttons! -->
    2422                        <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" />
    2624                        </div>
    2725
    2826                        <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" />
    3028                        </div>
    3129                </div>
  • trunk/wp-includes/js/tinymce/tiny_mce.js

    r6568 r6632  
    11
    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
     4var 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;
    6626                        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])
    72184                        return;
    73185
    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;
    115194                }
    116195
    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;
    128200                }
    129201
    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                        });
    242246                }
    243247
    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);
    346255        },
    347256
    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                        });
    359270                }
    360271        },
    361272
    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;
    368289        },
    369290
    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;
    372305        },
    373306
    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;
    382350        },
    383351
    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
     369window.tinymce = tinymce;
     370
     371// Initialize the API
     372tinymce._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
     382tinymce.create('tinymce.util.Dispatcher', {
     383        scope : null,
     384        listeners : null,
     385
     386        Dispatcher : function(s) {
     387                this.scope = s || this;
     388                this.listeners = [];
    391389        },
    392390
    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;
    398395        },
    399396
    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;
    402401        },
    403402
    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;
    408415        },
    409416
    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;
    423444                                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;
    462542                                                break;
    463543                                        }
    464544                                }
    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(/&lt;/g, '<');
    886                         content = content.replace(/&gt;/g, '>');
    887                         content = content.replace(/&quot;/g, '"');
    888                         content = content.replace(/&amp;/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 = "&nbsp;&nbsp;";
    1312                                                         else
    1313                                                                 elm.innerHTML = "&nbsp;";
    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;
    1324551                                                break;
    1325552                                        }
    1326553                                }
    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;
    1423651                }
     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
     732tinymce.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;
    1424773        },
    1425774
    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) {
    2122776                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 '&amp;';
    2405 
    2406                                 case '"':
    2407                                         return '&quot;';
    2408 
    2409                                 case '<':
    2410                                         return '&lt;';
    2411 
    2412                                 case '>':
    2413                                         return '&gt;';
    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 + ')');
    2588778                } catch (ex) {
    2589779                        // Ignore
    2590780                }
    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
     787tinymce.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);
    2597835                }
    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
    2609837                }
    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);
    2678888                        }
    2679889                }
    2680890
    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;
    28961004                                        }
    28971005
    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
    30901010                                                }
    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, &amp;, &nbsp; etc will be encoded wrong in FF
    3439                                                 if (value.indexOf('<') == -1 && !value.match(/(&#38;|&#160;|&#60;|&#62;)/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
    36771027                        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, "&#40;", "(", "gi");
    4017                 htm = tinyMCE.regexpReplace(htm, "&#41;", ")", "gi");
    4018                 htm = tinyMCE.regexpReplace(htm, "&#59;", ";", "gi");
    4019                 htm = tinyMCE.regexpReplace(htm, "&#34;", "&quot;", "gi");
    4020                 htm = tinyMCE.regexpReplace(htm, "&#94;", "^", "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>&nbsp;</p>');
    4044                 s = s.replace(new RegExp('<p>\\s*<\\/p>', 'gi'), '<p>&nbsp;</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 = '&nbsp;';
    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' ? '&#160;' : '&nbsp;';
    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>(&nbsp;|&#160;)<\/p><hr \/><p>(&nbsp;|&#160;)<\/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*(&nbsp;|&#160;)\s*<br \/>\s*(&nbsp;|&#160;)\s*<\/p>/g, '<p>' + nb + '</p>');
    4413                 h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
    4414                 h = h.replace(/<p>\s*<br \/>\s*&nbsp;\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>&nbsp;<\/p>|<p>&#160;<\/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(/&nbsp;\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>(&nbsp;|&#160;)<\/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" ? "&nbsp;" : "&#160;";
    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">&nbsp;</p>'); // Keep empty paragraphs
    5323                         h = h.replace(/<p([^>]*)>\s*&nbsp;\s*<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
    5324                         h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</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
    60971034                        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());
    63671047                                };
    63681048                        } 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 '&amp;';
     1860
     1861                                        case '"':
     1862                                                return '&quot;';
     1863
     1864                                        case '<':
     1865                                                return '&lt;';
     1866
     1867                                        case '>':
     1868                                                return '&gt;';
     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;
    63812585
    63822586                                return {
     
    63872591                                };
    63882592                        }
    6389                 } else {
    6390                         s = this.getSel();
    6391                         e = this.getFocusElement();
     2593
     2594                        // Handle W3C
     2595                        e = t.getNode();
     2596                        s = t.getSel();
    63922597
    63932598                        if (!s)
    63942599                                return null;
    63952600
     2601                        // Image selection
    63962602                        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 
    64052603                                return {
    6406                                         start : -1,
    6407                                         end : -1,
    6408                                         index : sp,
    64092604                                        scrollX : sx,
    64102605                                        scrollY : sy
     
    64122607                        }
    64132608
     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
    64142629                        // Caret or selection
    64152630                        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);
    64172632
    64182633                                if (!e)
     
    64262641                                };
    64272642                        } else {
    6428                                 e = this._getPosText(b, rng.startContainer, rng.endContainer);
     2643                                e = getPos(ro, r.startContainer, r.endContainer);
    64292644
    64302645                                if (!e)
     
    64322647
    64332648                                return {
    6434                                         start : e.start + rng.startOffset,
    6435                                         end : e.end + rng.endOffset,
     2649                                        start : e.start + r.startOffset,
     2650                                        end : e.end + r.endOffset,
    64362651                                        scrollX : sx,
    64372652                                        scrollY : sy
    64382653                                };
    64392654                        }
     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();
    64402914                }
    64412915
    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 &gt; 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 &gt; 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 &gt; we need to do it our self to normalize the output for all browsers
     3000                        if (tinymce.isOpera)
     3001                                h = h.replace(/\|>/g, '&gt;');
     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 = '&nbsp;';
     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 &amp; &quot; 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 &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor
     3528                                if (o.set)
     3529                                        h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');
     3530                                else
     3531                                        h = h.replace(/<p>\s+(&nbsp;|&#160;|\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 &nbsp;
     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
     4146tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
     4147        Container : function(id, s) {
     4148                this.parent(id, s);
     4149                this.controls = [];
     4150                this.lookup = {};
    64434151        },
    64444152
    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
     4169tinymce.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
     5166tinymce.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
    64505485                        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
     5542var 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>(&nbsp;|#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
    64546366                        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;
    64557316                }
    64567317
    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
    64597873                                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);
    64617984                                } catch (ex) {
    64627985                                        // Ignore
    64637986                                }
    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
     8110tinymce.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|&#160;|&nbsp;)<\/p>/g, '</p>');
     8272
     8273                                o.content = o.content.replace(/<p><\/p>/g, '<p>\u00a0</p>');
     8274
     8275                                // Use BR instead of &nbsp; 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>&nbsp;</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)
    64658367                                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 {
    64768441                                        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();
    64788448                                        } catch (ex) {
    6479                                                 // Might be thrown if the node no longer exists
     8449                                                // Ignore
    64808450                                        }
    64818451                                }
     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);
    64828592                        } 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 ? '&nbsp;' : '<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);
    65038680                }
    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();
    65388704                                });
    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();
    65448974                }
    65458975
    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');
    65629086                }
    65639087
    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 = "&nbsp;";
    7081 
    7082                                 // Check if it's a empty paragraph
    7083                                 if (isEmpty(paraAfter))
    7084                                         paraAfter.innerHTML = "&nbsp;";
    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 + ">&nbsp;</" + blockName + "><" + blockName + ">&nbsp;</" + 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 = "&nbsp;";
    7145 
    7146                 // Check if it's a empty paragraph
    7147                 if (isEmpty(paraAfter))
    7148                         paraAfter.innerHTML = "&nbsp;";
    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  
    2828        $invalid_elements = apply_filters('mce_invalid_elements', '');
    2929
    30         $plugins = array('inlinepopups', 'autosave', 'spellchecker', 'paste', 'wordpress');
     30        $plugins = array( 'safari', 'inlinepopups', 'autosave', 'spellchecker', 'paste', 'wordpress', 'media' );
    3131        $plugins = apply_filters('mce_plugins', $plugins);
    3232        $plugins = implode($plugins, ',');
    3333
    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'));
    3535        $mce_buttons = implode($mce_buttons, ',');
    3636
    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'));
    3838        $mce_buttons_2 = implode($mce_buttons_2, ',');
    3939
     
    5555?>
    5656
     57/*
    5758wpEditorInit = function() {
    5859        // Activate tinyMCE if it's the user's default editor
    5960        if ( ( 'undefined' == typeof wpTinyMCEConfig ) || 'tinymce' == wpTinyMCEConfig.defaultEditor )
    60                 tinyMCE.execCommand("mceAddControl", true, 'content');
     61                tinyMCE.execCommand('mceAddControl', false, 'content');
    6162};
     63*/
     64
     65wpEditorInit = function() {
     66    if ( ( 'undefined' != typeof wpTinyMCEConfig ) && 'tinymce' != wpTinyMCEConfig.defaultEditor )
     67        tinyMCE.get('content').hide();
     68}
    6269
    6370initArray = {
    64         mode : "specific_textareas",
    65         editor_selector : "mceEditor",
     71        mode : "exact",
     72        elements : "content",
     73//      editor_selector : "mceEditor",
    6674        oninit : "wpEditorInit",
    6775        width : "100%",
    6876        theme : "advanced",
     77        skin : "o2k7",
    6978        theme_advanced_buttons1 : "<?php echo $mce_buttons; ?>",
    7079        theme_advanced_buttons2 : "<?php echo $mce_buttons_2; ?>",
     
    7382        theme_advanced_toolbar_location : "top",
    7483        theme_advanced_toolbar_align : "left",
    75         theme_advanced_path_location : "bottom",
     84        theme_advanced_statusbar_location : "bottom",
    7685        theme_advanced_resizing : true,
    7786        browsers : "<?php echo $mce_browsers; ?>",
  • trunk/wp-includes/js/tinymce/tiny_mce_gzip.php

    r5700 r6632  
    1010 * Notice: This script defaults the button_tile_map option to true for extra performance.
    1111 */
    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   
    1520        // Get input
    1621        $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
     2var tinymce = null, tinyMCEPopup, tinyMCE;
     3
     4tinyMCEPopup = {
     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                        });
    16167                }
    17168
    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);
    23188                }
    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);
    107215                        }
    108216                }
    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                 else
    122                         eval(str);
    123         },
    124 
    125         resizeToInnerSize : function() {
    126                 var i, doc, body, oldMargin, wrapper, iframe, nodes, dx, dy;
    127 
    128                 // Netscape 7.1 workaround
    129                 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 margin
    142                         oldMargin = body.style.margin;
    143                         body.style.margin = '0';
    144 
    145                         // Create wrapper
    146                         wrapper = doc.createElement("div");
    147                         wrapper.id = 'mcBodyWrapper';
    148                         wrapper.style.display = 'none';
    149                         wrapper.style.margin = '0';
    150 
    151                         // Wrap body elements
    152                         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                                 else
    157                                         wrapper.appendChild(nodes[i].cloneNode(true));
    158 
    159                                 nodes[i].parentNode.removeChild(nodes[i]);
    160                         }
    161 
    162                         // Add wrapper
    163                         doc.body.appendChild(wrapper);
    164 
    165                         // Create iframe
    166                         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 iframe
    174                         doc.body.appendChild(iframe);
    175 
    176                         // Measure iframe
    177                         iframe = document.getElementById('mcWinIframe');
    178                         dx = tinyMCE.getWindowArg('mce_width') - iframe.clientWidth;
    179                         dy = tinyMCE.getWindowArg('mce_height') - iframe.clientHeight;
    180 
    181                         // Resize window
    182                         // tinyMCE.debug(tinyMCE.getWindowArg('mce_width') + "," + tinyMCE.getWindowArg('mce_height') + " - " + dx + "," + dy);
    183                         window.resizeBy(dx, dy);
    184 
    185                         // Hide iframe and show wrapper
    186                         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 selection
    247                 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 : false
    261                 });
    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 callback
    272                 if (eval('typeof(tinyMCEPopup.windowOpener.' + cb + ')') == "undefined")
    273                         alert("Callback function: " + cb + " could not be found.");
    274                 else
    275                         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;
    287217        }
    288 
    289         };
    290 
    291 // Setup global instance
    292 var tinyMCEPopup = new TinyMCE_Popup();
     218};
    293219
    294220tinyMCEPopup.init();
     221tinyMCEPopup._wait(); // Wait for DOM Content Loaded
  • trunk/wp-includes/js/tinymce/utils/editable_selects.js

    • Property svn:eol-style set to native
    r4799 r6632  
    11/**
    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 $
    33 *
    44 * Makes select boxes editable.
    55 *
    66 * @author Moxiecode
    7  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    88 */
    99
     
    2121
    2222                                nl[i].options[nl[i].options.length] = o;
    23                                 nl[i].setAttribute('onchange', 'TinyMCE_EditableSelects.onChangeEditableSelect(this);');
     23                                nl[i].onchange = TinyMCE_EditableSelects.onChangeEditableSelect;
    2424                        }
    2525                }
    2626        },
    2727
    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;
    3030
    3131                if (se.options[se.selectedIndex].value == '__mce_add_custom__') {
     
    3535                        ne.type = "text";
    3636
    37                         ne.style.width = se.clientWidth;
     37                        ne.style.width = se.offsetWidth + 'px';
    3838                        se.parentNode.insertBefore(ne, se);
    3939                        se.style.display = 'none';
  • trunk/wp-includes/js/tinymce/utils/form_utils.js

    r4799 r6632  
    11/**
    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 $
    33 *
    44 * Various form utilitiy functions.
    55 *
    66 * @author Moxiecode
    7  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    88 */
    99
    10 var themeBaseURL = tinyMCE.baseURL + '/themes/' + tinyMCE.getParam("theme");
     10var themeBaseURL = tinyMCEPopup.editor.baseURI.toAbsolute('themes/' + tinyMCEPopup.getParam("theme"));
    1111
    1212function getColorPickerHTML(id, target_form_element) {
    1313        var h = "";
    1414
    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>';
    2217
    2318        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);
    2919}
    3020
     
    4131                        lnk.setAttribute("realhref", lnk.getAttribute("href"));
    4232                        lnk.removeAttribute("href");
    43                         tinyMCE.switchClass(img, 'mceButtonDisabled', true);
     33                        tinyMCEPopup.dom.addClass(img, 'disabled');
    4434                } else {
    4535                        lnk.setAttribute("href", lnk.getAttribute("realhref"));
    46                         tinyMCE.switchClass(img, 'mceButtonNormal', false);
     36                        tinyMCEPopup.dom.removeClass(img, 'disabled');
    4737                }
    4838        }
     
    5040
    5141function 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)
    5547                return "";
    5648
    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>';
    6652
    6753        return html;
    6854}
    6955
    70 function openBrower(img_id, target_form_element, type, option) {
     56function openBrowser(img_id, target_form_element, type, option) {
    7157        var img = document.getElementById(img_id);
    7258
     
    120106        // Setup class droplist
    121107        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);
    124110
    125111        if (styles) {
     
    137123                }
    138124        } 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                });
    143128        }
    144129}
     
    197182
    198183function getStyle(elm, attrib, style) {
    199         var val = tinyMCE.getAttrib(elm, attrib);
     184        var val = tinyMCEPopup.dom.getAttrib(elm, attrib);
    200185
    201186        if (val != '')
     
    205190                style = attrib;
    206191
    207         val = eval('elm.style.' + style);
    208 
    209         return val == null ? '' : '' + val;
     192        return tinyMCEPopup.dom.getStyle(elm, style);
    210193}
  • trunk/wp-includes/js/tinymce/utils/mclayer.js

    r4799 r6632  
    11/**
    2  * $Id: mclayer.js 162 2007-01-03 16:16:52Z spocke $
     2 * $Id: mclayer.js 520 2008-01-07 16:30:32Z spocke $
    33 *
    44 * Moxiecode floating layer script.
    55 *
    66 * @author Moxiecode
    7  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    88 */
    99
  • trunk/wp-includes/js/tinymce/utils/mctabs.js

    r4799 r6632  
    11/**
    2  * $Id: mctabs.js 162 2007-01-03 16:16:52Z spocke $
     2 * $Id: mctabs.js 520 2008-01-07 16:30:32Z spocke $
    33 *
    44 * Moxiecode DHTML Tabs script.
    55 *
    66 * @author Moxiecode
    7  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    88 */
    99
  • trunk/wp-includes/js/tinymce/utils/validate.js

    r4799 r6632  
    11/**
    2  * $Id: validate.js 162 2007-01-03 16:16:52Z spocke $
     2 * $Id: validate.js 520 2008-01-07 16:30:32Z spocke $
    33 *
    44 * Various form validation methods.
    55 *
    66 * @author Moxiecode
    7  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     7 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
    88 */
    99
Note: See TracChangeset for help on using the changeset viewer.