Make WordPress Core

Changeset 6632


Ignore:
Timestamp:
01/17/2008 03:44:05 PM (16 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