Make WordPress Core

Changeset 3664


Ignore:
Timestamp:
03/30/2006 07:50:33 AM (21 years ago)
Author:
ryan
Message:

tinyMCE 2.0.5 coming at you live. fixes #2598

Location:
trunk
Files:
53 added
41 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/admin-header.php

    r3660 r3664  
    5858<script type="text/javascript" src="../wp-includes/js/dbx-key.js"></script>
    5959<?php } ?>
    60 <?php if ( $editing && user_can_richedit() ) { ?>
    61 <script type="text/javascript" src="../wp-includes/js/tinymce/tiny_mce_gzip.php?ver=20051211"></script>
    62 <?php } ?>
     60<?php if ( $editing && user_can_richedit() ) { tinymce_include(); } ?>
    6361<?php if ( $cat_js ) { ?>
    6462<script type="text/javascript" src="cat-js.php"></script>
  • trunk/wp-admin/edit-form-advanced.php

    r3660 r3664  
    144144<legend><?php _e('Post') ?></legend>
    145145
    146 <?php
    147  $rows = get_settings('default_post_edit_rows');
    148  if (($rows < 3) || ($rows > 100)) {
    149      $rows = 12;
    150  }
    151 ?>
    152 <?php the_quicktags(); ?>
    153 
    154 <div><textarea <?php if ( user_can_richedit() ) echo 'title="true" '; ?>rows="<?php echo $rows; ?>" cols="40" name="content" tabindex="2" id="content"><?php echo user_can_richedit() ? wp_richedit_pre($post->post_content) : $post->post_content; ?></textarea></div>
    155 </fieldset>
    156 
    157 <script type="text/javascript">
    158 <!--
    159 edCanvas = document.getElementById('content');
    160 <?php if ( user_can_richedit() ) : ?>
    161 // This code is meant to allow tabbing from Title to Post (TinyMCE).
    162 if ( tinyMCE.isMSIE )
    163         document.getElementById('title').onkeydown = function (e)
    164                 {
    165                         e = e ? e : window.event;
    166                         if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
    167                                 var i = tinyMCE.selectedInstance;
    168                                 if(typeof i ==  'undefined')
    169                                         return true;
    170                                 tinyMCE.execCommand("mceStartTyping");
    171                                 this.blur();
    172                                 i.contentWindow.focus();
    173                                 e.returnValue = false;
    174                                 return false;
    175                         }
    176                 }
    177 else
    178         document.getElementById('title').onkeypress = function (e)
    179                 {
    180                         e = e ? e : window.event;
    181                         if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
    182                                 var i = tinyMCE.selectedInstance;
    183                                 if(typeof i ==  'undefined')
    184                                         return true;
    185                                 tinyMCE.execCommand("mceStartTyping");
    186                                 this.blur();
    187                                 i.contentWindow.focus();
    188                                 e.returnValue = false;
    189                                 return false;
    190                         }
    191                 }
    192 <?php endif; ?>
    193 //-->
    194 </script>
     146        <?php the_editor($post->post_content); ?>
    195147
    196148<?php echo $form_pingback ?>
  • trunk/wp-admin/edit-form-comment.php

    r3563 r3664  
    3838<fieldset style="clear: both;">
    3939        <legend><?php _e('Comment') ?></legend>
    40 <?php the_quicktags(); ?>
    41 
    42 <?php
    43  $rows = get_settings('default_post_edit_rows');
    44  if (($rows < 3) || ($rows > 100)) {
    45      $rows = 10;
    46  }
    47 ?>
    48 <div><textarea title="true" rows="<?php echo $rows; ?>" cols="40" name="content" tabindex="4" id="content" style="width: 99%"><?php echo user_can_richedit() ? wp_richedit_pre($comment->comment_content) : $comment->comment_content; ?></textarea></div>
     40        <?php the_editor($comment->comment_content, 'content', 'newcomment_author_url'); ?>
    4941</fieldset>
    50 
    51 <script type="text/javascript">
    52 <!--
    53 edCanvas = document.getElementById('content');
    54 <?php if ( user_can_richedit() ) : ?>
    55 // This code is meant to allow tabbing from Author URL to Post (TinyMCE).
    56 if ( tinyMCE.isMSIE )
    57         document.getElementById('newcomment_author_url').onkeydown = function (e)
    58                 {
    59                         e = e ? e : window.event;
    60                         if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
    61                                 var i = tinyMCE.selectedInstance;
    62                                 if(typeof i ==  'undefined')
    63                                         return true;
    64                                 tinyMCE.execCommand("mceStartTyping");
    65                                 this.blur();
    66                                 i.contentWindow.focus();
    67                                 e.returnValue = false;
    68                                 return false;
    69                         }
    70                 }
    71 else
    72         document.getElementById('newcomment_author_url').onkeypress = function (e)
    73                 {
    74                         e = e ? e : window.event;
    75                         if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
    76                                 var i = tinyMCE.selectedInstance;
    77                                 if(typeof i ==  'undefined')
    78                                         return true;
    79                                 tinyMCE.execCommand("mceStartTyping");
    80                                 this.blur();
    81                                 i.contentWindow.focus();
    82                                 e.returnValue = false;
    83                                 return false;
    84                         }
    85                 }
    86 <?php endif; ?>
    87 //-->
    88 </script>
    8942
    9043<p class="submit"><input type="submit" name="editcomment" id="editcomment" value="<?php echo $submitbutton_text ?>" style="font-weight: bold;" tabindex="6" />
  • trunk/wp-admin/edit-page-form.php

    r3660 r3664  
    131131<fieldset id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>">
    132132    <legend><?php _e('Page Content') ?></legend>
    133 <?php
    134  $rows = get_settings('default_post_edit_rows');
    135  if (($rows < 3) || ($rows > 100)) {
    136      $rows = 10;
    137  }
    138 ?>
    139 <?php the_quicktags(); ?>
    140 
    141 <div><textarea title="true" rows="<?php echo $rows; ?>" cols="40" name="content" tabindex="4" id="content"><?php echo user_can_richedit() ? wp_richedit_pre($post->post_content) : $post->post_content; ?></textarea></div>
     133        <?php the_editor($post->post_content); ?>
    142134</fieldset>
    143 
    144 <script type="text/javascript">
    145 <!--
    146 edCanvas = document.getElementById('content');
    147 <?php if ( user_can_richedit() ) : ?>
    148 // This code is meant to allow tabbing from Title to Post (TinyMCE).
    149 if ( tinyMCE.isMSIE )
    150         document.getElementById('title').onkeydown = function (e)
    151                 {
    152                         e = e ? e : window.event;
    153                         if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
    154                                 var i = tinyMCE.selectedInstance;
    155                                 if(typeof i ==  'undefined')
    156                                         return true;
    157                                 tinyMCE.execCommand("mceStartTyping");
    158                                 this.blur();
    159                                 i.contentWindow.focus();
    160                                 e.returnValue = false;
    161                                 return false;
    162                         }
    163                 }
    164 else
    165         document.getElementById('title').onkeypress = function (e)
    166                 {
    167                         e = e ? e : window.event;
    168                         if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
    169                                 var i = tinyMCE.selectedInstance;
    170                                 if(typeof i ==  'undefined')
    171                                         return true;
    172                                 tinyMCE.execCommand("mceStartTyping");
    173                                 this.blur();
    174                                 i.contentWindow.focus();
    175                                 e.returnValue = false;
    176                                 return false;
    177                         }
    178                 }
    179 <?php endif; ?>
    180 //-->
    181 </script>
    182135
    183136<p class="submit">
  • trunk/wp-includes/functions-post.php

    r3663 r3664  
    10291029        generic_ping();
    10301030}
     1031
     1032/**
     1033 * Places two script links in <head>: one to get tinyMCE (big), one to configure and start it (small)
     1034 */
     1035function tinymce_include() {
     1036        $src1 = get_settings('siteurl') . '/wp-includes/js/tinymce/tiny_mce_gzip.php';
     1037        $src2 = get_settings('siteurl') . '/wp-includes/js/tinymce/tiny_mce_config.php';
     1038
     1039        echo "<script type='text/javascript' src='$src1'></script>\n";
     1040        echo "<script type='text/javascript' src='$src2'></script>\n";
     1041}
     1042
     1043/**
     1044 * Places a textarea according to the current user's preferences, filled with $content.
     1045 * Also places a script block that enables tabbing between Title and Content.
     1046 *
     1047 * @param string Editor contents
     1048 * @param string (optional) Previous form field's ID (for tabbing support)
     1049 */
     1050function the_editor($content, $id = 'content', $prev_id = 'title') {
     1051        $rows = get_settings('default_post_edit_rows');
     1052        if (($rows < 3) || ($rows > 100))
     1053                $rows = 12;
     1054
     1055        $rows = "rows='$rows'";
     1056
     1057        the_quicktags();
     1058
     1059        if ( user_can_richedit() )
     1060                add_filter('the_editor_content', 'wp_richedit_pre');
     1061
     1062        $the_editor = apply_filters('the_editor', "<div><textarea class='mceEditor' $rows cols='40' name='$id' tabindex='2' id='$id'>%s</textarea></div>\n");
     1063        $the_editor_content = apply_filters('the_editor_content', $content);
     1064
     1065        printf($the_editor, $the_editor_content);
     1066
     1067        ?>
     1068        <script type="text/javascript">
     1069        //<!--
     1070        edCanvas = document.getElementById('<?php echo $id; ?>');
     1071        <?php if ( user_can_richedit() ) : ?>
     1072        // This code is meant to allow tabbing from Title to Post (TinyMCE).
     1073        if ( tinyMCE.isMSIE )
     1074                document.getElementById('<?php echo $prev_id; ?>').onkeydown = function (e)
     1075                        {
     1076                                e = e ? e : window.event;
     1077                                if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
     1078                                        var i = tinyMCE.selectedInstance;
     1079                                        if(typeof i ==  'undefined')
     1080                                                return true;
     1081                                        tinyMCE.execCommand("mceStartTyping");
     1082                                        this.blur();
     1083                                        i.contentWindow.focus();
     1084                                        e.returnValue = false;
     1085                                        return false;
     1086                                }
     1087                        }
     1088        else
     1089                document.getElementById('<?php echo $prev_id; ?>').onkeypress = function (e)
     1090                        {
     1091                                e = e ? e : window.event;
     1092                                if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
     1093                                        var i = tinyMCE.selectedInstance;
     1094                                        if(typeof i ==  'undefined')
     1095                                                return true;
     1096                                        tinyMCE.execCommand("mceStartTyping");
     1097                                        this.blur();
     1098                                        i.contentWindow.focus();
     1099                                        e.returnValue = false;
     1100                                        return false;
     1101                                }
     1102                        }
     1103        <?php endif; ?>
     1104        //-->
     1105        </script>
     1106        <?php
     1107}
     1108
    10311109?>
  • trunk/wp-includes/js/tinymce/langs/en.js

    r3569 r3664  
    11// UK lang variables
    22
    3 if (navigator.userAgent.indexOf('Mac OS') != -1) {
    4 // Mac OS browsers use Ctrl to hit accesskeys
    5         var metaKey = 'Ctrl';
    6 }
    7 else {
    8         var metaKey = 'Alt';
    9 }
    10 
    11 tinyMCELang['lang_bold_desc'] = 'Bold (' + metaKey + '+b)';
    12 tinyMCELang['lang_italic_desc'] = 'Italic (' + metaKey + '+i)';
    13 tinyMCELang['lang_underline_desc'] = 'Underline';
    14 tinyMCELang['lang_striketrough_desc'] = 'Striketrough (' + metaKey + '-d)';
    15 tinyMCELang['lang_justifyleft_desc'] = 'Align left (' + metaKey + '-f)';
    16 tinyMCELang['lang_justifycenter_desc'] = 'Align center (' + metaKey + '-c)';
    17 tinyMCELang['lang_justifyright_desc'] = 'Align right (' + metaKey + '-r)';
    18 tinyMCELang['lang_justifyfull_desc'] = 'Align full';
    19 tinyMCELang['lang_bullist_desc'] = 'Unordered list (' + metaKey + '-l)';
    20 tinyMCELang['lang_numlist_desc'] = 'Ordered list (' + metaKey + '-o)';
    21 tinyMCELang['lang_outdent_desc'] = 'Outdent (' + metaKey + '-w)';
    22 tinyMCELang['lang_indent_desc'] = 'Indent/Blockquote (' + metaKey + '-q)';
    23 tinyMCELang['lang_undo_desc'] = 'Undo (' + metaKey + '-u)';
    24 tinyMCELang['lang_redo_desc'] = 'Redo (' + metaKey + '-y)';
    25 tinyMCELang['lang_link_desc'] = 'Insert/edit link (' + metaKey + '-a)';
    26 tinyMCELang['lang_unlink_desc'] = 'Unlink (' + metaKey + '-s)';
    27 tinyMCELang['lang_image_desc'] = 'Insert/edit image (' + metaKey + '-m)';
    28 tinyMCELang['lang_cleanup_desc'] = 'Cleanup messy code';
    29 tinyMCELang['lang_focus_alert'] = 'A editor instance must be focused before using this command.';
    30 tinyMCELang['lang_edit_confirm'] = 'Do you want to use the WYSIWYG mode for this textarea?';
    31 tinyMCELang['lang_insert_link_title'] = 'Insert/edit link';
    32 tinyMCELang['lang_insert'] = 'Insert';
    33 tinyMCELang['lang_update'] = 'Update';
    34 tinyMCELang['lang_cancel'] = 'Cancel';
    35 tinyMCELang['lang_insert_link_url'] = 'Link URL';
    36 tinyMCELang['lang_insert_link_target'] = 'Target';
    37 tinyMCELang['lang_insert_link_target_same'] = 'Open link in the same window';
    38 tinyMCELang['lang_insert_link_target_blank'] = 'Open link in a new window';
    39 tinyMCELang['lang_insert_image_title'] = 'Insert/edit image';
    40 tinyMCELang['lang_insert_image_src'] = 'Image URL';
    41 tinyMCELang['lang_insert_image_alt'] = 'Image description';
    42 tinyMCELang['lang_help_desc'] = 'Help';
    43 tinyMCELang['lang_bold_img'] = "bold.gif";
    44 tinyMCELang['lang_italic_img'] = "italic.gif";
    45 tinyMCELang['lang_underline_img'] = "underline.gif";
    46 tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?';
    47 tinyMCELang['lang_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.';
     3tinyMCE.addToLang('',{
     4bold_desc : 'Bold (Ctrl+B)',
     5italic_desc : 'Italic (Ctrl+I)',
     6underline_desc : 'Underline (Ctrl+U)',
     7striketrough_desc : 'Strikethrough',
     8justifyleft_desc : 'Align left',
     9justifycenter_desc : 'Align center',
     10justifyright_desc : 'Align right',
     11justifyfull_desc : 'Align full',
     12bullist_desc : 'Unordered list',
     13numlist_desc : 'Ordered list',
     14outdent_desc : 'Outdent',
     15indent_desc : 'Indent',
     16undo_desc : 'Undo (Ctrl+Z)',
     17redo_desc : 'Redo (Ctrl+Y)',
     18link_desc : 'Insert/edit link',
     19unlink_desc : 'Unlink',
     20image_desc : 'Insert/edit image',
     21cleanup_desc : 'Cleanup messy code',
     22focus_alert : 'A editor instance must be focused before using this command.',
     23edit_confirm : 'Do you want to use the WYSIWYG mode for this textarea?',
     24insert_link_title : 'Insert/edit link',
     25insert : 'Insert',
     26update : 'Update',
     27cancel : 'Cancel',
     28insert_link_url : 'Link URL',
     29insert_link_target : 'Target',
     30insert_link_target_same : 'Open link in the same window',
     31insert_link_target_blank : 'Open link in a new window',
     32insert_image_title : 'Insert/edit image',
     33insert_image_src : 'Image URL',
     34insert_image_alt : 'Image description',
     35help_desc : 'Help',
     36bold_img : "bold.gif",
     37italic_img : "italic.gif",
     38underline_img : "underline.gif",
     39clipboard_msg : 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?',
     40popup_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});
  • trunk/wp-includes/js/tinymce/plugins/autosave/editor_plugin.js

    r2993 r3664  
     1/**
     2 * $RCSfile: editor_plugin_src.js,v $
     3 * $Revision: 1.11 $
     4 * $Date: 2006/03/22 12:21:21 $
     5 *
     6 * @author Moxiecode
     7 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
     8 */
     9
    110/* Import plugin specific language pack */
    2  tinyMCE.importPluginLanguagePack('autosave','en,sv,cs,he,no,hu,de,da,ru,ru_KOI8-R,ru_UTF-8,fi,cy,es,is,pl');function TinyMCE_autosave_getInfo(){return{longname:'Auto save',author:'Moxiecode Systems',authorurl:'http://tinymce.moxiecode.com',infourl:'http://tinymce.moxiecode.com/tinymce/docs/plugin_autosave.html',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion};};function TinyMCE_autosave_beforeUnloadHandler(){var msg=tinyMCE.getLang("lang_autosave_unload_msg");var anyDirty=false;for(var n in tinyMCE.instances){var inst=tinyMCE.instances[n];if(!tinyMCE.isInstance(inst))continue;if(inst.isDirty())return msg;}return;}window.onbeforeunload=TinyMCE_autosave_beforeUnloadHandler;
     11tinyMCE.importPluginLanguagePack('autosave', 'en,tr,sv,cs,he,nb,hu,de,da,ru,ru_KOI8-R,ru_UTF-8,nn,fi,cy,es,is,pl,pt_br');
     12
     13var TinyMCE_AutoSavePlugin = {
     14        getInfo : function() {
     15                return {
     16                        longname : 'Auto save',
     17                        author : 'Moxiecode Systems',
     18                        authorurl : 'http://tinymce.moxiecode.com',
     19                        infourl : 'http://tinymce.moxiecode.com/tinymce/docs/plugin_autosave.html',
     20                        version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
     21                };
     22        },
     23
     24        // Private plugin internal methods
     25
     26        _beforeUnloadHandler : function() {
     27                var n, inst, anyDirty = false, msg = tinyMCE.getLang("lang_autosave_unload_msg");
     28
     29                if (tinyMCE.getParam("fullscreen_is_enabled"))
     30                        return;
     31
     32                for (n in tinyMCE.instances) {
     33                        inst = tinyMCE.instances[n];
     34
     35                        if (!tinyMCE.isInstance(inst))
     36                                continue;
     37
     38                        if (inst.isDirty())
     39                                return msg;
     40                }
     41
     42                return;
     43        }
     44};
     45
     46window.onbeforeunload = TinyMCE_AutoSavePlugin._beforeUnloadHandler;
     47
     48tinyMCE.addPlugin("autosave", TinyMCE_AutoSavePlugin);
  • trunk/wp-includes/js/tinymce/plugins/inlinepopups/css/inlinepopup.css

    r3136 r3664  
     1/* Window classes */
     2
     3.mceWindow {
     4        position: absolute;
     5        left: 0;
     6        top: 0;
     7        border: 1px solid black;
     8        background-color: #D4D0C8;
     9}
     10
     11.mceWindowHead {
     12        background-color: #334F8D;
     13        width: 100%;
     14        height: 18px;
     15        cursor: move;
     16        overflow: hidden;
     17}
     18
     19.mceWindowBody {
     20        clear: both;
     21        background-color: white;
     22}
     23
     24.mceWindowStatusbar {
     25        background-color: #D4D0C8;
     26        height: 12px;
     27        border-top: 1px solid black;
     28}
     29
     30.mceWindowTitle {
     31        float: left;
     32        font-family: "MS Sans Serif";
     33        font-size: 9pt;
     34        font-weight: bold;
     35        line-height: 18px;
     36        color: white;
     37        margin-left: 2px;
     38        overflow: hidden;
     39}
     40
     41.mceWindowHeadTools {
     42        margin-right: 2px;
     43}
     44
     45.mceWindowClose, .mceWindowMinimize, .mceWindowMaximize {
     46        display: block;
     47        float: right;
     48        overflow: hidden;
     49        margin-top: 2px;
     50}
     51
     52.mceWindowClose {
     53        margin-left: 2px;
     54}
     55
     56.mceWindowMinimize {
     57}
     58
     59.mceWindowMaximize {
     60}
     61
     62.mceWindowResize {
     63        display: block;
     64        float: right;
     65        overflow: hidden;
     66        cursor: se-resize;
     67        width: 12px;
     68        height: 12px;
     69}
  • trunk/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js

    r3136 r3664  
     1/**
     2 * $RCSfile: editor_plugin_src.js,v $
     3 * $Revision: 1.8 $
     4 * $Date: 2006/02/06 20:02:38 $
     5 *
     6 * Moxiecode DHTML Windows script.
     7 *
     8 * @author Moxiecode
     9 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
     10 */
     11
     12// Patch openWindow, closeWindow TinyMCE functions
     13
     14var TinyMCE_InlinePopupsPlugin = {
     15        getInfo : function() {
     16                return {
     17                        longname : 'Inline Popups',
     18                        author : 'Moxiecode Systems',
     19                        authorurl : 'http://tinymce.moxiecode.com',
     20                        infourl : 'http://tinymce.moxiecode.com/tinymce/docs/plugin_inlinepopups.html',
     21                        version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
     22                };
     23        }
     24};
     25
     26tinyMCE.addPlugin("inlinepopups", TinyMCE_InlinePopupsPlugin);
     27
     28// Patch openWindow, closeWindow TinyMCE functions
     29
     30TinyMCE_Engine.prototype.orgOpenWindow = TinyMCE_Engine.prototype.openWindow;
     31
     32TinyMCE_Engine.prototype.openWindow = function(template, args) {
     33        // Does the caller support inline
     34        if (args['inline'] != "yes" || tinyMCE.isOpera || tinyMCE.getParam("plugins").indexOf('inlinepopups') == -1) {
     35                mcWindows.selectedWindow = null;
     36                args['mce_inside_iframe'] = false;
     37                this.orgOpenWindow(template, args);
     38                return;
     39        }
     40
     41        var url, resizable, scrollbars;
     42
     43        args['mce_inside_iframe'] = true;
     44        tinyMCE.windowArgs = args;
     45
     46        if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
     47                url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
     48        else
     49                url = template['file'];
     50
     51        if (!(width = parseInt(template['width'])))
     52                width = 320;
     53
     54        if (!(height = parseInt(template['height'])))
     55                height = 200;
     56
     57        resizable = (args && args['resizable']) ? args['resizable'] : "no";
     58        scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
     59
     60        height += 18;
     61
     62        // Replace all args as variables in URL
     63        for (var name in args) {
     64                if (typeof(args[name]) == 'function')
     65                        continue;
     66
     67                url = tinyMCE.replaceVar(url, name, escape(args[name]));
     68        }
     69
     70        var elm = document.getElementById(this.selectedInstance.editorId + '_parent');
     71        var pos = tinyMCE.getAbsPosition(elm);
     72
     73        // Center div in editor area
     74        pos.absLeft += Math.round((elm.firstChild.clientWidth / 2) - (width / 2));
     75        pos.absTop += Math.round((elm.firstChild.clientHeight / 2) - (height / 2));
     76
     77        mcWindows.open(url, mcWindows.idCounter++, "modal=yes,width=" + width+ ",height=" + height + ",resizable=" + resizable + ",scrollbars=" + scrollbars + ",statusbar=" + resizable + ",left=" + pos.absLeft + ",top=" + pos.absTop);
     78};
     79
     80TinyMCE_Engine.prototype.orgCloseWindow = TinyMCE_Engine.prototype.closeWindow;
     81
     82TinyMCE_Engine.prototype.closeWindow = function(win) {
     83        if (mcWindows.selectedWindow != null)
     84                mcWindows.selectedWindow.close();
     85        else
     86                this.orgCloseWindow(win);
     87};
     88
     89TinyMCE_Engine.prototype.setWindowTitle = function(win_ref, title) {
     90        for (var n in mcWindows.windows) {
     91                var win = mcWindows.windows[n];
     92                if (typeof(win) == 'function')
     93                        continue;
     94
     95                if (win_ref.name == win.id + "_iframe")
     96                        window.frames[win.id + "_iframe"].document.getElementById(win.id + '_title').innerHTML = title;
     97        }
     98};
     99
     100// * * * * * TinyMCE_Windows classes below
     101
     102// Windows handler
     103function TinyMCE_Windows() {
     104        this.settings = new Array();
     105        this.windows = new Array();
     106        this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
     107        this.isGecko = navigator.userAgent.indexOf('Gecko') != -1;
     108        this.isSafari = navigator.userAgent.indexOf('Safari') != -1;
     109        this.isMac = navigator.userAgent.indexOf('Mac') != -1;
     110        this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1);
     111        this.action = "none";
     112        this.selectedWindow = null;
     113        this.lastSelectedWindow = null;
     114        this.zindex = 100;
     115        this.mouseDownScreenX = 0;
     116        this.mouseDownScreenY = 0;
     117        this.mouseDownLayerX = 0;
     118        this.mouseDownLayerY = 0;
     119        this.mouseDownWidth = 0;
     120        this.mouseDownHeight = 0;
     121        this.idCounter = 0;
     122};
     123
     124TinyMCE_Windows.prototype.init = function(settings) {
     125        this.settings = settings;
     126
     127        if (this.isMSIE)
     128                this.addEvent(document, "mousemove", mcWindows.eventDispatcher);
     129        else
     130                this.addEvent(window, "mousemove", mcWindows.eventDispatcher);
     131
     132        this.addEvent(document, "mouseup", mcWindows.eventDispatcher);
     133
     134        this.doc = document;
     135};
     136
     137TinyMCE_Windows.prototype.getParam = function(name, default_value) {
     138        var value = null;
     139
     140        value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
     141
     142        // Fix bool values
     143        if (value == "true" || value == "false")
     144                return (value == "true");
     145
     146        return value;
     147};
     148
     149TinyMCE_Windows.prototype.eventDispatcher = function(e) {
     150        e = typeof(e) == "undefined" ? window.event : e;
     151
     152        if (mcWindows.selectedWindow == null)
     153                return;
     154
     155        // Switch focus
     156        if (mcWindows.isGecko && e.type == "mousedown") {
     157                var elm = e.currentTarget;
     158
     159                for (var n in mcWindows.windows) {
     160                        var win = mcWindows.windows[n];
     161
     162                        if (win.headElement == elm || win.resizeElement == elm) {
     163                                win.focus();
     164                                break;
     165                        }
     166                }
     167        }
     168
     169        switch (e.type) {
     170                case "mousemove":
     171                        mcWindows.selectedWindow.onMouseMove(e);
     172                        break;
     173
     174                case "mouseup":
     175                        mcWindows.selectedWindow.onMouseUp(e);
     176                        break;
     177
     178                case "mousedown":
     179                        mcWindows.selectedWindow.onMouseDown(e);
     180                        break;
     181
     182                case "focus":
     183                        mcWindows.selectedWindow.onFocus(e);
     184                        break;
     185        }
     186};
     187
     188TinyMCE_Windows.prototype.addEvent = function(obj, name, handler) {
     189        if (this.isMSIE)
     190                obj.attachEvent("on" + name, handler);
     191        else
     192                obj.addEventListener(name, handler, true);
     193};
     194
     195TinyMCE_Windows.prototype.cancelEvent = function(e) {
     196        if (this.isMSIE) {
     197                e.returnValue = false;
     198                e.cancelBubble = true;
     199        } else
     200                e.preventDefault();
     201};
     202
     203TinyMCE_Windows.prototype.parseFeatures = function(opts) {
     204        // Cleanup the options
     205        opts = opts.toLowerCase();
     206        opts = opts.replace(/;/g, ",");
     207        opts = opts.replace(/[^0-9a-z=,]/g, "");
     208
     209        var optionChunks = opts.split(',');
     210        var options = new Array();
     211
     212        options['left'] = "10";
     213        options['top'] = "10";
     214        options['width'] = "300";
     215        options['height'] = "300";
     216        options['resizable'] = "yes";
     217        options['minimizable'] = "yes";
     218        options['maximizable'] = "yes";
     219        options['close'] = "yes";
     220        options['movable'] = "yes";
     221        options['statusbar'] = "yes";
     222        options['scrollbars'] = "auto";
     223        options['modal'] = "no";
     224
     225        if (opts == "")
     226                return options;
     227
     228        for (var i=0; i<optionChunks.length; i++) {
     229                var parts = optionChunks[i].split('=');
     230
     231                if (parts.length == 2)
     232                        options[parts[0]] = parts[1];
     233        }
     234
     235        options['left'] = parseInt(options['left']);
     236        options['top'] = parseInt(options['top']);
     237        options['width'] = parseInt(options['width']);
     238        options['height'] = parseInt(options['height']);
     239
     240        return options;
     241};
     242
     243TinyMCE_Windows.prototype.open = function(url, name, features) {
     244        this.lastSelectedWindow = this.selectedWindow;
     245
     246        var win = new TinyMCE_Window();
     247        var winDiv, html = "", id;
     248        var imgPath = this.getParam("images_path");
     249
     250        features = this.parseFeatures(features);
     251
     252        // Create div
     253        id = "mcWindow_" + name;
     254        win.deltaHeight = 18;
     255
     256        if (features['statusbar'] == "yes") {
     257                win.deltaHeight += 13;
     258
     259                if (this.isMSIE)
     260                        win.deltaHeight += 1;
     261        }
     262
     263        width = parseInt(features['width']);
     264        height = parseInt(features['height'])-win.deltaHeight;
     265
     266        if (this.isMSIE)
     267                width -= 2;
     268
     269        // Setup first part of window
     270        win.id = id;
     271        win.url = url;
     272        win.name = name;
     273        win.features = features;
     274        this.windows[name] = win;
     275
     276        iframeWidth = width;
     277        iframeHeight = height;
     278
     279        // Create inner content
     280        html += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
     281        html += '<html>';
     282        html += '<head>';
     283        html += '<title>Wrapper iframe</title>';
     284        html += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
     285        html += '<link href="' + this.getParam("css_file") + '" rel="stylesheet" type="text/css" />';
     286        html += '</head>';
     287        html += '<body onload="parent.mcWindows.onLoad(\'' + name + '\');">';
     288
     289        html += '<div id="' + id + '_container" class="mceWindow">';
     290        html += '<div id="' + id + '_head" class="mceWindowHead" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
     291        html += '  <div id="' + id + '_title" class="mceWindowTitle"';
     292        html += '  onselectstart="return false;" unselectable="on" style="-moz-user-select: none !important;"></div>';
     293        html += '    <div class="mceWindowHeadTools">';
     294        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>';
     295//      html += '      <a href="javascript:mcWindows.windows[\'' + name + '\'].maximize();" target="_self" onmousedown="return false;" class="mceWindowMaximize"></a>';
     296//      html += '      <a href="javascript:mcWindows.windows[\'' + name + '\'].minimize();" target="_self" onmousedown="return false;" class="mceWindowMinimize"></a>';
     297        html += '    </div>';
     298        html += '</div><div id="' + id + '_body" class="mceWindowBody" style="width: ' + width + 'px; height: ' + height + 'px;">';
     299        html += '<iframe id="' + id + '_iframe" name="' + id + '_iframe" frameborder="0" width="' + iframeWidth + '" height="' + iframeHeight + '" src="' + url + '" class="mceWindowBodyIframe" scrolling="' + features['scrollbars'] + '"></iframe></div>';
     300
     301        if (features['statusbar'] == "yes") {
     302                html += '<div id="' + id + '_statusbar" class="mceWindowStatusbar" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
     303
     304                if (features['resizable'] == "yes") {
     305                        if (this.isGecko)
     306                                html += '<div id="' + id + '_resize" class="mceWindowResize"><div style="background-image: url(\'' + imgPath + '/window_resize.gif\'); width: 12px; height: 12px;"></div></div>';
     307                        else
     308                                html += '<div id="' + id + '_resize" class="mceWindowResize"><img onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();" border="0" src="' + imgPath + '/window_resize.gif" /></div>';
     309                }
     310
     311                html += '</div>';
     312        }
     313
     314        html += '</div>';
     315
     316        html += '</body>';
     317        html += '</html>';
     318
     319        // Create iframe
     320        this.createFloatingIFrame(id, features['left'], features['top'], features['width'], features['height'], html);
     321};
     322
     323// Blocks the document events by placing a image over the whole document
     324TinyMCE_Windows.prototype.setDocumentLock = function(state) {
     325        if (state) {
     326                var elm = document.getElementById('mcWindowEventBlocker');
     327                if (elm == null) {
     328                        elm = document.createElement("div");
     329
     330                        elm.id = "mcWindowEventBlocker";
     331                        elm.style.position = "absolute";
     332                        elm.style.left = "0";
     333                        elm.style.top = "0";
     334
     335                        document.body.appendChild(elm);
     336                }
     337
     338                elm.style.display = "none";
     339
     340                var imgPath = this.getParam("images_path");
     341                var width = document.body.clientWidth;
     342                var height = document.body.clientHeight;
     343
     344                elm.style.width = width;
     345                elm.style.height = height;
     346                elm.innerHTML = '<img src="' + imgPath + '/spacer.gif" width="' + width + '" height="' + height + '" />';
     347
     348                elm.style.zIndex = mcWindows.zindex-1;
     349                elm.style.display = "block";
     350        } else {
     351                var elm = document.getElementById('mcWindowEventBlocker');
     352
     353                if (mcWindows.windows.length == 0)
     354                        elm.parentNode.removeChild(elm);
     355                else
     356                        elm.style.zIndex = mcWindows.zindex-1;
     357        }
     358};
     359
     360// Gets called when wrapper iframe is initialized
     361TinyMCE_Windows.prototype.onLoad = function(name) {
     362        var win = mcWindows.windows[name];
     363        var id = "mcWindow_" + name;
     364        var wrapperIframe = window.frames[id + "_iframe"].frames[0];
     365        var wrapperDoc = window.frames[id + "_iframe"].document;
     366        var doc = window.frames[id + "_iframe"].document;
     367        var winDiv = document.getElementById("mcWindow_" + name + "_div");
     368        var realIframe = window.frames[id + "_iframe"].frames[0];
     369
     370        // Set window data
     371        win.id = "mcWindow_" + name;
     372        win.winElement = winDiv;
     373        win.bodyElement = doc.getElementById(id + '_body');
     374        win.iframeElement = doc.getElementById(id + '_iframe');
     375        win.headElement = doc.getElementById(id + '_head');
     376        win.titleElement = doc.getElementById(id + '_title');
     377        win.resizeElement = doc.getElementById(id + '_resize');
     378        win.containerElement = doc.getElementById(id + '_container');
     379        win.left = win.features['left'];
     380        win.top = win.features['top'];
     381        win.frame = window.frames[id + '_iframe'].frames[0];
     382        win.wrapperFrame = window.frames[id + '_iframe'];
     383        win.wrapperIFrameElement = document.getElementById(id + "_iframe");
     384
     385        // Add event handlers
     386        mcWindows.addEvent(win.headElement, "mousedown", mcWindows.eventDispatcher);
     387
     388        if (win.resizeElement != null)
     389                mcWindows.addEvent(win.resizeElement, "mousedown", mcWindows.eventDispatcher);
     390
     391        if (mcWindows.isMSIE) {
     392                mcWindows.addEvent(realIframe.document, "mousemove", mcWindows.eventDispatcher);
     393                mcWindows.addEvent(realIframe.document, "mouseup", mcWindows.eventDispatcher);
     394        } else {
     395                mcWindows.addEvent(realIframe, "mousemove", mcWindows.eventDispatcher);
     396                mcWindows.addEvent(realIframe, "mouseup", mcWindows.eventDispatcher);
     397                mcWindows.addEvent(realIframe, "focus", mcWindows.eventDispatcher);
     398        }
     399
     400        for (var i=0; i<window.frames.length; i++) {
     401                if (!window.frames[i]._hasMouseHandlers) {
     402                        if (mcWindows.isMSIE) {
     403                                mcWindows.addEvent(window.frames[i].document, "mousemove", mcWindows.eventDispatcher);
     404                                mcWindows.addEvent(window.frames[i].document, "mouseup", mcWindows.eventDispatcher);
     405                        } else {
     406                                mcWindows.addEvent(window.frames[i], "mousemove", mcWindows.eventDispatcher);
     407                                mcWindows.addEvent(window.frames[i], "mouseup", mcWindows.eventDispatcher);
     408                        }
     409
     410                        window.frames[i]._hasMouseHandlers = true;
     411                }
     412        }
     413
     414        if (mcWindows.isMSIE) {
     415                mcWindows.addEvent(win.frame.document, "mousemove", mcWindows.eventDispatcher);
     416                mcWindows.addEvent(win.frame.document, "mouseup", mcWindows.eventDispatcher);
     417        } else {
     418                mcWindows.addEvent(win.frame, "mousemove", mcWindows.eventDispatcher);
     419                mcWindows.addEvent(win.frame, "mouseup", mcWindows.eventDispatcher);
     420                mcWindows.addEvent(win.frame, "focus", mcWindows.eventDispatcher);
     421        }
     422
     423        // Dispatch open window event
     424        var func = this.getParam("on_open_window", "");
     425        if (func != "")
     426                eval(func + "(win);");
     427
     428        win.focus();
     429
     430        if (win.features['modal'] == "yes")
     431                mcWindows.setDocumentLock(true);
     432};
     433
     434TinyMCE_Windows.prototype.createFloatingIFrame = function(id_prefix, left, top, width, height, html) {
     435        var iframe = document.createElement("iframe");
     436        var div = document.createElement("div");
     437
     438        width = parseInt(width);
     439        height = parseInt(height)+1;
     440
     441        // Create wrapper div
     442        div.setAttribute("id", id_prefix + "_div");
     443        div.setAttribute("width", width);
     444        div.setAttribute("height", (height));
     445        div.style.position = "absolute";
     446        div.style.left = left + "px";
     447        div.style.top = top + "px";
     448        div.style.width = width + "px";
     449        div.style.height = (height) + "px";
     450        div.style.backgroundColor = "white";
     451        div.style.display = "none";
     452
     453        if (this.isGecko) {
     454                iframeWidth = width + 2;
     455                iframeHeight = height + 2;
     456        } else {
     457                iframeWidth = width;
     458                iframeHeight = height + 1;
     459        }
     460
     461        // Create iframe
     462        iframe.setAttribute("id", id_prefix + "_iframe");
     463        iframe.setAttribute("name", id_prefix + "_iframe");
     464        iframe.setAttribute("border", "0");
     465        iframe.setAttribute("frameBorder", "0");
     466        iframe.setAttribute("marginWidth", "0");
     467        iframe.setAttribute("marginHeight", "0");
     468        iframe.setAttribute("leftMargin", "0");
     469        iframe.setAttribute("topMargin", "0");
     470        iframe.setAttribute("width", iframeWidth);
     471        iframe.setAttribute("height", iframeHeight);
     472//      iframe.setAttribute("src", "../jscripts/tiny_mce/blank.htm");
     473        // iframe.setAttribute("allowtransparency", "false");
     474        iframe.setAttribute("scrolling", "no");
     475        iframe.style.width = iframeWidth + "px";
     476        iframe.style.height = iframeHeight + "px";
     477        iframe.style.backgroundColor = "white";
     478        div.appendChild(iframe);
     479
     480        document.body.appendChild(div);
     481
     482        // Fixed MSIE 5.0 issue
     483        div.innerHTML = div.innerHTML;
     484
     485        if (this.isSafari) {
     486                // Give Safari some time to setup
     487                window.setTimeout(function() {
     488                        doc = window.frames[id_prefix + '_iframe'].document;
     489                        doc.open();
     490                        doc.write(html);
     491                        doc.close();
     492                }, 10);
     493        } else {
     494                doc = window.frames[id_prefix + '_iframe'].window.document;
     495                doc.open();
     496                doc.write(html);
     497                doc.close();
     498        }
     499
     500        div.style.display = "block";
     501
     502        return div;
     503};
     504
     505// Window instance
     506function TinyMCE_Window() {
     507};
     508
     509TinyMCE_Window.prototype.focus = function() {
     510        if (this != mcWindows.selectedWindow) {
     511                this.winElement.style.zIndex = ++mcWindows.zindex;
     512                mcWindows.lastSelectedWindow = mcWindows.selectedWindow;
     513                mcWindows.selectedWindow = this;
     514        }
     515};
     516
     517TinyMCE_Window.prototype.minimize = function() {
     518};
     519
     520TinyMCE_Window.prototype.maximize = function() {
     521       
     522};
     523
     524TinyMCE_Window.prototype.startResize = function() {
     525        mcWindows.action = "resize";
     526};
     527
     528TinyMCE_Window.prototype.startMove = function(e) {
     529        mcWindows.action = "move";
     530};
     531
     532TinyMCE_Window.prototype.close = function() {
     533        if (this.frame && this.frame['tinyMCEPopup'])
     534                this.frame['tinyMCEPopup'].restoreSelection();
     535
     536        if (mcWindows.lastSelectedWindow != null)
     537                mcWindows.lastSelectedWindow.focus();
     538
     539        var mcWindowsNew = new Array();
     540        for (var n in mcWindows.windows) {
     541                var win = mcWindows.windows[n];
     542                if (typeof(win) == 'function')
     543                        continue;
     544
     545                if (win.name != this.name)
     546                        mcWindowsNew[n] = win;
     547        }
     548
     549        mcWindows.windows = mcWindowsNew;
     550
     551//      alert(mcWindows.doc.getElementById(this.id + "_iframe"));
     552
     553        var e = mcWindows.doc.getElementById(this.id + "_iframe");
     554        e.parentNode.removeChild(e);
     555
     556        var e = mcWindows.doc.getElementById(this.id + "_div");
     557        e.parentNode.removeChild(e);
     558
     559        mcWindows.setDocumentLock(false);
     560};
     561
     562TinyMCE_Window.prototype.onMouseMove = function(e) {
     563        var scrollX = 0;//this.doc.body.scrollLeft;
     564        var scrollY = 0;//this.doc.body.scrollTop;
     565
     566        // Calculate real X, Y
     567        var dx = e.screenX - mcWindows.mouseDownScreenX;
     568        var dy = e.screenY - mcWindows.mouseDownScreenY;
     569
     570        switch (mcWindows.action) {
     571                case "resize":
     572                        width = mcWindows.mouseDownWidth + (e.screenX - mcWindows.mouseDownScreenX);
     573                        height = mcWindows.mouseDownHeight + (e.screenY - mcWindows.mouseDownScreenY);
     574
     575                        width = width < 100 ? 100 : width;
     576                        height = height < 100 ? 100 : height;
     577
     578                        this.wrapperIFrameElement.style.width = width+2;
     579                        this.wrapperIFrameElement.style.height = height+2;
     580                        this.wrapperIFrameElement.width = width+2;
     581                        this.wrapperIFrameElement.height = height+2;
     582                        this.winElement.style.width = width;
     583                        this.winElement.style.height = height;
     584
     585                        height = height - this.deltaHeight;
     586
     587                        this.containerElement.style.width = width;
     588
     589                        this.iframeElement.style.width = width;
     590                        this.iframeElement.style.height = height;
     591                        this.bodyElement.style.width = width;
     592                        this.bodyElement.style.height = height;
     593                        this.headElement.style.width = width;
     594                        //this.statusElement.style.width = width;
     595
     596                        mcWindows.cancelEvent(e);
     597                        break;
     598
     599                case "move":
     600                        this.left = mcWindows.mouseDownLayerX + (e.screenX - mcWindows.mouseDownScreenX);
     601                        this.top = mcWindows.mouseDownLayerY + (e.screenY - mcWindows.mouseDownScreenY);
     602                        this.winElement.style.left = this.left + "px";
     603                        this.winElement.style.top = this.top + "px";
     604
     605                        mcWindows.cancelEvent(e);
     606                        break;
     607        }
     608};
     609
     610function debug(msg) {
     611        document.getElementById('debug').value += msg + "\n";
     612}
     613
     614TinyMCE_Window.prototype.onMouseUp = function(e) {
     615        mcWindows.action = "none";
     616};
     617
     618TinyMCE_Window.prototype.onFocus = function(e) {
     619        // Gecko only handler
     620        var winRef = e.currentTarget;
     621
     622        for (var n in mcWindows.windows) {
     623                var win = mcWindows.windows[n];
     624                if (typeof(win) == 'function')
     625                        continue;
     626
     627                if (winRef.name == win.id + "_iframe") {
     628                        win.focus();
     629                        return;
     630                }
     631        }
     632};
     633
     634TinyMCE_Window.prototype.onMouseDown = function(e) {
     635        var elm = mcWindows.isMSIE ? this.wrapperFrame.event.srcElement : e.target;
     636
     637        var scrollX = 0;//this.doc.body.scrollLeft;
     638        var scrollY = 0;//this.doc.body.scrollTop;
     639
     640        mcWindows.mouseDownScreenX = e.screenX;
     641        mcWindows.mouseDownScreenY = e.screenY;
     642        mcWindows.mouseDownLayerX = this.left;
     643        mcWindows.mouseDownLayerY = this.top;
     644        mcWindows.mouseDownWidth = parseInt(this.winElement.style.width);
     645        mcWindows.mouseDownHeight = parseInt(this.winElement.style.height);
     646
     647        if (this.resizeElement != null && elm == this.resizeElement.firstChild)
     648                this.startResize(e);
     649        else
     650                this.startMove(e);
     651
     652        mcWindows.cancelEvent(e);
     653};
     654
     655// Global instance
     656var mcWindows = new TinyMCE_Windows();
     657
     658// Initialize windows
     659mcWindows.init({
     660        images_path : tinyMCE.baseURL + "/plugins/inlinepopups/images",
     661        css_file : tinyMCE.baseURL + "/plugins/inlinepopups/css/inlinepopup.css"
     662});
  • trunk/wp-includes/js/tinymce/plugins/inlinepopups/jscripts/mcwindows.js

    r3136 r3664  
     1/**
     2 * $RCSfile: mcwindows.js,v $
     3 * $Revision: 1.2 $
     4 * $Date: 2005/10/18 13:59:43 $
     5 *
     6 * Moxiecode DHTML Windows script.
     7 *
     8 * @author Moxiecode
     9 * @copyright Copyright © 2004, Moxiecode Systems AB, All rights reserved.
     10 */
     11
     12// Windows handler
     13function MCWindows() {
     14        this.settings = new Array();
     15        this.windows = new Array();
     16        this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
     17        this.isGecko = navigator.userAgent.indexOf('Gecko') != -1;
     18        this.isSafari = navigator.userAgent.indexOf('Safari') != -1;
     19        this.isMac = navigator.userAgent.indexOf('Mac') != -1;
     20        this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1);
     21        this.action = "none";
     22        this.selectedWindow = null;
     23        this.zindex = 100;
     24        this.mouseDownScreenX = 0;
     25        this.mouseDownScreenY = 0;
     26        this.mouseDownLayerX = 0;
     27        this.mouseDownLayerY = 0;
     28        this.mouseDownWidth = 0;
     29        this.mouseDownHeight = 0;
     30};
     31
     32MCWindows.prototype.init = function(settings) {
     33        this.settings = settings;
     34
     35        if (this.isMSIE)
     36                this.addEvent(document, "mousemove", mcWindows.eventDispatcher);
     37        else
     38                this.addEvent(window, "mousemove", mcWindows.eventDispatcher);
     39
     40        this.addEvent(document, "mouseup", mcWindows.eventDispatcher);
     41};
     42
     43MCWindows.prototype.getParam = function(name, default_value) {
     44        var value = null;
     45
     46        value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
     47
     48        // Fix bool values
     49        if (value == "true" || value == "false")
     50                return (value == "true");
     51
     52        return value;
     53};
     54
     55MCWindows.prototype.eventDispatcher = function(e) {
     56        e = typeof(e) == "undefined" ? window.event : e;
     57
     58        if (mcWindows.selectedWindow == null)
     59                return;
     60
     61        // Switch focus
     62        if (mcWindows.isGecko && e.type == "mousedown") {
     63                var elm = e.currentTarget;
     64
     65                for (var n in mcWindows.windows) {
     66                        var win = mcWindows.windows[n];
     67                        if (typeof(win) == 'function')
     68                                continue;
     69
     70                        if (win.headElement == elm || win.resizeElement == elm) {
     71                                win.focus();
     72                                break;
     73                        }
     74                }
     75        }
     76
     77        switch (e.type) {
     78                case "mousemove":
     79                        mcWindows.selectedWindow.onMouseMove(e);
     80                        break;
     81
     82                case "mouseup":
     83                        mcWindows.selectedWindow.onMouseUp(e);
     84                        break;
     85
     86                case "mousedown":
     87                        mcWindows.selectedWindow.onMouseDown(e);
     88                        break;
     89
     90                case "focus":
     91                        mcWindows.selectedWindow.onFocus(e);
     92                        break;
     93        }
     94}
     95
     96MCWindows.prototype.addEvent = function(obj, name, handler) {
     97        if (this.isMSIE)
     98                obj.attachEvent("on" + name, handler);
     99        else
     100                obj.addEventListener(name, handler, true);
     101};
     102
     103MCWindows.prototype.cancelEvent = function(e) {
     104        if (this.isMSIE) {
     105                e.returnValue = false;
     106                e.cancelBubble = true;
     107        } else
     108                e.preventDefault();
     109};
     110
     111MCWindows.prototype.parseFeatures = function(opts) {
     112        // Cleanup the options
     113        opts = opts.toLowerCase();
     114        opts = opts.replace(/;/g, ",");
     115        opts = opts.replace(/[^0-9a-z=,]/g, "");
     116
     117        var optionChunks = opts.split(',');
     118        var options = new Array();
     119
     120        options['left'] = 10;
     121        options['top'] = 10;
     122        options['width'] = 300;
     123        options['height'] = 300;
     124        options['resizable'] = true;
     125        options['minimizable'] = true;
     126        options['maximizable'] = true;
     127        options['close'] = true;
     128        options['movable'] = true;
     129
     130        if (opts == "")
     131                return options;
     132
     133        for (var i=0; i<optionChunks.length; i++) {
     134                var parts = optionChunks[i].split('=');
     135
     136                if (parts.length == 2)
     137                        options[parts[0]] = parts[1];
     138        }
     139
     140        return options;
     141};
     142
     143MCWindows.prototype.open = function(url, name, features) {
     144        var win = new MCWindow();
     145        var winDiv, html = "", id;
     146
     147        features = this.parseFeatures(features);
     148
     149        // Create div
     150        id = "mcWindow_" + name;
     151
     152        width = parseInt(features['width']);
     153        height = parseInt(features['height'])-12-19;
     154
     155        if (this.isMSIE)
     156                width -= 2;
     157
     158        // Setup first part of window
     159        win.id = id;
     160        win.url = url;
     161        win.name = name;
     162        win.features = features;
     163        this.windows[name] = win;
     164
     165        iframeWidth = width;
     166        iframeHeight = height;
     167
     168        // Create inner content
     169        html += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
     170        html += '<html>';
     171        html += '<head>';
     172        html += '<title>Wrapper iframe</title>';
     173        html += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
     174        html += '<link href="../jscripts/tiny_mce/themes/advanced/css/editor_ui.css" rel="stylesheet" type="text/css" />';
     175        html += '</head>';
     176        html += '<body onload="parent.mcWindows.onLoad(\'' + name + '\');">';
     177
     178        html += '<div id="' + id + '_container" class="mceWindow">';
     179        html += '<div id="' + id + '_head" class="mceWindowHead" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
     180        html += '  <div id="' + id + '_title" class="mceWindowTitle"';
     181        html += '  onselectstart="return false;" unselectable="on" style="-moz-user-select: none !important;">No name window</div>';
     182        html += '    <div class="mceWindowHeadTools">';
     183        html += '      <a href="javascript:parent.mcWindows.windows[\'' + name + '\'].close();" onmousedown="return false;" class="mceWindowClose"><img border="0" src="../jscripts/tiny_mce/themes/advanced/images/window_close.gif" /></a>';
     184//      html += '      <a href="javascript:mcWindows.windows[\'' + name + '\'].maximize();" onmousedown="return false;" class="mceWindowMaximize"></a>';
     185//      html += '      <a href="javascript:mcWindows.windows[\'' + name + '\'].minimize();" onmousedown="return false;" class="mceWindowMinimize"></a>';
     186        html += '    </div>';
     187        html += '</div><div id="' + id + '_body" class="mceWindowBody" style="width: ' + width + 'px; height: ' + height + 'px;">';
     188        html += '<iframe id="' + id + '_iframe" name="' + id + '_iframe" onfocus="parent.mcWindows.windows[\'' + name + '\'].focus();" frameborder="0" width="' + iframeWidth + '" height="' + iframeHeight + '" src="' + url + '" class="mceWindowBodyIframe"></iframe></div>';
     189        html += '<div id="' + id + '_statusbar" class="mceWindowStatusbar" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
     190        html += '<div id="' + id + '_resize" class="mceWindowResize"><img onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();" border="0" src="../jscripts/tiny_mce/themes/advanced/images/window_resize.gif" /></div>';
     191        html += '</div>';
     192        html += '</div>';
     193
     194        html += '</body>';
     195        html += '</html>';
     196
     197        // Create iframe
     198        this.createFloatingIFrame(id, features['left'], features['top'], features['width'], features['height'], html);
     199};
     200
     201// Gets called when wrapper iframe is initialized
     202MCWindows.prototype.onLoad = function(name) {
     203        var win = mcWindows.windows[name];
     204        var id = "mcWindow_" + name;
     205        var wrapperIframe = window.frames[id + "_iframe"].frames[0];
     206        var wrapperDoc = window.frames[id + "_iframe"].document;
     207        var doc = window.frames[id + "_iframe"].document;
     208        var winDiv = document.getElementById("mcWindow_" + name + "_div");
     209        var realIframe = window.frames[id + "_iframe"].frames[0];
     210
     211        // Set window data
     212        win.id = "mcWindow_" + name + "_iframe";
     213        win.winElement = winDiv;
     214        win.bodyElement = doc.getElementById(id + '_body');
     215        win.iframeElement = doc.getElementById(id + '_iframe');
     216        win.headElement = doc.getElementById(id + '_head');
     217        win.titleElement = doc.getElementById(id + '_title');
     218        win.resizeElement = doc.getElementById(id + '_resize');
     219        win.containerElement = doc.getElementById(id + '_container');
     220        win.left = win.features['left'];
     221        win.top = win.features['top'];
     222        win.frame = window.frames[id + '_iframe'].frames[0];
     223        win.wrapperFrame = window.frames[id + '_iframe'];
     224        win.wrapperIFrameElement = document.getElementById(id + "_iframe");
     225
     226        // Add event handlers
     227        mcWindows.addEvent(win.headElement, "mousedown", mcWindows.eventDispatcher);
     228        mcWindows.addEvent(win.resizeElement, "mousedown", mcWindows.eventDispatcher);
     229
     230        if (mcWindows.isMSIE) {
     231                mcWindows.addEvent(realIframe.document, "mousemove", mcWindows.eventDispatcher);
     232                mcWindows.addEvent(realIframe.document, "mouseup", mcWindows.eventDispatcher);
     233        } else {
     234                mcWindows.addEvent(realIframe, "mousemove", mcWindows.eventDispatcher);
     235                mcWindows.addEvent(realIframe, "mouseup", mcWindows.eventDispatcher);
     236                mcWindows.addEvent(realIframe, "focus", mcWindows.eventDispatcher);
     237        }
     238
     239        for (var i=0; i<window.frames.length; i++) {
     240                if (!window.frames[i]._hasMouseHandlers) {
     241                        if (mcWindows.isMSIE) {
     242                                mcWindows.addEvent(window.frames[i].document, "mousemove", mcWindows.eventDispatcher);
     243                                mcWindows.addEvent(window.frames[i].document, "mouseup", mcWindows.eventDispatcher);
     244                        } else {
     245                                mcWindows.addEvent(window.frames[i], "mousemove", mcWindows.eventDispatcher);
     246                                mcWindows.addEvent(window.frames[i], "mouseup", mcWindows.eventDispatcher);
     247                        }
     248
     249                        window.frames[i]._hasMouseHandlers = true;
     250                }
     251        }
     252
     253        if (mcWindows.isMSIE) {
     254                mcWindows.addEvent(win.frame.document, "mousemove", mcWindows.eventDispatcher);
     255                mcWindows.addEvent(win.frame.document, "mouseup", mcWindows.eventDispatcher);
     256        } else {
     257                mcWindows.addEvent(win.frame, "mousemove", mcWindows.eventDispatcher);
     258                mcWindows.addEvent(win.frame, "mouseup", mcWindows.eventDispatcher);
     259                mcWindows.addEvent(win.frame, "focus", mcWindows.eventDispatcher);
     260        }
     261
     262        this.selectedWindow = win;
     263};
     264
     265MCWindows.prototype.createFloatingIFrame = function(id_prefix, left, top, width, height, html) {
     266        var iframe = document.createElement("iframe");
     267        var div = document.createElement("div");
     268
     269        width = parseInt(width);
     270        height = parseInt(height)+1;
     271
     272        // Create wrapper div
     273        div.setAttribute("id", id_prefix + "_div");
     274        div.setAttribute("width", width);
     275        div.setAttribute("height", (height));
     276        div.style.position = "absolute";
     277        div.style.left = left + "px";
     278        div.style.top = top + "px";
     279        div.style.width = width + "px";
     280        div.style.height = (height) + "px";
     281        div.style.backgroundColor = "white";
     282        div.style.display = "none";
     283
     284        if (this.isGecko) {
     285                iframeWidth = width + 2;
     286                iframeHeight = height + 2;
     287        } else {
     288                iframeWidth = width;
     289                iframeHeight = height + 1;
     290        }
     291
     292        // Create iframe
     293        iframe.setAttribute("id", id_prefix + "_iframe");
     294        iframe.setAttribute("name", id_prefix + "_iframe");
     295        iframe.setAttribute("border", "0");
     296        iframe.setAttribute("frameBorder", "0");
     297        iframe.setAttribute("marginWidth", "0");
     298        iframe.setAttribute("marginHeight", "0");
     299        iframe.setAttribute("leftMargin", "0");
     300        iframe.setAttribute("topMargin", "0");
     301        iframe.setAttribute("width", iframeWidth);
     302        iframe.setAttribute("height", iframeHeight);
     303//      iframe.setAttribute("src", "../jscripts/tiny_mce/blank.htm");
     304        // iframe.setAttribute("allowtransparency", "false");
     305        iframe.setAttribute("scrolling", "no");
     306        iframe.style.width = iframeWidth + "px";
     307        iframe.style.height = iframeHeight + "px";
     308        iframe.style.backgroundColor = "white";
     309        div.appendChild(iframe);
     310
     311        document.body.appendChild(div);
     312
     313        // Fixed MSIE 5.0 issue
     314        div.innerHTML = div.innerHTML;
     315
     316        if (this.isSafari) {
     317                // Give Safari some time to setup
     318                window.setTimeout(function() {
     319                        doc = window.frames[id_prefix + '_iframe'].document;
     320                        doc.open();
     321                        doc.write(html);
     322                        doc.close();
     323                }, 10);
     324        } else {
     325                doc = window.frames[id_prefix + '_iframe'].window.document
     326                doc.open();
     327                doc.write(html);
     328                doc.close();
     329        }
     330
     331        div.style.display = "block";
     332
     333        return div;
     334};
     335
     336// Window instance
     337function MCWindow() {
     338};
     339
     340MCWindow.prototype.focus = function() {
     341        this.winElement.style.zIndex = mcWindows.zindex++;
     342        mcWindows.selectedWindow = this;
     343};
     344
     345MCWindow.prototype.minimize = function() {
     346};
     347
     348MCWindow.prototype.maximize = function() {
     349       
     350};
     351
     352MCWindow.prototype.startResize = function() {
     353        mcWindows.action = "resize";
     354};
     355
     356MCWindow.prototype.startMove = function(e) {
     357        mcWindows.action = "move";
     358};
     359
     360MCWindow.prototype.close = function() {
     361        document.body.removeChild(this.winElement);
     362        mcWindows.windows[this.name] = null;
     363};
     364
     365MCWindow.prototype.onMouseMove = function(e) {
     366        var scrollX = 0;//this.doc.body.scrollLeft;
     367        var scrollY = 0;//this.doc.body.scrollTop;
     368
     369        // Calculate real X, Y
     370        var dx = e.screenX - mcWindows.mouseDownScreenX;
     371        var dy = e.screenY - mcWindows.mouseDownScreenY;
     372
     373        switch (mcWindows.action) {
     374                case "resize":
     375                        width = mcWindows.mouseDownWidth + (e.screenX - mcWindows.mouseDownScreenX);
     376                        height = mcWindows.mouseDownHeight + (e.screenY - mcWindows.mouseDownScreenY);
     377
     378                        width = width < 100 ? 100 : width;
     379                        height = height < 100 ? 100 : height;
     380
     381                        this.wrapperIFrameElement.style.width = width+2;
     382                        this.wrapperIFrameElement.style.height = height+2;
     383                        this.wrapperIFrameElement.width = width+2;
     384                        this.wrapperIFrameElement.height = height+2;
     385                        this.winElement.style.width = width;
     386                        this.winElement.style.height = height;
     387
     388                        height = height-12-19;
     389
     390                        this.containerElement.style.width = width;
     391
     392                        this.iframeElement.style.width = width;
     393                        this.iframeElement.style.height = height;
     394                        this.bodyElement.style.width = width;
     395                        this.bodyElement.style.height = height;
     396                        this.headElement.style.width = width;
     397                        //this.statusElement.style.width = width;
     398
     399                        mcWindows.cancelEvent(e);
     400                        break;
     401
     402                case "move":
     403                        this.left = mcWindows.mouseDownLayerX + (e.screenX - mcWindows.mouseDownScreenX);
     404                        this.top = mcWindows.mouseDownLayerY + (e.screenY - mcWindows.mouseDownScreenY);
     405                        this.winElement.style.left = this.left + "px";
     406                        this.winElement.style.top = this.top + "px";
     407
     408                        mcWindows.cancelEvent(e);
     409                        break;
     410        }
     411};
     412
     413MCWindow.prototype.onMouseUp = function(e) {
     414        mcWindows.action = "none";
     415};
     416
     417MCWindow.prototype.onFocus = function(e) {
     418        // Gecko only handler
     419        var winRef = e.currentTarget;
     420
     421        for (var n in mcWindows.windows) {
     422                var win = mcWindows.windows[n];
     423                if (typeof(win) == 'function')
     424                        continue;
     425
     426                if (winRef.name == win.id) {
     427                        win.focus();
     428                        return;
     429                }
     430        }
     431};
     432
     433MCWindow.prototype.onMouseDown = function(e) {
     434        var elm = mcWindows.isMSIE ? this.wrapperFrame.event.srcElement : e.target;
     435
     436        var scrollX = 0;//this.doc.body.scrollLeft;
     437        var scrollY = 0;//this.doc.body.scrollTop;
     438
     439        mcWindows.mouseDownScreenX = e.screenX;
     440        mcWindows.mouseDownScreenY = e.screenY;
     441        mcWindows.mouseDownLayerX = this.left;
     442        mcWindows.mouseDownLayerY = this.top;
     443        mcWindows.mouseDownWidth = parseInt(this.winElement.style.width);
     444        mcWindows.mouseDownHeight = parseInt(this.winElement.style.height);
     445
     446        if (elm == this.resizeElement.firstChild)
     447                this.startResize(e);
     448        else
     449                this.startMove(e);
     450
     451        mcWindows.cancelEvent(e);
     452};
     453
     454// Global instance
     455var mcWindows = new MCWindows();
  • trunk/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js

    r3517 r3664  
    11/* Import plugin specific language pack */
    2 tinyMCE.importPluginLanguagePack('wordpress', '');
    3 
    4 function TinyMCE_wordpress_initInstance(inst) {
    5         if (!tinyMCE.settings['wordpress_skip_plugin_css'])
    6                 tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/wordpress/wordpress.css");
    7 }
    8 
    9 function TinyMCE_wordpress_getControlHTML(control_name) {
    10         switch (control_name) {
    11                 case "wordpress":
    12                         var titleMore = tinyMCE.getLang('lang_wordpress_more_button');
    13                         var titlePage = tinyMCE.getLang('lang_wordpress_page_button');
    14                         var titleHelp = tinyMCE.getLang('lang_wordpress_help_button');
    15                         var buttons = '<a href="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpressmore\')" target="_self" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpressmore\');return false;"><img id="{$editor_id}_wordpress_more" src="{$pluginurl}/images/more.gif" title="'+titleMore+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';
    16                         // Add this to the buttons var to put the Page button into the toolbar.
    17                         // '<a href="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpresspage\')" target="_self" onclick="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpresspage\');return false;"><img id="{$editor_id}_wordpress_page" src="{$pluginurl}/images/page.gif" title="'+titlePage+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';
    18                         return buttons;
    19         }
    20 
    21         return '';
    22 }
    23 
    24 function TinyMCE_wordpress_parseAttributes(attribute_string) {
    25         var attributeName = "";
    26         var attributeValue = "";
    27         var withInName;
    28         var withInValue;
    29         var attributes = new Array();
    30         var whiteSpaceRegExp = new RegExp('^[ \n\r\t]+', 'g');
    31         var titleText = tinyMCE.getLang('lang_wordpress_more');
    32         var titleTextPage = tinyMCE.getLang('lang_wordpress_page');
    33 
    34         if (attribute_string == null || attribute_string.length < 2)
    35                 return null;
    36 
    37         withInName = withInValue = false;
    38 
    39         for (var i=0; i<attribute_string.length; i++) {
    40                 var chr = attribute_string.charAt(i);
    41 
    42                 if ((chr == '"' || chr == "'") && !withInValue)
    43                         withInValue = true;
    44                 else if ((chr == '"' || chr == "'") && withInValue) {
    45                         withInValue = false;
    46 
    47                         var pos = attributeName.lastIndexOf(' ');
    48                         if (pos != -1)
    49                                 attributeName = attributeName.substring(pos+1);
    50 
    51                         attributes[attributeName.toLowerCase()] = attributeValue.substring(1).toLowerCase();
    52 
    53                         attributeName = "";
    54                         attributeValue = "";
    55                 } else if (!whiteSpaceRegExp.test(chr) && !withInName && !withInValue)
    56                         withInName = true;
    57 
    58                 if (chr == '=' && withInName)
    59                         withInName = false;
    60 
    61                 if (withInName)
    62                         attributeName += chr;
    63 
    64                 if (withInValue)
    65                         attributeValue += chr;
    66         }
    67 
    68         return attributes;
    69 }
    70 
    71 function TinyMCE_wordpress_execCommand(editor_id, element, command, user_interface, value) {
    72         var inst = tinyMCE.getInstanceById(editor_id);
    73         var focusElm = inst.getFocusElement();
    74         var doc = inst.getDoc();
    75 
    76         function getAttrib(elm, name) {
    77                 return elm.getAttribute(name) ? elm.getAttribute(name) : "";
    78         }
    79 
    80         // Handle commands
    81         switch (command) {
    82                         case "mcewordpressmore":
     2tinyMCE.importPluginLanguagePack('wordpress', 'en');
     3
     4var TinyMCE_wordpressPlugin = {
     5        getInfo : function() {
     6                return {
     7                        longname : 'WordPress Plugin',
     8                        author : 'WordPress',
     9                        authorurl : 'http://wordpress.org',
     10                        infourl : 'http://wordpress.org',
     11                        version : '1'
     12                };
     13        },
     14
     15        getControlHTML : function(control_name) {
     16                switch (control_name) {
     17                        case "wp_more":
     18                                return tinyMCE.getButtonHTML(control_name, 'lang_wordpress_more_button', '{$pluginurl}/images/more.gif', 'wpMore');
     19                        case "wp_page":
     20                                return tinyMCE.getButtonHTML(control_name, 'lang_wordpress_page_button', '{$pluginurl}/images/page.gif', 'wpPage');
     21                        case "wp_help":
     22                                var buttons = tinyMCE.getButtonHTML(control_name, 'lang_help_button_title', '{$pluginurl}/images/help.gif', 'wpHelp');
     23                                var hiddenControls = '<div class="zerosize">'
     24                                + '<input type="button" accesskey="n" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceSpellCheck\',false);" />'
     25                                + '<input type="button" accesskey="k" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Strikethrough\',false);" />'
     26                                + '<input type="button" accesskey="l" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertUnorderedList\',false);" />'
     27                                + '<input type="button" accesskey="o" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertOrderedList\',false);" />'
     28                                + '<input type="button" accesskey="w" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Outdent\',false);" />'
     29                                + '<input type="button" accesskey="q" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Indent\',false);" />'
     30                                + '<input type="button" accesskey="f" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyLeft\',false);" />'
     31                                + '<input type="button" accesskey="c" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyCenter\',false);" />'
     32                                + '<input type="button" accesskey="r" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyRight\',false);" />'
     33                                + '<input type="button" accesskey="j" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyFull\',false);" />'
     34                                + '<input type="button" accesskey="a" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceLink\',true);" />'
     35                                + '<input type="button" accesskey="s" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'unlink\',false);" />'
     36                                + '<input type="button" accesskey="m" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceImage\',true);" />'
     37                                + '<input type="button" accesskey="t" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpMore\');" />'
     38                                + '<input type="button" accesskey="g" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpPage\');" />'
     39                                + '<input type="button" accesskey="u" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Undo\',false);" />'
     40                                + '<input type="button" accesskey="y" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Redo\',false);" />'
     41                                + '<input type="button" accesskey="e" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceCodeEditor\',false);" />'
     42                                + '<input type="button" accesskey="h" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpHelp\',false);" />'
     43                                + '<input type="button" accesskey="b" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpAdv\',false);" />'
     44                                + '</div>';
     45                                return buttons+hiddenControls;
     46                        case "wp_adv":
     47                                return tinyMCE.getButtonHTML(control_name, 'lang_wordpress_adv_button', '{$pluginurl}/images/toolbars.gif', 'wpAdv');
     48                        case "wp_adv_start":
     49                                return '<div id="wpadvbar" style="display:none;"><br />';
     50                        case "wp_adv_end":
     51                                return '</div>';
     52                }
     53                return '';
     54        },
     55
     56        execCommand : function(editor_id, element, command, user_interface, value) {
     57                var inst = tinyMCE.getInstanceById(editor_id);
     58                var focusElm = inst.getFocusElement();
     59                var doc = inst.getDoc();
     60
     61                function getAttrib(elm, name) {
     62                        return elm.getAttribute(name) ? elm.getAttribute(name) : "";
     63                }
     64
     65                // Handle commands
     66                switch (command) {
     67                        case "wpMore":
    8368                                var flag = "";
    8469                                var template = new Array();
    … …  
    9984                                        + ' width="100%" height="10px" '
    10085                                        + 'alt="'+altMore+'" title="'+altMore+'" class="mce_plugin_wordpress_more" name="mce_plugin_wordpress_more" />';
    101                                 tinyMCE.execCommand("mceInsertContent",true,html);
     86                                tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, html);
    10287                                tinyMCE.selectedInstance.repaint();
    10388                                return true;
    104                         case "mcewordpresspage":
     89
     90                        case "wpPage":
    10591                                var flag = "";
    10692                                var template = new Array();
    … …  
    124110                                tinyMCE.selectedInstance.repaint();
    125111                                return true;
     112
     113                        case "wpHelp":
     114                                var template = new Array();
     115
     116                                template['file']   = tinyMCE.baseURL + '/wp-mce-help.php';
     117                                template['width']  = 480;
     118                                template['height'] = 380;
     119
     120                                args = {
     121                                        resizable : 'yes',
     122                                        scrollbars : 'yes'
     123                                };
     124
     125                                tinyMCE.openWindow(template, args);
     126                                return true;
     127                        case "wpAdv":
     128                                var adv = document.getElementById('wpadvbar');
     129                                if ( adv.style.display == 'none' ) {
     130                                        adv.style.display = 'block';
     131                                        tinyMCE.switchClass(editor_id + '_wp_adv', 'mceButtonSelected');
     132                                } else {
     133                                        adv.style.display = 'none';
     134                                        tinyMCE.switchClass(editor_id + '_wp_adv', 'mceButtonNormal');
     135                                }
     136                                return true;
     137                }
     138
     139                // Pass to next handler in chain
     140                return false;
     141        },
     142
     143        cleanup : function(type, content) {
     144                switch (type) {
     145
     146                        case "insert_to_editor":
     147                                var startPos = 0;
     148                                var altMore = tinyMCE.getLang('lang_wordpress_more_alt');
     149                                var altPage = tinyMCE.getLang('lang_wordpress_page_alt');
     150
     151                                // Parse all <!--more--> tags and replace them with images
     152                                while ((startPos = content.indexOf('<!--more-->', startPos)) != -1) {
     153                                        // Insert image
     154                                        var contentAfter = content.substring(startPos + 11);
     155                                        content = content.substring(0, startPos);
     156                                        content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
     157                                        content += ' width="100%" height="10px" ';
     158                                        content += 'alt="'+altMore+'" title="'+altMore+'" class="mce_plugin_wordpress_more" name="mce_plugin_wordpress_more" />';
     159                                        content += contentAfter;
     160
     161                                        startPos++;
     162                                }
     163                                var startPos = 0;
     164
     165                                // Parse all <!--page--> tags and replace them with images
     166                                while ((startPos = content.indexOf('<!--nextpage-->', startPos)) != -1) {
     167                                        // Insert image
     168                                        var contentAfter = content.substring(startPos + 15);
     169                                        content = content.substring(0, startPos);
     170                                        content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
     171                                        content += ' width="100%" height="10px" ';
     172                                        content += 'alt="'+altPage+'" title="'+altPage+'" class="mce_plugin_wordpress_page" name="mce_plugin_wordpress_page" />';
     173                                        content += contentAfter;
     174
     175                                        startPos++;
     176                                }
     177
     178                                // Look for \n in <pre>, replace with <br>
     179                                var startPos = -1;
     180                                while ((startPos = content.indexOf('<pre', startPos+1)) != -1) {
     181                                        var endPos = content.indexOf('</pre>', startPos+1);
     182                                        var innerPos = content.indexOf('>', startPos+1);
     183                                        var chunkBefore = content.substring(0, innerPos);
     184                                        var chunkAfter = content.substring(endPos);
     185                                       
     186                                        var innards = content.substring(innerPos, endPos);
     187                                        innards = innards.replace(/\n/g, '<br />');
     188                                        content = chunkBefore + innards + chunkAfter;
     189                                }
     190
     191                                break;
     192
     193                        case "get_from_editor":
     194                                // Parse all img tags and replace them with <!--more-->
     195                                var startPos = -1;
     196                                while ((startPos = content.indexOf('<img', startPos+1)) != -1) {
     197                                        var endPos = content.indexOf('/>', startPos);
     198                                        var attribs = this._parseAttributes(content.substring(startPos + 4, endPos));
     199
     200                                        if (attribs['class'] == "mce_plugin_wordpress_more" || attribs['name'] == "mce_plugin_wordpress_more") {
     201                                                endPos += 2;
     202
     203                                                var embedHTML = '<!--more-->';
     204
     205                                                // Insert embed/object chunk
     206                                                chunkBefore = content.substring(0, startPos);
     207                                                chunkAfter = content.substring(endPos);
     208                                                content = chunkBefore + embedHTML + chunkAfter;
     209                                        }
     210                                        if (attribs['class'] == "mce_plugin_wordpress_page" || attribs['name'] == "mce_plugin_wordpress_page") {
     211                                                endPos += 2;
     212
     213                                                var embedHTML = '<!--nextpage-->';
     214
     215                                                // Insert embed/object chunk
     216                                                chunkBefore = content.substring(0, startPos);
     217                                                chunkAfter = content.substring(endPos);
     218                                                content = chunkBefore + embedHTML + chunkAfter;
     219                                        }
     220                                }
     221
     222                                // Remove normal line breaks
     223                                content = content.replace(/\n|\r/g, ' ');
     224
     225                                // Look for <br> in <pre>, replace with \n
     226                                var startPos = -1;
     227                                while ((startPos = content.indexOf('<pre', startPos+1)) != -1) {
     228                                        var endPos = content.indexOf('</pre>', startPos+1);
     229                                        var innerPos = content.indexOf('>', startPos+1);
     230                                        var chunkBefore = content.substring(0, innerPos);
     231                                        var chunkAfter = content.substring(endPos);
     232                                       
     233                                        var innards = content.substring(innerPos, endPos);
     234                                        innards = innards.replace(new RegExp('<br\\s?/?>', 'g'), '\n');
     235                                        innards = innards.replace(new RegExp('\\s$', ''), '');
     236                                        content = chunkBefore + innards + chunkAfter;
     237                                }
     238
     239                                // Remove anonymous, empty paragraphs.
     240                                content = content.replace(new RegExp('<p>(\\s|&nbsp;)*</p>', 'mg'), '');
     241       
     242                                // Handle table badness.
     243                                content = content.replace(new RegExp('<(table( [^>]*)?)>.*?<((tr|thead)( [^>]*)?)>', 'mg'), '<$1><$3>');
     244                                content = content.replace(new RegExp('<(tr|thead|tfoot)>.*?<((td|th)( [^>]*)?)>', 'mg'), '<$1><$2>');
     245                                content = content.replace(new RegExp('</(td|th)>.*?<(td( [^>]*)?|th( [^>]*)?|/tr|/thead|/tfoot)>', 'mg'), '</$1><$2>');
     246                                content = content.replace(new RegExp('</tr>.*?<(tr|/table)>', 'mg'), '</tr><$1>');
     247                                content = content.replace(new RegExp('<(/?(table|tbody|tr|th|td)[^>]*)>(\\s*|(<br ?/?>)*)*', 'g'), '<$1>');
     248       
     249                                // Pretty it up for the source editor.
     250                                var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre|p';
     251                                content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
     252                                content = content.replace(new RegExp('\\s*<(('+blocklist+')[^>]*)>\\s*', 'mg'), '\n<$1>');
     253                                content = content.replace(new RegExp('<((li|/?tr|/?thead|/?tfoot)( [^>]*)?)>', 'g'), '\t<$1>');
     254                                content = content.replace(new RegExp('<((td|th)( [^>]*)?)>', 'g'), '\t\t<$1>');
     255                                content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'mg'), '<br />\n');
     256                                content = content.replace(new RegExp('^\\s*', ''), '');
     257                                content = content.replace(new RegExp('\\s*$', ''), '');
     258
     259                                break;
     260                }
     261
     262                // Pass through to next handler in chain
     263                return content;
     264        },
     265
     266        handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
     267
     268                tinyMCE.switchClass(editor_id + '_wp_more', 'mceButtonNormal');
     269                tinyMCE.switchClass(editor_id + '_wp_page', 'mceButtonNormal');
     270
     271                if (node == null)
     272                        return;
     273
     274                do {
     275                        if (node.nodeName.toLowerCase() == "img" && tinyMCE.getAttrib(node, 'class').indexOf('mce_plugin_wordpress_more') == 0)
     276                                tinyMCE.switchClass(editor_id + '_wp_more', 'mceButtonSelected');
     277                        if (node.nodeName.toLowerCase() == "img" && tinyMCE.getAttrib(node, 'class').indexOf('mce_plugin_wordpress_page') == 0)
     278                                tinyMCE.switchClass(editor_id + '_wp_page', 'mceButtonSelected');
     279                } while ((node = node.parentNode));
     280
     281                return true;
     282        },
     283
     284        saveCallback : function(el, content, body) {
     285                // We have a TON of cleanup to do.
     286
     287                // Mark </p> if it has any attributes.
     288                content = content.replace(new RegExp('(<p[^>]+>.*?)</p>', 'mg'), '$1</p#>');
     289
     290                // Decode the ampersands of time.
     291                // content = content.replace(new RegExp('&amp;', 'g'), '&');
     292
     293                // Get it ready for wpautop.
     294                content = content.replace(new RegExp('[\\s]*<p>[\\s]*', 'mgi'), '');
     295                content = content.replace(new RegExp('[\\s]*</p>[\\s]*', 'mgi'), '\n\n');
     296                content = content.replace(new RegExp('\\n\\s*\\n\\s*\\n*', 'mgi'), '\n\n');
     297                content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'gi'), '\n');
     298
     299                // Fix some block element newline issues
     300                var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre';
     301                content = content.replace(new RegExp('\\s*<(('+blocklist+') ?[^>]*)\\s*>', 'mg'), '\n<$1>');
     302                content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
     303                content = content.replace(new RegExp('<li>', 'g'), '\t<li>');
     304
     305                // Unmark special paragraph closing tags
     306                content = content.replace(new RegExp('</p#>', 'g'), '</p>\n');
     307                content = content.replace(new RegExp('\\s*(<p[^>]+>.*</p>)', 'mg'), '\n$1');
     308
     309                // Trim any whitespace
     310                content = content.replace(new RegExp('^\\s*', ''), '');
     311                content = content.replace(new RegExp('\\s*$', ''), '');
     312
     313                // Hope.
     314                return content;
     315
     316        },
     317
     318        _parseAttributes : function(attribute_string) {
     319                var attributeName = "";
     320                var attributeValue = "";
     321                var withInName;
     322                var withInValue;
     323                var attributes = new Array();
     324                var whiteSpaceRegExp = new RegExp('^[ \n\r\t]+', 'g');
     325                var titleText = tinyMCE.getLang('lang_wordpress_more');
     326                var titleTextPage = tinyMCE.getLang('lang_wordpress_page');
     327
     328                if (attribute_string == null || attribute_string.length < 2)
     329                        return null;
     330
     331                withInName = withInValue = false;
     332
     333                for (var i=0; i<attribute_string.length; i++) {
     334                        var chr = attribute_string.charAt(i);
     335
     336                        if ((chr == '"' || chr == "'") && !withInValue)
     337                                withInValue = true;
     338                        else if ((chr == '"' || chr == "'") && withInValue) {
     339                                withInValue = false;
     340
     341                                var pos = attributeName.lastIndexOf(' ');
     342                                if (pos != -1)
     343                                        attributeName = attributeName.substring(pos+1);
     344
     345                                attributes[attributeName.toLowerCase()] = attributeValue.substring(1).toLowerCase();
     346
     347                                attributeName = "";
     348                                attributeValue = "";
     349                        } else if (!whiteSpaceRegExp.test(chr) && !withInName && !withInValue)
     350                                withInName = true;
     351
     352                        if (chr == '=' && withInName)
     353                                withInName = false;
     354
     355                        if (withInName)
     356                                attributeName += chr;
     357
     358                        if (withInValue)
     359                                attributeValue += chr;
     360                }
     361
     362                return attributes;
    126363        }
    127 
    128         // Pass to next handler in chain
    129         return false;
    130 }
    131 
    132 function TinyMCE_wordpress_cleanup(type, content) {
    133         switch (type) {
    134 
    135                 case "insert_to_editor":
    136                         var startPos = 0;
    137                         var altMore = tinyMCE.getLang('lang_wordpress_more_alt');
    138                         var altPage = tinyMCE.getLang('lang_wordpress_page_alt');
    139 
    140                         // Parse all <!--more--> tags and replace them with images
    141                         while ((startPos = content.indexOf('<!--more-->', startPos)) != -1) {
    142                                 // Insert image
    143                                 var contentAfter = content.substring(startPos + 11);
    144                                 content = content.substring(0, startPos);
    145                                 content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
    146                                 content += ' width="100%" height="10px" ';
    147                                 content += 'alt="'+altMore+'" title="'+altMore+'" class="mce_plugin_wordpress_more" />';
    148                                 content += contentAfter;
    149 
    150                                 startPos++;
    151                         }
    152                         var startPos = 0;
    153 
    154                         // Parse all <!--page--> tags and replace them with images
    155                         while ((startPos = content.indexOf('<!--nextpage-->', startPos)) != -1) {
    156                                 // Insert image
    157                                 var contentAfter = content.substring(startPos + 15);
    158                                 content = content.substring(0, startPos);
    159                                 content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
    160                                 content += ' width="100%" height="10px" ';
    161                                 content += 'alt="'+altPage+'" title="'+altPage+'" class="mce_plugin_wordpress_page" />';
    162                                 content += contentAfter;
    163 
    164                                 startPos++;
    165                         }
    166 
    167                         // It's supposed to be WYSIWYG, right?
    168                         content = content.replace(new RegExp('&', 'g'), '&amp;');
    169 
    170                         break;
    171 
    172                 case "get_from_editor":
    173                         // Parse all img tags and replace them with <!--more-->
    174                         var startPos = -1;
    175                         while ((startPos = content.indexOf('<img', startPos+1)) != -1) {
    176                                 var endPos = content.indexOf('/>', startPos);
    177                                 var attribs = TinyMCE_wordpress_parseAttributes(content.substring(startPos + 4, endPos));
    178 
    179                                 if (attribs['class'] == "mce_plugin_wordpress_more") {
    180                                         endPos += 2;
    181 
    182                                         var embedHTML = '<!--more-->';
    183 
    184                                         // Insert embed/object chunk
    185                                         chunkBefore = content.substring(0, startPos);
    186                                         chunkAfter = content.substring(endPos);
    187                                         content = chunkBefore + embedHTML + chunkAfter;
    188                                 }
    189                                 if (attribs['class'] == "mce_plugin_wordpress_page") {
    190                                         endPos += 2;
    191 
    192                                         var embedHTML = '<!--nextpage-->';
    193 
    194                                         // Insert embed/object chunk
    195                                         chunkBefore = content.substring(0, startPos);
    196                                         chunkAfter = content.substring(endPos);
    197                                         content = chunkBefore + embedHTML + chunkAfter;
    198                                 }
    199                         }
    200 
    201                         // If it says & in the WYSIWYG editor, it should say &amp; in the html.
    202                         content = content.replace(new RegExp('&', 'g'), '&amp;');
    203                         content = content.replace(new RegExp('&amp;nbsp;', 'g'), '&nbsp;');
    204 
    205                         // Remove anonymous, empty paragraphs.
    206                         content = content.replace(new RegExp('<p>(\\s|&nbsp;)*</p>', 'mg'), '');
    207 
    208                         // Handle table badness.
    209                         content = content.replace(new RegExp('<(table( [^>]*)?)>.*?<((tr|thead)( [^>]*)?)>', 'mg'), '<$1><$3>');
    210                         content = content.replace(new RegExp('<(tr|thead|tfoot)>.*?<((td|th)( [^>]*)?)>', 'mg'), '<$1><$2>');
    211                         content = content.replace(new RegExp('</(td|th)>.*?<(td( [^>]*)?|th( [^>]*)?|/tr|/thead|/tfoot)>', 'mg'), '</$1><$2>');
    212                         content = content.replace(new RegExp('</tr>.*?<(tr|/table)>', 'mg'), '</tr><$1>');
    213                         content = content.replace(new RegExp('<(/?(table|tbody|tr|th|td)[^>]*)>(\\s*|(<br ?/?>)*)*', 'g'), '<$1>');
    214 
    215                         // Pretty it up for the source editor.
    216                         var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre|p';
    217                         content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
    218                         content = content.replace(new RegExp('\\s*<(('+blocklist+')[^>]*)>\\s*', 'mg'), '\n<$1>');
    219                         content = content.replace(new RegExp('<((li|/?tr|/?thead|/?tfoot)( [^>]*)?)>', 'g'), '\t<$1>');
    220                         content = content.replace(new RegExp('<((td|th)( [^>]*)?)>', 'g'), '\t\t<$1>');
    221                         content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'mg'), '<br />\n');
    222                         content = content.replace(new RegExp('^\\s*', ''), '');
    223                         content = content.replace(new RegExp('\\s*$', ''), '');
    224 
    225                         break;
     364};
     365
     366tinyMCE.addPlugin("wordpress", TinyMCE_wordpressPlugin);
     367
     368/* This little hack protects our More and Page placeholders from the removeformat command */
     369tinyMCE.orgExecCommand = tinyMCE.execCommand;
     370tinyMCE.execCommand = function (command, user_interface, value) {
     371        re = this.orgExecCommand(command, user_interface, value);
     372
     373        if ( command == 'removeformat' ) {
     374                var inst = tinyMCE.getInstanceById('mce_editor_0');
     375                doc = inst.getDoc();
     376                var imgs = doc.getElementsByTagName('img');
     377                for (i=0;img=imgs[i];i++)
     378                        img.className = img.name;
    226379        }
    227 
    228         // Pass through to next handler in chain
    229         return content;
    230 }
    231 
    232 function TinyMCE_wordpress_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
    233         function getAttrib(elm, name) {
    234                 return elm.getAttribute(name) ? elm.getAttribute(name) : "";
    235         }
    236 
    237         tinyMCE.switchClassSticky(editor_id + '_wordpress_more', 'mceButtonNormal');
    238         tinyMCE.switchClassSticky(editor_id + '_wordpress_page', 'mceButtonNormal');
    239 
    240         if (node == null)
    241                 return;
    242 
    243         do {
    244                 if (node.nodeName.toLowerCase() == "img" && getAttrib(node, 'class').indexOf('mce_plugin_wordpress_more') == 0)
    245                         tinyMCE.switchClassSticky(editor_id + '_wordpress_more', 'mceButtonSelected');
    246                 if (node.nodeName.toLowerCase() == "img" && getAttrib(node, 'class').indexOf('mce_plugin_wordpress_page') == 0)
    247                         tinyMCE.switchClassSticky(editor_id + '_wordpress_page', 'mceButtonSelected');
    248         } while ((node = node.parentNode));
    249 
    250         return true;
    251 }
    252 
    253 function wp_save_callback(el, content, body) {
    254         // We have a TON of cleanup to do.
    255 
    256         // Mark </p> if it has any attributes.
    257         content = content.replace(new RegExp('(<p[^>]+>.*?)</p>', 'mg'), '$1</p#>');
    258 
    259         // Decode the ampersands of time.
    260         content = content.replace(new RegExp('&amp;', 'g'), '&');
    261 
    262         // Get it ready for wpautop.
    263         content = content.replace(new RegExp('[\\s]*<p>[\\s]*', 'mgi'), '');
    264         content = content.replace(new RegExp('[\\s]*</p>[\\s]*', 'mgi'), '\n\n');
    265         content = content.replace(new RegExp('\\n\\s*\\n\\s*\\n*', 'mgi'), '\n\n');
    266         content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'gi'), '\n');
    267 
    268         // Fix some block element newline issues
    269         var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre';
    270         content = content.replace(new RegExp('\\s*<(('+blocklist+') ?[^>]*)\\s*>', 'mg'), '\n<$1>');
    271         content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
    272         content = content.replace(new RegExp('<li>', 'g'), '\t<li>');
    273 
    274         // Unmark special paragraph closing tags
    275         content = content.replace(new RegExp('</p#>', 'g'), '</p>\n');
    276         content = content.replace(new RegExp('\\s*(<p[^>]+>.*</p>)', 'mg'), '\n$1');
    277 
    278         // Trim any whitespace
    279         content = content.replace(new RegExp('^\\s*', ''), '');
    280         content = content.replace(new RegExp('\\s*$', ''), '');
    281 
    282         // Hope.
    283         return content;
    284 
    285 }
     380        return re;
     381};
     382
     383tinyMCE.orgFixGeckoBaseHREFBug = tinyMCE.fixGeckoBaseHREFBug;
     384tinyMCE.fixGeckoBaseHREFBug = function(m, e, h) {
     385        if ( tinyMCE.isGecko && m == 1 )
     386                h = h.replace(new RegExp('<((a|img|select|area|iframe|base|input|script|embed|object|link)\\s([^>]*\\s)?)(src|href)\\s*=', 'gi'), '<$1 x$4=');
     387        else
     388                h = tinyMCE.orgFixGeckoBaseHREFBug(m, e, h);
     389
     390        return h;
     391};
     392
     393tinyMCE.orgStoreAwayURLs = tinyMCE.storeAwayURLs;
     394tinyMCE.storeAwayURLs = function(s) {
     395                // Remove all mce_src, mce_href and replace them with new ones
     396                s = s.replace(new RegExp('mce_(href|src)\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
     397                s = s.replace(new RegExp('<((a|img|select|area|iframe|base|input|script|embed|object|link)\\s([^>]*\\s)?)(src|href)\\s*=\\s*"([^"]*)"', 'gi'), '<$1 $4="$5" mce_$4="$5"');
     398
     399                return s;
     400};
  • trunk/wp-includes/js/tinymce/plugins/wordpress/langs/en.js

    r3569 r3664  
    1010
    1111tinyMCE.addToLang('',{
    12 wordpress_more_button : 'Split post with More tag (' + metaKey + '-t)',
     12wordpress_more_button : 'Split post with More tag (' + metaKey + '+t)',
    1313wordpress_page_button : 'Split post with Page tag',
     14wordpress_adv_button : 'Show/Hide Advanced Toolbar (' + metaKey + '+b)',
    1415wordpress_more_alt : 'More...',
    15 wordpress_page_alt : '...page...'
     16wordpress_page_alt : '...page...',
     17help_button_title : 'Help (' + metaKey + '+h)',
     18bold_desc : 'Bold (Ctrl+B)',
     19italic_desc : 'Italic (Ctrl+I)',
     20underline_desc : 'Underline (Ctrl+U)',
     21link_desc : 'Insert/edit link (' + metaKey + '+a)',
     22unlink_desc : 'Unlink (' + metaKey + '+s)',
     23image_desc : 'Insert/edit image (' + metaKey + '+m)',
     24striketrough_desc : 'Strikethrough (' + metaKey + '+k)',
     25justifyleft_desc : 'Align left (' + metaKey + '+f)',
     26justifycenter_desc : 'Align center (' + metaKey + '+c)',
     27justifyright_desc : 'Align right (' + metaKey + '+r)',
     28justifyfull_desc : 'Align full (' + metaKey + '+j)',
     29bullist_desc : 'Unordered list (' + metaKey + '+l)',
     30numlist_desc : 'Ordered list (' + metaKey + '+o)',
     31outdent_desc : 'Outdent (' + metaKey + '+w)',
     32indent_desc : 'Indent List/Blockquote (' + metaKey + '+q)'
    1633});
  • trunk/wp-includes/js/tinymce/plugins/wordpress/wordpress.css

    r2820 r3664  
    2020        background-position: right top;
    2121}
     22
     23/* This file contains the CSS data for the editable area(iframe) of TinyMCE */
     24/* You can extend this CSS by adding your own CSS file with the the content_css option */
     25
     26body {
     27        font-family: Verdana, Arial, Helvetica, sans-serif;
     28        font-size: 0.9em;
     29        line-height: 1.2em;
     30        padding: .3em;
     31        background-color: #FFFFFF;
     32}
     33
     34td {
     35        font-size: 10px;
     36}
     37
     38pre {
     39        font-family: "Courier New", fixed;
     40        font-size: 11px;
     41        line-height: 13px;
     42}
     43
     44.mceVisualAid {
     45        border: 1px dashed #BBBBBB !important;
     46}
     47
     48.mceItemAnchor {
     49        width: 12px;
     50        line-height: 6px;
     51        overflow: hidden;
     52        padding-left: 12px;
     53        background-image: url('../images/anchor_symbol.gif');
     54        background-position: bottom;
     55        background-repeat: no-repeat;
     56}
     57
     58/* Important is needed in Gecko browsers inorder to style links */
     59/*
     60a {
     61        color: green !important;
     62}
     63*/
     64
     65/* Style selection range colors in Gecko browsers */
     66/*
     67::-moz-selection {
     68        background-color: red;
     69        color: green;
     70}
     71*/
     72
     73/* MSIE specific */
     74
     75* html body {
     76        scrollbar-3dlight-color: #F0F0EE;
     77        scrollbar-arrow-color: #676662;
     78        scrollbar-base-color: #F0F0EE;
     79        scrollbar-darkshadow-color: #DDDDDD;
     80        scrollbar-face-color: #E0E0DD;
     81        scrollbar-highlight-color: #F0F0EE;
     82        scrollbar-shadow-color: #F0F0EE;
     83        scrollbar-track-color: #F5F5F5;
     84}
  • trunk/wp-includes/js/tinymce/themes/advanced/about.htm

    r3062 r3664  
    55        <script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
    66        <script language="javascript" type="text/javascript" src="jscripts/about.js"></script>
    7         <link href="css/dialog_about.css" rel="stylesheet" type="text/css" />
     7        <base target="_self" />
    88</head>
    99<body id="about" onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
    … …  
    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>
    24                                 <p>Copyright &copy; 2005, <a href="http://www.moxiecode.com" target="_blank">Moxiecode Systems AB</a>, All rights reserved.</p>
     24                                <p>Copyright &copy; 2003-2006, <a href="http://www.moxiecode.com" target="_blank">Moxiecode Systems AB</a>, All rights reserved.</p>
    2525                                <p>For more information about this software visit the <a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE website</a>.</p>
    2626
  • trunk/wp-includes/js/tinymce/themes/advanced/anchor.htm

    r3062 r3664  
    44        <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
    55        <script language="javascript" type="text/javascript" src="jscripts/anchor.js"></script>
     6        <base target="_self" />
    67</head>
    78<body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
  • trunk/wp-includes/js/tinymce/themes/advanced/charmap.htm

    r3062 r3664  
    55        <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
    66        <script language="javascript" type="text/javascript" src="jscripts/charmap.js"></script>
     7        <base target="_self" />
    78</head>
    8 <body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
     9<body onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('insert').focus();" style="display: none">
    910<table align="center" border="0" cellspacing="0" cellpadding="2">
    1011    <tr>
  • trunk/wp-includes/js/tinymce/themes/advanced/color_picker.htm

    r3062 r3664  
    44        <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
    55        <script language="javascript" type="text/javascript" src="jscripts/color_picker.js"></script>
     6        <base target="_self" />
    67</head>
    7 <body onload="tinyMCEPopup.executeOnLoad('init();');" marginheight="3" topmargin="3" leftmargin="3" marginwidth="3" style="display: none">
     8<body onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('insert').focus();" style="margin: 3px; display: none">
    89        <div align="center">
    910           <script language="javascript" type="text/javascript">renderColorMap();</script>
  • trunk/wp-includes/js/tinymce/themes/advanced/css/editor_content.css

    r3015 r3664  
    22/* You can extend this CSS by adding your own CSS file with the the content_css option */
    33
    4 body {
    5         background-color: #FFFFFF;
    6         font-family: Verdana, Arial, Helvetica, sans-serif;
    7         font-size: 0.9em;
    8         line-height: 1.2em;
    9         padding: .3em;
    10 }
    11 
    12 td {
     4body, td, pre {
    135        font-family: Verdana, Arial, Helvetica, sans-serif;
    146        font-size: 10px;
    157}
    168
    17 pre {
    18         font-family: Verdana, Arial, Helvetica, sans-serif;
    19         font-size: 10px;
     9body {
     10        background-color: #FFFFFF;
    2011}
    2112
    … …  
    4839}
    4940*/
     41
     42/* MSIE specific */
     43
     44* html body {
     45        scrollbar-3dlight-color: #F0F0EE;
     46        scrollbar-arrow-color: #676662;
     47        scrollbar-base-color: #F0F0EE;
     48        scrollbar-darkshadow-color: #DDDDDD;
     49        scrollbar-face-color: #E0E0DD;
     50        scrollbar-highlight-color: #F0F0EE;
     51        scrollbar-shadow-color: #F0F0EE;
     52        scrollbar-track-color: #F5F5F5;
     53}
  • trunk/wp-includes/js/tinymce/themes/advanced/css/editor_popup.css

    r2916 r3664  
    3636
    3737.input_noborder {
    38         border: 0px solid #808080;
    39 }
    40 
    41 #insert {
     38        border: 0;
     39}
     40
     41#insert, .updateButton {
    4242   font-weight: bold;
    4343   width: 90px;
    4444   height: 21px;
    45    border: 0px;
     45   border: 0;
    4646   background-image: url('../images/insert_button_bg.gif');
    4747   cursor: pointer;
    … …  
    5252   width: 90px;
    5353   height: 21px;
    54    border: 0px;
     54   border: 0;
    5555   background-image: url('../images/cancel_button_bg.gif');
    5656   cursor: pointer;
    … …  
    8585td.charmapOver {
    8686        background-color: #CCCCCC;
    87         cursor: arrow;
     87        cursor: default;
    8888}
    8989
    … …  
    121121        border-right: 1px solid;
    122122        border-color: #F0F0EE;
    123         cursor: arrow;
     123        cursor: default;
    124124}
    125125
    126126.mceButtonOver {
    127127        border: 1px solid #0A246A;
    128         cursor: arrow;
     128        cursor: default;
    129129        background-color: #B6BDD2;
    130130}
    131131
    132132.mceButtonDown {
    133         cursor: arrow;
     133        cursor: default;
    134134        border: 1px solid #0A246A;
    135135        background-color: #8592B5;
    … …  
    145145        border-right: 1px solid;
    146146        border-color: #F0F0EE;
    147         cursor: arrow;
     147        cursor: default;
    148148}
    149149
    … …  
    163163.tabs ul {
    164164        margin: 0;
    165         padding: 0px 0px 0;
     165        padding: 0 0 0;
    166166        list-style: none;
    167167}
    … …  
    171171        background: url("../images/xp/tab_bg.gif") no-repeat left top;
    172172        margin: 0;
    173         margin-left: 0px;
     173        margin-left: 0;
    174174        margin-right: 2px;
    175175        padding: 0 0 0 10px;
    … …  
    186186        display: block;
    187187        background: url("../images/xp/tab_end.gif") no-repeat right top;
    188         padding: 0px 10px 0px 0px;
     188        padding: 0px 10px 0 0;
    189189}
    190190
    … …  
    236236        font-family: Verdana, Arial;
    237237        font-size: 10px;
    238         padding: 0px;
    239         margin: 0px;
     238        padding: 0;
     239        margin: 0;
    240240        padding: 4px;
    241241}
    … …  
    296296h1, h2, h3, h4 {
    297297        color: #2B6FB6;
    298         margin: 0px;
    299         padding: 0px;
     298        margin: 0;
     299        padding: 0;
    300300        padding-top: 5px;
    301301}
    … …  
    303303h3 {
    304304        font-size: 14px;
     305}
     306
     307#link .panel_wrapper, #link div.current {
     308        height: 125px;
     309}
     310
     311#image .panel_wrapper, #image div.current {
     312        height: 190px;
    305313}
    306314
    … …  
    318326}
    319327*/
     328
     329/* Below this line is WordPress customizations */
     330#insert, #cancel, .submitbutton {
     331        font: 11px Verdana, Arial, Helvetica, sans-serif;
     332        height: auto;
     333        width: auto;
     334        background-color: transparent;
     335        background-image: url(../../../../../../wp-admin/images/fade-butt.png);
     336        background-repeat: repeat;
     337        border: 3px double;
     338        border-right-color: rgb(153, 153, 153);
     339        border-bottom-color: rgb(153, 153, 153);
     340        border-left-color: rgb(204, 204, 204);
     341        border-top-color: rgb(204, 204, 204);
     342        color: rgb(51, 51, 51);
     343        padding: 0.1em 0.5em;
     344}
     345
     346#insert:active, #cancel:active, .submitbutton:active {
     347        background: #f4f4f4;
     348        border-left-color: #999;
     349        border-top-color: #999;
     350}
     351
     352#styleSelectRow {
     353        display: none;
     354}
  • trunk/wp-includes/js/tinymce/themes/advanced/css/editor_ui.css

    r2993 r3664  
    22
    33.mceToolbarTop a, .mceToolbarTop a:visited, .mceToolbarTop a:hover, .mceToolbarBottom a, .mceToolbarBottom a:visited, .mceToolbarBottom a:hover {
    4         border: 0px; margin: 0px; padding: 0px; background: transparent;
    5 }
    6 
    7 .mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceSeparatorLine, .mceButtonDisabled, .mceButtonSelected {
    8         border: 0px; margin: 0px; padding: 0px; background: transparent;
    9         margin-top: 1px;
    10         margin-left: 1px;
    11 }
    12 
    13 .mceButtonNormal {
    14         border-top: 1px solid;
    15         border-left: 1px solid;
    16         border-bottom: 1px solid;
    17         border-right: 1px solid;
    18         border-color: #F0F0EE;
    19         cursor: arrow;
    20 }
    21 
    22 .mceButtonOver {
    23         border: 1px solid #0A246A;
    24         cursor: arrow;
    25         background-color: #B6BDD2;
    26 }
    27 
    28 .mceButtonDown {
    29         cursor: arrow;
    30         border: 1px solid #0A246A;
    31         background-color: #8592B5;
    32 }
    33 
    34 .mceButtonSelected {
    35         border: 1px solid;
    36         border-color: #C0C0BB;
    37         cursor: arrow;
    38 }
    39 
    40 .mceButtonDisabled {
    41         filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);
    42         -moz-opacity:0.3;
    43         opacity: 0.3;
    44         border-top: 1px solid;
    45         border-left: 1px solid;
    46         border-bottom: 1px solid;
    47         border-right: 1px solid;
    48         border-color: #F0F0EE;
    49         cursor: arrow;
    50 }
    51 
    52 .mceSeparator {
    53         border-top: 1px solid buttonhighlight;
    54         border-left: 1px solid buttonhighlight;
    55         border-bottom: 1px solid buttonshadow;
    56         border-right: 1px solid buttonshadow;
     4        border: 0; margin: 0; padding: 0; background: transparent;
     5}
     6
     7.mceSeparatorLine {
     8        border: 0;
     9        padding: 0;
     10        margin-left: 4px;
    5711        margin-right: 2px;
    58         margin-left: 2px;
    59 }
    60 
    61 .mceSeparatorLine {
    62         margin:2px;
    63         margin-left: 4px;
    64         background-color: #F0F0EE;
    65         border-top: 1px solid buttonshadow;
    66         border-left: 1px solid buttonshadow;
    67         border-bottom: 1px solid buttonhighlight;
    68         border-right: 1px solid buttonhighlight;
    69         width: 0px;
    70         height: 15px;
    7112}
    7213
    7314.mceSelectList {
    74         font-family: "MS Sans Serif";
    75         font-size: 7pt;
     15        font-family: 'MS Sans Serif', sans-serif, Verdana, Arial;
     16        font-size: 7pt !important;
    7617        font-weight: normal;
    7718        margin-top: 3px;
    78         padding: 0px;
     19        padding: 0;
    7920        display: inline;
    8021        vertical-align: top;
    81         background-color: #F0F0EE
     22        background-color: #F0F0EE;
    8223}
    8324
    … …  
    9940        background: #F0F0EE;
    10041        border: 1px solid #cccccc;
    101         padding: 0px;
    102         margin: 0px;
     42        padding: 0;
     43        margin: 0;
    10344}
    10445
    … …  
    10647        font-family: 'MS Sans Serif', sans-serif, Verdana, Arial;
    10748        background: #FFFFFF;
    108         padding: 0px;
    109         margin: 0px;
     49        padding: 0;
     50        margin: 0;
    11051}
    11152
    … …  
    11859.mceToolbarTop {
    11960        border-bottom: 1px solid #cccccc;
     61        padding-bottom: 1px;
    12062}
    12163
    … …  
    177119        display: none;
    178120        border: 1px dotted gray;
    179         margin: 0px;
    180         padding: 0px;
    181 }
     121        margin: 0;
     122        padding: 0;
     123}
     124
     125/* Button CSS rules */
     126
     127a.mceButtonDisabled img, a.mceButtonNormal img, a.mceButtonSelected img {
     128        width: 20px;
     129        height: 20px;
     130        cursor: default;
     131        margin-top: 1px;
     132        margin-left: 1px;
     133}
     134
     135a.mceButtonDisabled img {
     136        border: 0 !important;
     137}
     138
     139a.mceButtonNormal img, a.mceButtonSelected img {
     140        border: 1px solid #F0F0EE !important;
     141}
     142
     143a.mceButtonSelected img {
     144        border: 1px solid #6779AA !important;
     145        background-color: #D4D5D8;
     146}
     147
     148a.mceButtonNormal img:hover, a.mceButtonSelected img:hover {
     149        border: 1px solid #0A246A !important;
     150        cursor: default;
     151        background-color: #B6BDD2;
     152}
     153
     154a.mceButtonDisabled img {
     155        -moz-opacity:0.3;
     156        opacity: 0.3;
     157        border: 1px solid #F0F0EE !important;
     158        cursor: default;
     159}
     160
     161a.mceTiledButton img {
     162        background-image: url('../images/buttons.gif');
     163        background-repeat: no-repeat;
     164}
     165
     166/* MSIE specific rules */
     167
     168* html a.mceButtonNormal img, * html a.mceButtonSelected img, * html a.mceButtonDisabled img {
     169        border: 0 !important;
     170        margin-top: 2px;
     171        margin-bottom: 1px;
     172}
     173
     174* html a.mceButtonDisabled img {
     175        filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);
     176        border: 0 !important;
     177}
     178
     179* html a.mceButtonDisabled {
     180        border: 1px solid #F0F0EE !important;
     181}
     182
     183* html a.mceButtonNormal, * html a.mceButtonSelected {
     184        border: 1px solid #F0F0EE !important;
     185        cursor: default;
     186}
     187
     188* html a.mceButtonSelected {
     189        border: 1px solid #6779AA !important;
     190        background-color: #D4D5D8;
     191}
     192
     193* html a.mceButtonNormal:hover, * html a.mceButtonSelected:hover {
     194        border: 1px solid #0A246A !important;
     195        cursor: default;
     196        background-color: #B6BDD2;
     197}
     198
     199* html .mceSelectList {
     200        margin-top: 2px;
     201}
     202
     203/* Menu button CSS rules */
     204
     205span.mceMenuButton img, span.mceMenuButtonSelected img {
     206        border: 1px solid #F0F0EE;
     207        margin-left: 1px;
     208}
     209
     210span.mceMenuButtonSelected img {
     211        border: 1px solid #6779AA;
     212        background-color: #B6BDD2;
     213}
     214
     215span.mceMenuButtonSelected img.mceMenuButton {
     216        border: 1px solid #F0F0EE;
     217        background-color: transparent;
     218}
     219
     220span.mceMenuButton img.mceMenuButton, span.mceMenuButtonSelected img.mceMenuButton {
     221        border-left: 0;
     222        margin-left: 0;
     223}
     224
     225span.mceMenuButton:hover img, span.mceMenuButtonSelected:hover img {
     226        border: 1px solid #0A246A;
     227        background-color: #B6BDD2;
     228}
     229
     230span.mceMenuButton:hover img.mceMenuButton, span.mceMenuButtonSelected:hover img.mceMenuButton {
     231        border-left: 0;
     232}
     233
     234span.mceMenuButtonFocus img {
     235        border: 1px solid gray;
     236        border-right: 0;
     237        margin-left: 1px;
     238        background-color: #F5F4F2;
     239}
     240
     241span.mceMenuButtonFocus img.mceMenuButton {
     242        border: 1px solid gray;
     243        border-left: 1px solid #F5F4F2;
     244        margin-left: 0;
     245}
     246
     247/* Menu button MSIE specific rules */
     248
     249* html span.mceMenuButton, * html span.mceMenuButtonFocus {
     250        position: relative;
     251        left: 0;
     252        top: 0;
     253}
     254
     255* html span.mceMenuButton img, * html span.mceMenuButtonSelected img, * html span.mceMenuButtonFocus img {
     256        position: relative;
     257        top: 1px;
     258}
     259
     260* html span.mceMenuHover img {
     261        border: 1px solid #0A246A;
     262        background-color: #B6BDD2;
     263}
     264
     265* html span.mceMenuButtonSelected.mceMenuHover img.mceMenuButton {
     266        border: 1px solid #0A246A;
     267        background-color: #B6BDD2;
     268        border-left: 0;
     269}
     270
     271/* Menu */
     272
     273.mceMenu {
     274        position: absolute;
     275        left: 0;
     276        top: 0;
     277        display: none;
     278        z-index: 100;
     279        background-color: white;
     280        border: 1px solid gray;
     281        font-weight: normal;
     282}
     283
     284.mceMenu a, .mceMenuTitle, .mceMenuDisabled {
     285        display: block;
     286        width: 100%;
     287        text-decoration: none;
     288        background-color: white;
     289        font-family: Tahoma, Verdana, Arial, Helvetica;
     290        font-size: 11px;
     291        line-height: 20px;
     292        color: black;
     293}
     294
     295.mceMenu a:hover {
     296        background-color: #B6BDD2;
     297        color: black;
     298}
     299
     300.mceMenu span {
     301        padding-left: 10px;
     302        padding-right: 10px;
     303        display: block;
     304        line-height: 20px;
     305}
     306
     307.mceMenuSeparator {
     308        border-bottom: 1px solid gray;
     309        background-color: gray;
     310        height: 1px;
     311}
     312
     313.mceMenuTitle span {
     314        padding-left: 5px;
     315}
     316
     317.mceMenuTitle {
     318        background-color: #DDDDDD;
     319        font-weight: bold;
     320}
     321
     322.mceMenuDisabled {
     323        color: gray;
     324}
     325
     326span.mceMenuSelectedItem {
     327        background-image: url('../images/menu_check.gif');
     328        background-repeat: no-repeat;
     329        background-position: 5px 8px;
     330        padding-left: 20px;
     331}
     332
     333span.mceMenuCheckItem {
     334        padding-left: 20px;
     335}
     336
     337span.mceMenuLine {
     338        display: block;
     339        position: absolute;
     340        left: 0;
     341        top: -1px;
     342        background-color: #F5F4F2;
     343        width: 30px;
     344        height: 1px;
     345        overflow: hidden;
     346        padding-left: 0;
     347        padding-right: 0;
     348}
  • trunk/wp-includes/js/tinymce/themes/advanced/editor_template.js

    r3163 r3664  
     1/**
     2 * $RCSfile: editor_template_src.js,v $
     3 * $Revision: 1.93 $
     4 * $Date: 2006/03/14 17:33:50 $
     5 *
     6 * @author Moxiecode
     7 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
     8 */
     9
    110/* Import theme specific language pack */
    2  tinyMCE.importThemeLanguagePack('advanced');var TinyMCE_advanced_autoImportCSSClasses=true;var TinyMCE_advanced_resizer=new Object();var TinyMCE_advanced_buttons=[['bold','{$lang_bold_img}','{$lang_bold_desc}','Bold'],['italic','{$lang_italic_img}','{$lang_italic_desc}','Italic'],['underline','{$lang_underline_img}','{$lang_underline_desc}','Underline'],['strikethrough','strikethrough.gif','{$lang_striketrough_desc}','Strikethrough'],['justifyleft','left.gif','{$lang_justifyleft_desc}','JustifyLeft'],['justifycenter','center.gif','{$lang_justifycenter_desc}','JustifyCenter'],['justifyright','right.gif','{$lang_justifyright_desc}','JustifyRight'],['justifyfull','full.gif','{$lang_justifyfull_desc}','JustifyFull'],['bullist','bullist.gif','{$lang_bullist_desc}','InsertUnorderedList'],['numlist','numlist.gif','{$lang_numlist_desc}','InsertOrderedList'],['outdent','outdent.gif','{$lang_outdent_desc}','Outdent'],['indent','indent.gif','{$lang_indent_desc}','Indent'],['cut','cut.gif','{$lang_cut_desc}','Cut'],['copy','copy.gif','{$lang_copy_desc}','Copy'],['paste','paste.gif','{$lang_paste_desc}','Paste'],['undo','undo.gif','{$lang_undo_desc}','Undo'],['redo','redo.gif','{$lang_redo_desc}','Redo'],['link','link.gif','{$lang_link_desc}','mceLink',true],['unlink','unlink.gif','{$lang_unlink_desc}','unlink'],['image','image.gif','{$lang_image_desc}','mceImage',true],['cleanup','cleanup.gif','{$lang_cleanup_desc}','mceCleanup'],['help','help.gif','{$lang_help_desc}','mceHelp'],['code','code.gif','{$lang_theme_code_desc}','mceCodeEditor'],['hr','hr.gif','{$lang_theme_hr_desc}','inserthorizontalrule'],['removeformat','removeformat.gif','{$lang_theme_removeformat_desc}','removeformat'],['sub','sub.gif','{$lang_theme_sub_desc}','subscript'],['sup','sup.gif','{$lang_theme_sup_desc}','superscript'],['forecolor','forecolor.gif','{$lang_theme_forecolor_desc}','mceForeColor',true],['backcolor','backcolor.gif','{$lang_theme_backcolor_desc}','mceBackColor',true],['charmap','charmap.gif','{$lang_theme_charmap_desc}','mceCharMap'],['visualaid','visualaid.gif','{$lang_theme_visualaid_desc}','mceToggleVisualAid'],['anchor','anchor.gif','{$lang_theme_anchor_desc}','mceInsertAnchor'],['newdocument','newdocument.gif','{$lang_newdocument_desc}','mceNewDocument']];function TinyMCE_advanced_getControlHTML(button_name){var buttonTileMap=new Array('anchor.gif','backcolor.gif','bullist.gif','center.gif','charmap.gif','cleanup.gif','code.gif','copy.gif','custom_1.gif','cut.gif','forecolor.gif','full.gif','help.gif','hr.gif','image.gif','indent.gif','left.gif','link.gif','numlist.gif','outdent.gif','paste.gif','redo.gif','removeformat.gif','right.gif','strikethrough.gif','sub.gif','sup.gif','undo.gif','unlink.gif','visualaid.gif');for(var i=0;i<TinyMCE_advanced_buttons.length;i++){var but=TinyMCE_advanced_buttons[i];if(but[0]==button_name){if(tinyMCE.settings['button_tile_map']){for(var x=0;!tinyMCE.isMSIE&&x<buttonTileMap.length;x++){if(buttonTileMap[x]==but[1]){var cmd='tinyMCE.execInstanceCommand(\'{$editor_id}\',\''+but[3]+'\','+(but.length>4?but[4]:false)+(but.length>5?',\''+but[5]+'\'':'')+')';return '<a href="javascript:'+cmd+'" onclick="'+cmd+';return false;" onmousedown="return false;" target="_self"><img id="{$editor_id}_'+but[0]+'" src="{$themeurl}/images/spacer.gif" style="background-image:url({$themeurl}/images/buttons.gif); background-position: '+(0-(x*20))+'px 0px" title="'+but[2]+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';}}}var cmd='tinyMCE.execInstanceCommand(\'{$editor_id}\',\''+but[3]+'\','+(but.length>4?but[4]:false)+(but.length>5?',\''+but[5]+'\'':'')+')';return '<a href="javascript:'+cmd+'" onclick="'+cmd+';return false;" onmousedown="return false;" target="_self"><img id="{$editor_id}_'+but[0]+'" src="{$themeurl}/images/'+but[1]+'" title="'+but[2]+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';}}switch(button_name){case "formatselect":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">';var formats=tinyMCE.getParam("theme_advanced_blockformats","p,address,pre,h1,h2,h3,h4,h5,h6",true).split(',');var lookup=[['p','{$lang_theme_paragraph}'],['address','{$lang_theme_address}'],['pre','{$lang_theme_pre}'],['h1','{$lang_theme_h1}'],['h2','{$lang_theme_h2}'],['h3','{$lang_theme_h3}'],['h4','{$lang_theme_h4}'],['h5','{$lang_theme_h5}'],['h6','{$lang_theme_h6}']];html+='<option value="">{$lang_theme_block}</option>';for(var i=0;i<formats.length;i++){for(var x=0;x<lookup.length;x++){if(formats[i]==lookup[x][0]){html+='<option value="<'+lookup[x][0]+'>">'+lookup[x][1]+'</option>';}}}html+='</select>';return html;case "styleselect":return '<select id="{$editor_id}_styleSelect" onmousedown="TinyMCE_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>';case "fontselect":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>';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';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';var fonts=tinyMCE.getParam("theme_advanced_fonts",nFonts).split(';');for(var i=0;i<fonts.length;i++){if(fonts[i]!=''){var parts=fonts[i].split('=');fontHTML+='<option value="'+parts[1]+'">'+parts[0]+'</option>';}}fontHTML+='</select>';return fontHTML;case "fontsizeselect":return '<select id="{$editor_id}_fontSizeSelect" name="{$editor_id}_fontSizeSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontSize\',false,this.options[this.selectedIndex].value);" class="mceSelectList">\
    3                 <option value="0">{$lang_theme_font_size}</option>\
    4                 <option value="1">1 (8 pt)</option>\
    5                 <option value="2">2 (10 pt)</option>\
    6                 <option value="3">3 (12 pt)</option>\
    7                 <option value="4">4 (14 pt)</option>\
    8                 <option value="5">5 (18 pt)</option>\
    9                 <option value="6">6 (24 pt)</option>\
    10                 <option value="7">7 (36 pt)</option>\
    11                 </select>';case "|":case "separator":return '<img src="{$themeurl}/images/spacer.gif" width="1" height="15" class="mceSeparatorLine">';case "spacer":return '<img src="{$themeurl}/images/spacer.gif" width="1" height="15" border="0" class="mceSeparatorLine" style="vertical-align: middle" />';case "rowseparator":return '<br />';}return "";}function TinyMCE_advanced_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceForeColor":var template=new Array();var elm=tinyMCE.selectedInstance.getFocusElement();var inputColor=tinyMCE.getAttrib(elm,"color");if(inputColor=='')inputColor=elm.style.color;if(!inputColor)inputColor="#000000";template['file']='color_picker.htm';template['width']=220;template['height']=190;tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes",command:"forecolor",input_color:inputColor});return true;case "mceBackColor":var template=new Array();var elm=tinyMCE.selectedInstance.getFocusElement();var inputColor=elm.style.backgroundColor;if(!inputColor)inputColor="#000000";template['file']='color_picker.htm';template['width']=220;template['height']=190;template['width']+=tinyMCE.getLang('lang_theme_advanced_backcolor_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_backcolor_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes",command:"HiliteColor",input_color:inputColor});return true;case "mceColorPicker":if(user_interface){var template=new Array();var inputColor=value['document'].getElementById(value['element_id']).value;template['file']='color_picker.htm';template['width']=220;template['height']=190;template['close_previous']="no";template['width']+=tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_height',0);if(typeof(value['store_selection'])=="undefined")value['store_selection']=true;tinyMCE.lastColorPickerValue=value;tinyMCE.openWindow(template,{editor_id:editor_id,mce_store_selection:value['store_selection'],inline:"yes",command:"mceColorPicker",input_color:inputColor});}else{var savedVal=tinyMCE.lastColorPickerValue;var elm=savedVal['document'].getElementById(savedVal['element_id']);elm.value=value;eval('elm.onchange();');}return true;case "mceCodeEditor":var template=new Array();template['file']='source_editor.htm';template['width']=parseInt(tinyMCE.getParam("theme_advanced_source_editor_width",500));template['height']=parseInt(tinyMCE.getParam("theme_advanced_source_editor_height",400));tinyMCE.openWindow(template,{editor_id:editor_id,resizable:"yes",scrollbars:"no",inline:"yes"});return true;case "mceCharMap":var template=new Array();template['file']='charmap.htm';template['width']=550+(tinyMCE.isOpera?40:0);template['height']=250;template['width']+=tinyMCE.getLang('lang_theme_advanced_charmap_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_charmap_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"});return true;case "mceInsertAnchor":var template=new Array();template['file']='anchor.htm';template['width']=320;template['height']=90+(tinyMCE.isNS7?30:0);template['width']+=tinyMCE.getLang('lang_theme_advanced_anchor_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_anchor_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"});return true;case "mceNewDocument":if(confirm(tinyMCE.getLang('lang_newdocument')))tinyMCE.execInstanceCommand(editor_id,'mceSetContent',false,'');return true;}return false;}function TinyMCE_advanced_getEditorTemplate(settings,editorId){function removeFromArray(in_array,remove_array){var outArray=new Array();for(var i=0;i<in_array.length;i++){skip=false;for(var j=0;j<remove_array.length;j++){if(in_array[i]==remove_array[j]){skip=true;}}if(!skip){outArray[outArray.length]=in_array[i];}}return outArray;}function addToArray(in_array,add_array){for(var i=0;i<add_array.length;i++){in_array[in_array.length]=add_array[i];}return in_array;}var template=new Array();var deltaHeight=0;var resizing=tinyMCE.getParam("theme_advanced_resizing",false);var path=tinyMCE.getParam("theme_advanced_path",true);var statusbarHTML='<div id="{$editor_id}_path" class="mceStatusbarPathText" style="display: '+(path?"block":"none")+'">&nbsp;</div><div id="{$editor_id}_resize" class="mceStatusbarResize" style="display: '+(resizing?"block":"none")+'" onmousedown="TinyMCE_advanced_setResizing(event,\'{$editor_id}\',true);"></div><br style="clear: both" />';var layoutManager=tinyMCE.getParam("theme_advanced_layout_manager","SimpleLayout");var styleSelectHTML='<option value="">{$lang_theme_style_select}</option>';if(settings['theme_advanced_styles']){var stylesAr=settings['theme_advanced_styles'].split(';');for(var i=0;i<stylesAr.length;i++){var key,value;key=stylesAr[i].split('=')[0];value=stylesAr[i].split('=')[1];styleSelectHTML+='<option value="'+value+'">'+key+'</option>';}TinyMCE_advanced_autoImportCSSClasses=false;}switch(layoutManager){case "SimpleLayout":var toolbarHTML="";var toolbarLocation=tinyMCE.getParam("theme_advanced_toolbar_location","bottom");var toolbarAlign=tinyMCE.getParam("theme_advanced_toolbar_align","center");var pathLocation=tinyMCE.getParam("theme_advanced_path_location","none");var statusbarLocation=tinyMCE.getParam("theme_advanced_statusbar_location",pathLocation);var defVals={theme_advanced_buttons1:"bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,separator,sub,sup,separator,charmap"};/*toolbarHTML+='<a href="#" accesskey="q" title="'+tinyMCE.getLang("lang_toolbar_focus")+'"></a>';*/for(var i=1;i<100;i++){var def=defVals["theme_advanced_buttons"+i];var buttons=tinyMCE.getParam("theme_advanced_buttons"+i,def==null?'':def,true,',');if(buttons.length==0)break;buttons=removeFromArray(buttons,tinyMCE.getParam("theme_advanced_disable","",true,','));buttons=addToArray(buttons,tinyMCE.getParam("theme_advanced_buttons"+i+"_add","",true,','));buttons=addToArray(tinyMCE.getParam("theme_advanced_buttons"+i+"_add_before","",true,','),buttons);for(var b=0;b<buttons.length;b++)toolbarHTML+=tinyMCE.getControlHTML(buttons[b]);if(buttons.length>0){toolbarHTML+="<br />";deltaHeight-=23;}}toolbarHTML+='<a href="#" accesskey="z" onfocus="tinyMCE.getInstanceById(\''+editorId+'\').getWin().focus();"></a>';template['html']='<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>';if(toolbarLocation=="top"){template['html']+='<tr><td class="mceToolbarTop" align="'+toolbarAlign+'" height="1" nowrap="nowrap">'+toolbarHTML+'</td></tr>';}if(statusbarLocation=="top"){template['html']+='<tr><td class="mceStatusbarTop" height="1">'+statusbarHTML+'</td></tr>';deltaHeight-=23;}template['html']+='<tr><td align="center"><span id="{$editor_id}"></span></td></tr>';if(toolbarLocation=="bottom"){template['html']+='<tr><td class="mceToolbarBottom" align="'+toolbarAlign+'" height="1">'+toolbarHTML+'</td></tr>';}if(toolbarLocation=="external"){var bod=document.body;var elm=document.createElement("div");toolbarHTML=tinyMCE.replaceVars(toolbarHTML,tinyMCE.settings);toolbarHTML=tinyMCE.replaceVars(toolbarHTML,tinyMCELang);toolbarHTML=tinyMCE.replaceVar(toolbarHTML,'style_select_options',styleSelectHTML);toolbarHTML=tinyMCE.replaceVar(toolbarHTML,"editor_id",editorId);toolbarHTML=tinyMCE.applyTemplate(toolbarHTML);elm.className="mceToolbarExternal";elm.id=editorId+"_toolbar";elm.innerHTML='<table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table>';bod.appendChild(elm);deltaHeight=0;tinyMCE.getInstanceById(editorId).toolbarElement=elm;}else{tinyMCE.getInstanceById(editorId).toolbarElement=null;}if(statusbarLocation=="bottom"){template['html']+='<tr><td class="mceStatusbarBottom" height="1">'+statusbarHTML+'</td></tr>';deltaHeight-=23;}template['html']+='</tbody></table>';break;case "RowLayout":template['html']='<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>';var containers=tinyMCE.getParam("theme_advanced_containers","",true,",");var defaultContainerCSS=tinyMCE.getParam("theme_advanced_containers_default_class","container");var defaultContainerAlign=tinyMCE.getParam("theme_advanced_containers_default_align","center");for(var i=0;i<containers.length;i++){if(containers[i]=="mceEditor"){template['html']+='<tr><td align="center" class="mceEditor_border">\
    12                                                                                                 <span id="{$editor_id}"></span>\
    13                                                                                                 </td></tr>';}else if(containers[i]=="mceElementpath"||containers[i]=="mceStatusbar"){var pathClass="mceStatusbar";if(i==containers.length-1){pathClass="mceStatusbarBottom";}else if(i==0){pathClass="mceStatusbar";}else{deltaHeight-=2;}template['html']+='<tr><td class="'+pathClass+'" height="1">'+statusbarHTML+'</td></tr>';deltaHeight-=22;}else{var curContainer=tinyMCE.getParam("theme_advanced_container_"+containers[i],"",true,',');var curContainerHTML="";var curAlign=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align",defaultContainerAlign);var curCSS=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class",defaultContainerCSS);for(var j=0;j<curContainer.length;j++){curContainerHTML+=tinyMCE.getControlHTML(curContainer[j]);}if(curContainer.length>0){curContainerHTML+="<br />";deltaHeight-=23;}template['html']+='<tr><td class="'+curCSS+'" align="'+curAlign+'" height="1">'+curContainerHTML+'</td></tr>';}}template['html']+='</tbody></table>';break;case "BorderLayout":break;case "CustomLayout":var customLayout=tinyMCE.getParam("theme_advanced_custom_layout","");if(customLayout!=""&&eval("typeof("+customLayout+")")!="undefined"){template=eval(customLayout+"(template);");}break;default:alert('UNDEFINED LAYOUT MANAGER! PLEASE CHECK YOUR TINYMCE CONFIG!');break;}template['html']+='<div id="{$editor_id}_resize_box" class="mceResizeBox"></div>';template['html']=tinyMCE.replaceVar(template['html'],'style_select_options',styleSelectHTML);template['delta_width']=0;template['delta_height']=deltaHeight;return template;}function TinyMCE_advanced_setResizing(e,editor_id,state){e=typeof(e)=="undefined"?window.event:e;var resizer=TinyMCE_advanced_resizer;var editorContainer=document.getElementById(editor_id+'_parent');var editorArea=document.getElementById(editor_id+'_parent').firstChild;var resizeBox=document.getElementById(editor_id+'_resize_box');var inst=tinyMCE.getInstanceById(editor_id);if(state){var width=editorArea.clientWidth;var height=editorArea.clientHeight;resizeBox.style.width=width+"px";resizeBox.style.height=height+"px";resizer.iframeWidth=inst.iframeElement.clientWidth;resizer.iframeHeight=inst.iframeElement.clientHeight;editorArea.style.display="none";resizeBox.style.display="block";if(!resizer.eventHandlers){if(tinyMCE.isMSIE)tinyMCE.addEvent(document,"mousemove",TinyMCE_advanced_resizeEventHandler);else tinyMCE.addEvent(window,"mousemove",TinyMCE_advanced_resizeEventHandler);tinyMCE.addEvent(document,"mouseup",TinyMCE_advanced_resizeEventHandler);resizer.eventHandlers=true;}resizer.resizing=true;resizer.downX=e.screenX;resizer.downY=e.screenY;resizer.width=parseInt(resizeBox.style.width);resizer.height=parseInt(resizeBox.style.height);resizer.editorId=editor_id;resizer.resizeBox=resizeBox;resizer.horizontal=tinyMCE.getParam("theme_advanced_resize_horizontal",true);}else{resizer.resizing=false;resizeBox.style.display="none";editorArea.style.display=tinyMCE.isMSIE?"block":"table";tinyMCE.execCommand('mceResetDesignMode');}}function TinyMCE_advanced_initInstance(inst){if(tinyMCE.getParam("theme_advanced_resizing",false)){if(tinyMCE.getParam("theme_advanced_resizing_use_cookie",true)){var w=TinyMCE_advanced_getCookie("TinyMCE_"+inst.editorId+"_width");var h=TinyMCE_advanced_getCookie("TinyMCE_"+inst.editorId+"_height");TinyMCE_advanced_resizeTo(inst,w,h,tinyMCE.getParam("theme_advanced_resize_horizontal",true));}}}function TinyMCE_advanced_setCookie(name,value,expires,path,domain,secure){var curCookie=name+"="+escape(value)+((expires)?"; expires="+expires.toGMTString():"")+((path)?"; path="+escape(path):"")+((domain)?"; domain="+domain:"")+((secure)?"; secure":"");document.cookie=curCookie;}function TinyMCE_advanced_getCookie(name){var dc=document.cookie;var prefix=name+"=";var begin=dc.indexOf("; "+prefix);if(begin==-1){begin=dc.indexOf(prefix);if(begin!=0)return null;}else begin+=2;var end=document.cookie.indexOf(";",begin);if(end==-1)end=dc.length;return unescape(dc.substring(begin+prefix.length,end));}function TinyMCE_advanced_resizeTo(inst,w,h,set_w){var editorContainer=document.getElementById(inst.editorId+'_parent');var tableElm=editorContainer.firstChild;var iframe=inst.iframeElement;if(w==null||w=="null"){set_w=false;w=0;}if(h==null||h=="null")return;w=parseInt(w);h=parseInt(h);if(tinyMCE.isGecko){w+=2;h+=2;}var dx=w-tableElm.clientWidth;var dy=h-tableElm.clientHeight;if(set_w)tableElm.style.width=w+"px";tableElm.style.height=h+"px";iw=iframe.clientWidth+dx;ih=iframe.clientHeight+dy;if(tinyMCE.isGecko){iw-=2;ih-=2;}if(set_w)iframe.style.width=iw+"px";iframe.style.height=ih+"px";if(set_w){var tableBodyElm=tableElm.firstChild;var minIframeWidth=tableBodyElm.scrollWidth;if(inst.iframeElement.clientWidth<minIframeWidth){dx=minIframeWidth-inst.iframeElement.clientWidth;inst.iframeElement.style.width=(iw+dx)+"px";}}}function TinyMCE_advanced_resizeEventHandler(e){var resizer=TinyMCE_advanced_resizer;if(!resizer.resizing)return;e=typeof(e)=="undefined"?window.event:e;var dx=e.screenX-resizer.downX;var dy=e.screenY-resizer.downY;var resizeBox=resizer.resizeBox;var editorId=resizer.editorId;switch(e.type){case "mousemove":if(resizer.horizontal)resizeBox.style.width=(resizer.width+dx)+"px";resizeBox.style.height=(resizer.height+dy)+"px";break;case "mouseup":TinyMCE_advanced_setResizing(e,editorId,false);TinyMCE_advanced_resizeTo(tinyMCE.getInstanceById(editorId),resizer.width+dx,resizer.height+dy,resizer.horizontal);if(tinyMCE.getParam("theme_advanced_resizing_use_cookie",true)){var expires=new Date();expires.setTime(expires.getTime()+3600000*24*30);TinyMCE_advanced_setCookie("TinyMCE_"+editorId+"_width",""+(resizer.horizontal?resizer.width+dx:""),expires);TinyMCE_advanced_setCookie("TinyMCE_"+editorId+"_height",""+(resizer.height+dy),expires);}break;}}function TinyMCE_advanced_getInsertLinkTemplate(){var template=new Array();template['file']='link.htm';template['width']=330;template['height']=160;template['width']+=tinyMCE.getLang('lang_insert_link_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_link_delta_height',0);return template;};function TinyMCE_advanced_getInsertImageTemplate(){var template=new Array();template['file']='image.htm?src={$src}';template['width']=340;template['height']=165;template['width']+=tinyMCE.getLang('lang_insert_image_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_image_delta_height',0);return template;};function TinyMCE_advanced_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection,setup_content){function selectByValue(select_elm,value,first_index){first_index=typeof(first_index)=="undefined"?false:true;if(select_elm){for(var i=0;i<select_elm.options.length;i++){var ov=""+select_elm.options[i].value;if(first_index&&ov.toLowerCase().indexOf(value.toLowerCase())==0){select_elm.selectedIndex=i;return true;}if(ov==value){select_elm.selectedIndex=i;return true;}}}return false;};function getAttrib(elm,name){return elm.getAttribute(name)?elm.getAttribute(name):"";};if(node==null){return;}var pathElm=document.getElementById(editor_id+"_path");var inst=tinyMCE.getInstanceById(editor_id);var doc=inst.getDoc();if(pathElm){var parentNode=node;var path=new Array();while(parentNode!=null){if(parentNode.nodeName.toUpperCase()=="BODY"){break;}if(parentNode.nodeType==1){path[path.length]=parentNode;}parentNode=parentNode.parentNode;}var html="";for(var i=path.length-1;i>=0;i--){var nodeName=path[i].nodeName.toLowerCase();var nodeData="";if(nodeName=="b"){nodeName="strong";}if(nodeName=="i"){nodeName="em";}if(nodeName=="span"){var cn=tinyMCE.getAttrib(path[i],"class");if(cn!=""&&cn.indexOf('mceItem')==-1)nodeData+="class: "+cn+" ";var st=tinyMCE.getAttrib(path[i],"style");if(st!=""){st=tinyMCE.serializeStyle(tinyMCE.parseStyle(st));nodeData+="style: "+st+" ";}}if(nodeName=="font"){if(tinyMCE.getParam("convert_fonts_to_spans"))nodeName="span";var face=tinyMCE.getAttrib(path[i],"face");if(face!="")nodeData+="font: "+face+" ";var size=tinyMCE.getAttrib(path[i],"size");if(size!="")nodeData+="size: "+size+" ";var color=tinyMCE.getAttrib(path[i],"color");if(color!="")nodeData+="color: "+color+" ";}if(getAttrib(path[i],'id')!=""){nodeData+="id: "+path[i].getAttribute('id')+" ";}var className=tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i],"class"),false);if(className!=""&&className.indexOf('mceItem')==-1)nodeData+="class: "+className+" ";if(getAttrib(path[i],'src')!=""){nodeData+="src: "+path[i].getAttribute('src')+" ";}if(getAttrib(path[i],'href')!=""){nodeData+="href: "+path[i].getAttribute('href')+" ";}if(nodeName=="img"&&tinyMCE.getAttrib(path[i],"class").indexOf('mceItemFlash')!=-1){nodeName="flash";nodeData="src: "+path[i].getAttribute('title');}if(nodeName=="a"&&(anchor=tinyMCE.getAttrib(path[i],"name"))!=""){nodeName="a";nodeName+="#"+anchor;nodeData="";}if(getAttrib(path[i],'name').indexOf("mce_")!=0){var className=tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i],"class"),false);if(className!=""&&className.indexOf('mceItem')==-1){nodeName+="."+className;}}var cmd='tinyMCE.execInstanceCommand(\''+editor_id+'\',\'mceSelectNodeDepth\',false,\''+i+'\');';html+='<a title="'+nodeData+'" href="javascript:'+cmd+'" onclick="'+cmd+'return false;" onmousedown="return false;" target="_self" class="mcePathItem">'+nodeName+'</a>';if(i>0){html+=" &raquo; ";}}pathElm.innerHTML='<a href="#" accesskey="x"></a>'+tinyMCE.getLang('lang_theme_path')+": "+html+'&nbsp;';}tinyMCE.switchClassSticky(editor_id+'_justifyleft','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifyright','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifyfull','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_sub','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_sup','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_anchor','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_link','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_unlink','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_outdent','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_image','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_hr','mceButtonNormal');if(node.nodeName=="A"&&tinyMCE.getAttrib(node,"class").indexOf('mceItemAnchor')!=-1)tinyMCE.switchClassSticky(editor_id+'_anchor','mceButtonSelected');var anchorLink=tinyMCE.getParentElement(node,"a","href");if(anchorLink||any_selection){tinyMCE.switchClassSticky(editor_id+'_link',anchorLink?'mceButtonSelected':'mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_unlink',anchorLink?'mceButtonSelected':'mceButtonNormal',false);}tinyMCE.switchClassSticky(editor_id+'_visualaid',visual_aid?'mceButtonSelected':'mceButtonNormal',false);if(undo_levels!=-1){tinyMCE.switchClassSticky(editor_id+'_undo','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_redo','mceButtonDisabled',true);}if(tinyMCE.getParentElement(node,"li,blockquote")){tinyMCE.switchClassSticky(editor_id+'_outdent','mceButtonNormal',false);}if(undo_index!=-1&&(undo_index<undo_levels-1&&undo_levels>0)){tinyMCE.switchClassSticky(editor_id+'_redo','mceButtonNormal',false);}if(undo_index!=-1&&(undo_index>0&&undo_levels>0)){tinyMCE.switchClassSticky(editor_id+'_undo','mceButtonNormal',false);}var selectElm=document.getElementById(editor_id+"_styleSelect");if(selectElm){TinyMCE_advanced_setupCSSClasses(editor_id);classNode=node;breakOut=false;var index=0;do{if(classNode&&classNode.className){for(var i=0;i<selectElm.options.length;i++){if(selectElm.options[i].value==classNode.className){index=i;breakOut=true;break;}}}}while(!breakOut&&classNode!=null&&(classNode=classNode.parentNode)!=null);selectElm.selectedIndex=index;}var selectElm=document.getElementById(editor_id+"_formatSelect");if(selectElm){var elm=tinyMCE.getParentElement(node,"p,div,h1,h2,h3,h4,h5,h6,pre,address");if(elm){selectByValue(selectElm,"<"+elm.nodeName.toLowerCase()+">");}else{selectByValue(selectElm,"");}}var selectElm=document.getElementById(editor_id+"_fontNameSelect");if(selectElm){if(!tinyMCE.isSafari&&!(tinyMCE.isMSIE&&!tinyMCE.isOpera)){var face=doc.queryCommandValue('FontName');face=face==null||face==""?"":face;selectByValue(selectElm,face,face!="");}else{var elm=tinyMCE.getParentElement(node,"font","face");if(elm){var family=tinyMCE.getAttrib(elm,"face");if(family=='')family=''+elm.style.fontFamily;if(!selectByValue(selectElm,family,family!=""))selectByValue(selectElm,"");}else selectByValue(selectElm,"");}}var selectElm=document.getElementById(editor_id+"_fontSizeSelect");if(selectElm){if(!tinyMCE.isSafari&&!tinyMCE.isOpera){var size=doc.queryCommandValue('FontSize');selectByValue(selectElm,size==null||size==""?"0":size);}else{var elm=tinyMCE.getParentElement(node,"font","size");if(elm){var size=tinyMCE.getAttrib(elm,"size");if(size==''){var sizes=new Array('','8px','10px','12px','14px','18px','24px','36px');size=''+elm.style.fontSize;for(var i=0;i<sizes.length;i++){if((''+sizes[i])==size){size=i;break;}}}if(!selectByValue(selectElm,size))selectByValue(selectElm,"");}else selectByValue(selectElm,"0");}}alignNode=node;breakOut=false;do{if(!alignNode.getAttribute||!alignNode.getAttribute('align')){continue;}switch(alignNode.getAttribute('align').toLowerCase()){case "left":tinyMCE.switchClassSticky(editor_id+'_justifyleft','mceButtonSelected');breakOut=true;break;case "right":tinyMCE.switchClassSticky(editor_id+'_justifyright','mceButtonSelected');breakOut=true;break;case "middle":case "center":tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonSelected');breakOut=true;break;case "justify":tinyMCE.switchClassSticky(editor_id+'_justifyfull','mceButtonSelected');breakOut=true;break;}}while(!breakOut&&(alignNode=alignNode.parentNode)!=null);var div=tinyMCE.getParentElement(node,"div");if(div&&div.style.textAlign=="center")tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonSelected');if(!setup_content){var ar=new Array("Bold","_bold","Italic","_italic","Strikethrough","_strikethrough","superscript","_sup","subscript","_sub");for(var i=0;i<ar.length;i+=2){if(doc.queryCommandState(ar[i]))tinyMCE.switchClassSticky(editor_id+ar[i+1],'mceButtonSelected');}if(doc.queryCommandState("Underline")&&(node.parentNode==null||node.parentNode.nodeName!="A")){tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonSelected');}}do{switch(node.nodeName){case "UL":tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonSelected');break;case "OL":tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonSelected');break;case "HR":tinyMCE.switchClassSticky(editor_id+'_hr','mceButtonSelected');break;case "IMG":if(getAttrib(node,'name').indexOf('mce_')!=0){tinyMCE.switchClassSticky(editor_id+'_image','mceButtonSelected');}break;}}while((node=node.parentNode)!=null);};function TinyMCE_advanced_setupCSSClasses(editor_id){if(!TinyMCE_advanced_autoImportCSSClasses){return;}var selectElm=document.getElementById(editor_id+'_styleSelect');if(selectElm&&selectElm.getAttribute('cssImported')!='true'){var csses=tinyMCE.getCSSClasses(editor_id);if(csses&&selectElm){for(var i=0;i<csses.length;i++){selectElm.options[selectElm.length]=new Option(csses[i],csses[i]);}}if(csses!=null&&csses.length>0){selectElm.setAttribute('cssImported','true');}}};
     11tinyMCE.importThemeLanguagePack('advanced');
     12
     13var TinyMCE_AdvancedTheme = {
     14        // Private theme fields
     15        _autoImportCSSClasses : true,
     16        _resizer : {},
     17        _buttons : [
     18                // Control id, button img, button title, command, user_interface, value
     19                ['bold', '{$lang_bold_img}', 'lang_bold_desc', 'Bold'],
     20                ['italic', '{$lang_italic_img}', 'lang_italic_desc', 'Italic'],
     21                ['underline', '{$lang_underline_img}', 'lang_underline_desc', 'Underline'],
     22                ['strikethrough', 'strikethrough.gif', 'lang_striketrough_desc', 'Strikethrough'],
     23                ['justifyleft', 'justifyleft.gif', 'lang_justifyleft_desc', 'JustifyLeft'],
     24                ['justifycenter', 'justifycenter.gif', 'lang_justifycenter_desc', 'JustifyCenter'],
     25                ['justifyright', 'justifyright.gif', 'lang_justifyright_desc', 'JustifyRight'],
     26                ['justifyfull', 'justifyfull.gif', 'lang_justifyfull_desc', 'JustifyFull'],
     27                ['bullist', 'bullist.gif', 'lang_bullist_desc', 'InsertUnorderedList'],
     28                ['numlist', 'numlist.gif', 'lang_numlist_desc', 'InsertOrderedList'],
     29                ['outdent', 'outdent.gif', 'lang_outdent_desc', 'Outdent'],
     30                ['indent', 'indent.gif', 'lang_indent_desc', 'Indent'],
     31                ['cut', 'cut.gif', 'lang_cut_desc', 'Cut'],
     32                ['copy', 'copy.gif', 'lang_copy_desc', 'Copy'],
     33                ['paste', 'paste.gif', 'lang_paste_desc', 'Paste'],
     34                ['undo', 'undo.gif', 'lang_undo_desc', 'Undo'],
     35                ['redo', 'redo.gif', 'lang_redo_desc', 'Redo'],
     36                ['link', 'link.gif', 'lang_link_desc', 'mceLink', true],
     37                ['unlink', 'unlink.gif', 'lang_unlink_desc', 'unlink'],
     38                ['image', 'image.gif', 'lang_image_desc', 'mceImage', true],
     39                ['cleanup', 'cleanup.gif', 'lang_cleanup_desc', 'mceCleanup'],
     40                ['help', 'help.gif', 'lang_help_desc', 'mceHelp'],
     41                ['code', 'code.gif', 'lang_theme_code_desc', 'mceCodeEditor'],
     42                ['hr', 'hr.gif', 'lang_theme_hr_desc', 'inserthorizontalrule'],
     43                ['removeformat', 'removeformat.gif', 'lang_theme_removeformat_desc', 'removeformat'],
     44                ['sub', 'sub.gif', 'lang_theme_sub_desc', 'subscript'],
     45                ['sup', 'sup.gif', 'lang_theme_sup_desc', 'superscript'],
     46                ['forecolor', 'forecolor.gif', 'lang_theme_forecolor_desc', 'mceForeColor', true],
     47                ['backcolor', 'backcolor.gif', 'lang_theme_backcolor_desc', 'mceBackColor', true],
     48                ['charmap', 'charmap.gif', 'lang_theme_charmap_desc', 'mceCharMap'],
     49                ['visualaid', 'visualaid.gif', 'lang_theme_visualaid_desc', 'mceToggleVisualAid'],
     50                ['anchor', 'anchor.gif', 'lang_theme_anchor_desc', 'mceInsertAnchor'],
     51                ['newdocument', 'newdocument.gif', 'lang_newdocument_desc', 'mceNewDocument']
     52        ],
     53
     54        _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',
     55
     56        /**
     57         * Returns HTML code for the specificed control.
     58         */
     59        getControlHTML : function(button_name) {
     60                var i, x;
     61
     62                // Lookup button in button list
     63                for (i=0; i<TinyMCE_AdvancedTheme._buttons.length; i++) {
     64                        var but = TinyMCE_AdvancedTheme._buttons[i];
     65
     66                        if (but[0] == button_name)
     67                                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));
     68                }
     69
     70                // Custom controlls other than buttons
     71                switch (button_name) {
     72                        case "formatselect":
     73                                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">';
     74                                var formats = tinyMCE.getParam("theme_advanced_blockformats", "p,address,pre,h1,h2,h3,h4,h5,h6", true).split(',');
     75                                var lookup = [
     76                                        ['p', '{$lang_theme_paragraph}'],
     77                                        ['address', '{$lang_theme_address}'],
     78                                        ['pre', '{$lang_theme_pre}'],
     79                                        ['h1', '{$lang_theme_h1}'],
     80                                        ['h2', '{$lang_theme_h2}'],
     81                                        ['h3', '{$lang_theme_h3}'],
     82                                        ['h4', '{$lang_theme_h4}'],
     83                                        ['h5', '{$lang_theme_h5}'],
     84                                        ['h6', '{$lang_theme_h6}']
     85                                ];
     86
     87                                html += '<option value="">{$lang_theme_block}</option>';
     88
     89                                // Build format select
     90                                for (var i=0; i<formats.length; i++) {
     91                                        for (var x=0; x<lookup.length; x++) {
     92                                                if (formats[i] == lookup[x][0])
     93                                                        html += '<option value="<' + lookup[x][0] + '>">' + lookup[x][1] + '</option>';
     94                                        }
     95                                }
     96
     97                                html += '</select>';
     98
     99                                return html;
     100
     101                        case "styleselect":
     102                                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>';
     103
     104                        case "fontselect":
     105                                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>';
     106                                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';
     107                                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';
     108                                var fonts = tinyMCE.getParam("theme_advanced_fonts", nFonts).split(';');
     109                                for (i=0; i<fonts.length; i++) {
     110                                        if (fonts[i] != '') {
     111                                                var parts = fonts[i].split('=');
     112                                                fontHTML += '<option value="' + parts[1] + '">' + parts[0] + '</option>';
     113                                        }
     114                                }
     115
     116                                fontHTML += '</select>';
     117                                return fontHTML;
     118
     119                        case "fontsizeselect":
     120                                return '<select id="{$editor_id}_fontSizeSelect" name="{$editor_id}_fontSizeSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontSize\',false,this.options[this.selectedIndex].value);" class="mceSelectList">\
     121                                                <option value="0">{$lang_theme_font_size}</option>\
     122                                                <option value="1">1 (8 pt)</option>\
     123                                                <option value="2">2 (10 pt)</option>\
     124                                                <option value="3">3 (12 pt)</option>\
     125                                                <option value="4">4 (14 pt)</option>\
     126                                                <option value="5">5 (18 pt)</option>\
     127                                                <option value="6">6 (24 pt)</option>\
     128                                                <option value="7">7 (36 pt)</option>\
     129                                                </select>';
     130
     131                        case "|":
     132                        case "separator":
     133                                return '<img src="{$themeurl}/images/separator.gif" width="2" height="20" class="mceSeparatorLine" />';
     134
     135                        case "spacer":
     136                                return '<img src="{$themeurl}/images/separator.gif" width="2" height="15" border="0" class="mceSeparatorLine" style="vertical-align: middle" />';
     137
     138                        case "rowseparator":
     139                                return '<br />';
     140                }
     141
     142                return "";
     143        },
     144
     145        /**
     146         * Theme specific execcommand handling.
     147         */
     148        execCommand : function(editor_id, element, command, user_interface, value) {
     149                switch (command) {
     150                        case "mceLink":
     151                                var inst = tinyMCE.getInstanceById(editor_id);
     152                                var doc = inst.getDoc();
     153                                var selectedText = "";
     154
     155                                if (tinyMCE.isMSIE) {
     156                                        var rng = doc.selection.createRange();
     157                                        selectedText = rng.text;
     158                                } else
     159                                        selectedText = inst.getSel().toString();
     160
     161                                if (!tinyMCE.linkElement) {
     162                                        if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0))
     163                                                return true;
     164                                }
     165
     166                                var href = "", target = "", title = "", onclick = "", action = "insert", style_class = "";
     167
     168                                if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a")
     169                                        tinyMCE.linkElement = tinyMCE.selectedElement;
     170
     171                                // Is anchor not a link
     172                                if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "")
     173                                        tinyMCE.linkElement = null;
     174
     175                                if (tinyMCE.linkElement) {
     176                                        href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href');
     177                                        target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target');
     178                                        title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title');
     179                                        onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
     180                                        style_class = tinyMCE.getAttrib(tinyMCE.linkElement, 'class');
     181
     182                                        // Try old onclick to if copy/pasted content
     183                                        if (onclick == "")
     184                                                onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
     185
     186                                        onclick = tinyMCE.cleanupEventStr(onclick);
     187
     188                                        href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
     189
     190                                        // Use mce_href if defined
     191                                        mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_href');
     192                                        if (mceRealHref != "") {
     193                                                href = mceRealHref;
     194
     195                                                if (tinyMCE.getParam('convert_urls'))
     196                                                        href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
     197                                        }
     198
     199                                        action = "update";
     200                                }
     201
     202                                var template = new Array();
     203
     204                                template['file'] = 'link.htm';
     205                                template['width'] = 310;
     206                                template['height'] = 200;
     207
     208                                // Language specific width and height addons
     209                                template['width'] += tinyMCE.getLang('lang_insert_link_delta_width', 0);
     210                                template['height'] += tinyMCE.getLang('lang_insert_link_delta_height', 0);
     211
     212                                if (inst.settings['insertlink_callback']) {
     213                                        var returnVal = eval(inst.settings['insertlink_callback'] + "(href, target, title, onclick, action, style_class);");
     214                                        if (returnVal && returnVal['href'])
     215                                                TinyMCE_AdvancedTheme._insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']);
     216                                } else {
     217                                        tinyMCE.openWindow(template, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class, inline : "yes"});
     218                                }
     219
     220                                return true;
     221
     222                        case "mceImage":
     223                                var src = "", alt = "", border = "", hspace = "", vspace = "", width = "", height = "", align = "";
     224                                var title = "", onmouseover = "", onmouseout = "", action = "insert";
     225                                var img = tinyMCE.imgElement;
     226                                var inst = tinyMCE.getInstanceById(editor_id);
     227
     228                                if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") {
     229                                        img = tinyMCE.selectedElement;
     230                                        tinyMCE.imgElement = img;
     231                                }
     232
     233                                if (img) {
     234                                        // Is it a internal MCE visual aid image, then skip this one.
     235                                        if (tinyMCE.getAttrib(img, 'name').indexOf('mce_') == 0)
     236                                                return true;
     237
     238                                        src = tinyMCE.getAttrib(img, 'src');
     239                                        alt = tinyMCE.getAttrib(img, 'alt');
     240
     241                                        // Try polling out the title
     242                                        if (alt == "")
     243                                                alt = tinyMCE.getAttrib(img, 'title');
     244
     245                                        // Fix width/height attributes if the styles is specified
     246                                        if (tinyMCE.isGecko) {
     247                                                var w = img.style.width;
     248                                                if (w != null && w != "")
     249                                                        img.setAttribute("width", w);
     250
     251                                                var h = img.style.height;
     252                                                if (h != null && h != "")
     253                                                        img.setAttribute("height", h);
     254                                        }
     255
     256                                        border = tinyMCE.getAttrib(img, 'border');
     257                                        hspace = tinyMCE.getAttrib(img, 'hspace');
     258                                        vspace = tinyMCE.getAttrib(img, 'vspace');
     259                                        width = tinyMCE.getAttrib(img, 'width');
     260                                        height = tinyMCE.getAttrib(img, 'height');
     261                                        align = tinyMCE.getAttrib(img, 'align');
     262                                        onmouseover = tinyMCE.getAttrib(img, 'onmouseover');
     263                                        onmouseout = tinyMCE.getAttrib(img, 'onmouseout');
     264                                        title = tinyMCE.getAttrib(img, 'title');
     265
     266                                        // Is realy specified?
     267                                        if (tinyMCE.isMSIE) {
     268                                                width = img.attributes['width'].specified ? width : "";
     269                                                height = img.attributes['height'].specified ? height : "";
     270                                        }
     271
     272                                        //onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover));
     273                                        //onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout));
     274
     275                                        src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
     276
     277                                        // Use mce_src if defined
     278                                        mceRealSrc = tinyMCE.getAttrib(img, 'mce_src');
     279                                        if (mceRealSrc != "") {
     280                                                src = mceRealSrc;
     281
     282                                                if (tinyMCE.getParam('convert_urls'))
     283                                                        src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
     284                                        }
     285
     286                                        //if (onmouseover != "")
     287                                        //      onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);");
     288
     289                                        //if (onmouseout != "")
     290                                        //      onmouseout = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, img, true);");
     291
     292                                        action = "update";
     293                                }
     294
     295                                var template = new Array();
     296
     297                                template['file'] = 'image.htm?src={$src}';
     298                                template['width'] = 355;
     299                                template['height'] = 265 + (tinyMCE.isMSIE ? 25 : 0);
     300
     301                                // Language specific width and height addons
     302                                template['width'] += tinyMCE.getLang('lang_insert_image_delta_width', 0);
     303                                template['height'] += tinyMCE.getLang('lang_insert_image_delta_height', 0);
     304
     305                                if (inst.settings['insertimage_callback']) {
     306                                        var returnVal = eval(inst.settings['insertimage_callback'] + "(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);");
     307                                        if (returnVal && returnVal['src'])
     308                                                TinyMCE_AdvancedTheme._insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']);
     309                                } else
     310                                        tinyMCE.openWindow(template, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action, inline : "yes"});
     311
     312                                return true;
     313
     314                        case "mceForeColor":
     315                                var template = new Array();
     316                                var elm = tinyMCE.selectedInstance.getFocusElement();
     317                                var inputColor = tinyMCE.getAttrib(elm, "color");
     318
     319                                if (inputColor == '')
     320                                        inputColor = elm.style.color;
     321
     322                                if (!inputColor)
     323                                        inputColor = "#000000";
     324
     325                                template['file'] = 'color_picker.htm';
     326                                template['width'] = 220;
     327                                template['height'] = 190;
     328
     329                                tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes", command : "forecolor", input_color : inputColor});
     330                        return true;
     331
     332                        case "mceBackColor":
     333                                var template = new Array();
     334                                var elm = tinyMCE.selectedInstance.getFocusElement();
     335                                var inputColor = elm.style.backgroundColor;
     336
     337                                if (!inputColor)
     338                                        inputColor = "#000000";
     339
     340                                template['file'] = 'color_picker.htm';
     341                                template['width'] = 220;
     342                                template['height'] = 190;
     343
     344                                template['width'] += tinyMCE.getLang('lang_theme_advanced_backcolor_delta_width', 0);
     345                                template['height'] += tinyMCE.getLang('lang_theme_advanced_backcolor_delta_height', 0);
     346
     347                                tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes", command : "HiliteColor", input_color : inputColor});
     348                                //mceBackColor
     349                        return true;
     350
     351                        case "mceColorPicker":
     352                                if (user_interface) {
     353                                        var template = new Array();
     354                                        var inputColor = value['document'].getElementById(value['element_id']).value;
     355
     356                                        template['file'] = 'color_picker.htm';
     357                                        template['width'] = 220;
     358                                        template['height'] = 190;
     359                                        template['close_previous'] = "no";
     360
     361                                        template['width'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_width', 0);
     362                                        template['height'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_height', 0);
     363
     364                                        if (typeof(value['store_selection']) == "undefined")
     365                                                value['store_selection'] = true;
     366
     367                                        tinyMCE.lastColorPickerValue = value;
     368                                        tinyMCE.openWindow(template, {editor_id : editor_id, mce_store_selection : value['store_selection'], inline : "yes", command : "mceColorPicker", input_color : inputColor});
     369                                } else {
     370                                        var savedVal = tinyMCE.lastColorPickerValue;
     371                                        var elm = savedVal['document'].getElementById(savedVal['element_id']);
     372                                        elm.value = value;
     373
     374                                        if (elm.onchange != null && elm.onchange != '')
     375                                                eval('elm.onchange();');
     376                                }
     377                        return true;
     378
     379                        case "mceCodeEditor":
     380                                var template = new Array();
     381
     382                                template['file'] = 'source_editor.htm';
     383                                template['width'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_width", 720));
     384                                template['height'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_height", 580));
     385
     386                                tinyMCE.openWindow(template, {editor_id : editor_id, resizable : "yes", scrollbars : "no", inline : "yes"});
     387                                return true;
     388
     389                        case "mceCharMap":
     390                                var template = new Array();
     391
     392                                template['file'] = 'charmap.htm';
     393                                template['width'] = 550 + (tinyMCE.isOpera ? 40 : 0);
     394                                template['height'] = 250;
     395
     396                                template['width'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_width', 0);
     397                                template['height'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_height', 0);
     398
     399                                tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"});
     400                                return true;
     401
     402                        case "mceInsertAnchor":
     403                                var template = new Array();
     404
     405                                template['file'] = 'anchor.htm';
     406                                template['width'] = 320;
     407                                template['height'] = 90 + (tinyMCE.isNS7 ? 30 : 0);
     408
     409                                template['width'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_width', 0);
     410                                template['height'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_height', 0);
     411
     412                                tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"});
     413                                return true;
     414
     415                        case "mceNewDocument":
     416                                if (confirm(tinyMCE.getLang('lang_newdocument')))
     417                                        tinyMCE.execInstanceCommand(editor_id, 'mceSetContent', false, ' ');
     418
     419                                return true;
     420                }
     421
     422                return false;
     423        },
     424
     425        /**
     426         * Editor instance template function.
     427         */
     428        getEditorTemplate : function(settings, editorId) {
     429                function removeFromArray(in_array, remove_array) {
     430                        var outArray = new Array();
     431                       
     432                        for (var i=0; i<in_array.length; i++) {
     433                                skip = false;
     434
     435                                for (var j=0; j<remove_array.length; j++) {
     436                                        if (in_array[i] == remove_array[j]) {
     437                                                skip = true;
     438                                        }
     439                                }
     440
     441                                if (!skip) {
     442                                        outArray[outArray.length] = in_array[i];
     443                                }
     444                        }
     445
     446                        return outArray;
     447                }
     448
     449                function addToArray(in_array, add_array) {
     450                        for (var i=0; i<add_array.length; i++) {
     451                                in_array[in_array.length] = add_array[i];
     452                        }
     453
     454                        return in_array;
     455                }
     456
     457                var template = new Array();
     458                var deltaHeight = 0;
     459                var resizing = tinyMCE.getParam("theme_advanced_resizing", false);
     460                var path = tinyMCE.getParam("theme_advanced_path", true);
     461                var statusbarHTML = '<div id="{$editor_id}_path" class="mceStatusbarPathText" style="display: ' + (path ? "block" : "none") + '">&nbsp;</div><div id="{$editor_id}_resize" class="mceStatusbarResize" style="display: ' + (resizing ? "block" : "none") + '" onmousedown="tinyMCE.themes.advanced._setResizing(event,\'{$editor_id}\',true);"></div><br style="clear: both" />';
     462                var layoutManager = tinyMCE.getParam("theme_advanced_layout_manager", "SimpleLayout");
     463
     464                // Setup style select options -- MOVED UP FOR EXTERNAL TOOLBAR COMPATABILITY!
     465                var styleSelectHTML = '<option value="">{$lang_theme_style_select}</option>';
     466                if (settings['theme_advanced_styles']) {
     467                        var stylesAr = settings['theme_advanced_styles'].split(';');
     468                       
     469                        for (var i=0; i<stylesAr.length; i++) {
     470                                var key, value;
     471
     472                                key = stylesAr[i].split('=')[0];
     473                                value = stylesAr[i].split('=')[1];
     474
     475                                styleSelectHTML += '<option value="' + value + '">' + key + '</option>';
     476                        }
     477
     478                        TinyMCE_AdvancedTheme._autoImportCSSClasses = false;
     479                }
     480
     481                switch(layoutManager) {
     482                        case "SimpleLayout" : //the default TinyMCE Layout (for backwards compatibility)...
     483                                var toolbarHTML = "";
     484                                var toolbarLocation = tinyMCE.getParam("theme_advanced_toolbar_location", "bottom");
     485                                var toolbarAlign = tinyMCE.getParam("theme_advanced_toolbar_align", "center");
     486                                var pathLocation = tinyMCE.getParam("theme_advanced_path_location", "none"); // Compatiblity
     487                                var statusbarLocation = tinyMCE.getParam("theme_advanced_statusbar_location", pathLocation);
     488                                var defVals = {
     489                                        theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect",
     490                                        theme_advanced_buttons2 : "bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code",
     491                                        theme_advanced_buttons3 : "hr,removeformat,visualaid,separator,sub,sup,separator,charmap"
     492                                };
     493
     494                                // Add accessibility control
     495                                toolbarHTML += '<a href="#" accesskey="q" title="' + tinyMCE.getLang("lang_toolbar_focus") + '"';
     496
     497                                if (!tinyMCE.getParam("accessibility_focus"))
     498                                        toolbarHTML += ' onfocus="tinyMCE.getInstanceById(\'' + editorId + '\').getWin().focus();"';
     499
     500                                toolbarHTML += '></a>';
     501
     502                                // Render rows
     503                                for (var i=1; i<100; i++) {
     504                                        var def = defVals["theme_advanced_buttons" + i];
     505
     506                                        var buttons = tinyMCE.getParam("theme_advanced_buttons" + i, def == null ? '' : def, true, ',');
     507                                        if (buttons.length == 0)
     508                                                break;
     509
     510                                        buttons = removeFromArray(buttons, tinyMCE.getParam("theme_advanced_disable", "", true, ','));
     511                                        buttons = addToArray(buttons, tinyMCE.getParam("theme_advanced_buttons" + i + "_add", "", true, ','));
     512                                        buttons = addToArray(tinyMCE.getParam("theme_advanced_buttons" + i + "_add_before", "", true, ','), buttons);
     513
     514                                        for (var b=0; b<buttons.length; b++)
     515                                                toolbarHTML += tinyMCE.getControlHTML(buttons[b]);
     516
     517                                        if (buttons.length > 0) {
     518                                                toolbarHTML += "<br />";
     519                                                deltaHeight -= 23;
     520                                        }
     521                                }
     522
     523                                // Add accessibility control
     524                                toolbarHTML += '<a href="#" accesskey="z" onfocus="tinyMCE.getInstanceById(\'' + editorId + '\').getWin().focus();"></a>';
     525
     526                                // Setup template html
     527                                template['html'] = '<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>';
     528
     529                                if (toolbarLocation == "top") {
     530                                        template['html'] += '<tr><td class="mceToolbarTop" align="' + toolbarAlign + '" height="1" nowrap="nowrap">' + toolbarHTML + '</td></tr>';
     531                                }
     532
     533                                if (statusbarLocation == "top") {
     534                                        template['html'] += '<tr><td class="mceStatusbarTop" height="1">' + statusbarHTML + '</td></tr>';
     535                                        deltaHeight -= 23;
     536                                }
     537
     538                                template['html'] += '<tr><td align="center"><span id="{$editor_id}"></span></td></tr>';
     539
     540                                if (toolbarLocation == "bottom") {
     541                                        template['html'] += '<tr><td class="mceToolbarBottom" align="' + toolbarAlign + '" height="1">' + toolbarHTML + '</td></tr>';
     542                                }
     543
     544                                // External toolbar changes
     545                                if (toolbarLocation == "external") {
     546                                        var bod = document.body;
     547                                        var elm = document.createElement ("div");
     548
     549                                        toolbarHTML = tinyMCE.replaceVar(toolbarHTML, 'style_select_options', styleSelectHTML);
     550                                        toolbarHTML = tinyMCE.applyTemplate(toolbarHTML, {editor_id : editorId});
     551
     552                                        elm.className = "mceToolbarExternal";
     553                                        elm.id = editorId+"_toolbar";
     554                                        elm.innerHTML = '<table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table>';
     555                                        bod.appendChild (elm);
     556                                        // bod.style.marginTop = elm.offsetHeight + "px";
     557
     558                                        deltaHeight = 0;
     559                                        tinyMCE.getInstanceById(editorId).toolbarElement = elm;
     560
     561                                        //template['html'] = '<div id="mceExternalToolbar" align="center" class="mceToolbarExternal"><table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table></div>' + template["html"];
     562                                } else {
     563                                        tinyMCE.getInstanceById(editorId).toolbarElement = null;
     564                                }
     565
     566                                if (statusbarLocation == "bottom") {
     567                                        template['html'] += '<tr><td class="mceStatusbarBottom" height="1">' + statusbarHTML + '</td></tr>';
     568                                        deltaHeight -= 23;
     569                                }
     570
     571                                template['html'] += '</tbody></table>';
     572                                //"SimpleLayout"
     573                        break;
     574
     575                        case "RowLayout" : //Container Layout - containers defined in "theme_advanced_containers" are rendered from top to bottom.
     576                                template['html'] = '<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>';
     577
     578                                var containers = tinyMCE.getParam("theme_advanced_containers", "", true, ",");
     579                                var defaultContainerCSS = tinyMCE.getParam("theme_advanced_containers_default_class", "container");
     580                                var defaultContainerAlign = tinyMCE.getParam("theme_advanced_containers_default_align", "center");
     581
     582                                //Render Containers:
     583                                for (var i = 0; i < containers.length; i++)
     584                                {
     585                                        if (containers[i] == "mceEditor") //Exceptions for mceEditor and ...
     586                                        {
     587                                                template['html'] += '<tr><td align="center" class="mceEditor_border">\
     588                                                                                                        <span id="{$editor_id}"></span>\
     589                                                                                                        </td></tr>';
     590                                        }
     591                                        else if (containers[i] == "mceElementpath" || containers[i] == "mceStatusbar") // ... mceElementpath:
     592                                        {
     593                                                var pathClass = "mceStatusbar";
     594
     595                                                if (i == containers.length-1)
     596                                                {
     597                                                        pathClass = "mceStatusbarBottom";
     598                                                }
     599                                                else if (i == 0)
     600                                                {
     601                                                        pathClass = "mceStatusbar";
     602                                                }
     603                                                else
     604                                                {
     605                                                        deltaHeight-=2;
     606                                                }
     607
     608                                                template['html'] += '<tr><td class="' + pathClass + '" height="1">' + statusbarHTML + '</td></tr>';
     609                                                deltaHeight -= 22;
     610                                        } else { // Render normal Container
     611                                                var curContainer = tinyMCE.getParam("theme_advanced_container_"+containers[i], "", true, ',');
     612                                                var curContainerHTML = "";
     613                                                var curAlign = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align", defaultContainerAlign);
     614                                                var curCSS = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class", defaultContainerCSS);
     615
     616                                                for (var j=0; j<curContainer.length; j++) {
     617                                                        curContainerHTML += tinyMCE.getControlHTML(curContainer[j]);
     618                                                }
     619
     620                                                if (curContainer.length > 0) {
     621                                                        curContainerHTML += "<br />";
     622                                                        deltaHeight -= 23;
     623                                                }
     624
     625                                                template['html'] += '<tr><td class="' + curCSS + '" align="' + curAlign + '" height="1">' + curContainerHTML + '</td></tr>';
     626                                        }
     627                                }
     628
     629                                template['html'] += '</tbody></table>';
     630                                //RowLayout
     631                        break;
     632
     633                        case "CustomLayout" : //User defined layout callback...
     634                                var customLayout = tinyMCE.getParam("theme_advanced_custom_layout","");
     635
     636                                if (customLayout != "" && eval("typeof(" + customLayout + ")") != "undefined") {
     637                                        template = eval(customLayout + "(template);");
     638                                }
     639                        break;
     640                }
     641
     642                if (resizing)
     643                        template['html'] += '<span id="{$editor_id}_resize_box" class="mceResizeBox"></span>';
     644
     645                template['html'] = tinyMCE.replaceVar(template['html'], 'style_select_options', styleSelectHTML);
     646                template['delta_width'] = 0;
     647                template['delta_height'] = deltaHeight;
     648
     649                return template;
     650        },
     651
     652        initInstance : function(inst) {
     653                if (tinyMCE.getParam("theme_advanced_resizing", false)) {
     654                        if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) {
     655                                var w = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_width");
     656                                var h = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_height");
     657
     658                                TinyMCE_AdvancedTheme._resizeTo(inst, w, h, tinyMCE.getParam("theme_advanced_resize_horizontal", true));
     659                        }
     660                }
     661
     662                inst.addShortcut('ctrl', 'k', 'lang_link_desc', 'mceLink');
     663        },
     664
     665        /**
     666         * Node change handler.
     667         */
     668        handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection, setup_content) {
     669                function selectByValue(select_elm, value, first_index) {
     670                        first_index = typeof(first_index) == "undefined" ? false : true;
     671
     672                        if (select_elm) {
     673                                for (var i=0; i<select_elm.options.length; i++) {
     674                                        var ov = "" + select_elm.options[i].value;
     675
     676                                        if (first_index && ov.toLowerCase().indexOf(value.toLowerCase()) == 0) {
     677                                                select_elm.selectedIndex = i;
     678                                                return true;
     679                                        }
     680
     681                                        if (ov == value) {
     682                                                select_elm.selectedIndex = i;
     683                                                return true;
     684                                        }
     685                                }
     686                        }
     687
     688                        return false;
     689                };
     690
     691                function getAttrib(elm, name) {
     692                        return elm.getAttribute(name) ? elm.getAttribute(name) : "";
     693                };
     694
     695                // No node provided
     696                if (node == null)
     697                        return;
     698
     699                // Update path
     700                var pathElm = document.getElementById(editor_id + "_path");
     701                var inst = tinyMCE.getInstanceById(editor_id);
     702                var doc = inst.getDoc();
     703
     704                if (pathElm) {
     705                        // Get node path
     706                        var parentNode = node;
     707                        var path = new Array();
     708                       
     709                        while (parentNode != null) {
     710                                if (parentNode.nodeName.toUpperCase() == "BODY") {
     711                                        break;
     712                                }
     713
     714                                // Only append element nodes to path
     715                                if (parentNode.nodeType == 1 && tinyMCE.getAttrib(parentNode, "class").indexOf('mceItemHidden') == -1) {
     716                                        path[path.length] = parentNode;
     717                                }
     718
     719                                parentNode = parentNode.parentNode;
     720                        }
     721
     722                        // Setup HTML
     723                        var html = "";
     724                        for (var i=path.length-1; i>=0; i--) {
     725                                var nodeName = path[i].nodeName.toLowerCase();
     726                                var nodeData = "";
     727
     728                                if (nodeName == "b") {
     729                                        nodeName = "strong";
     730                                }
     731
     732                                if (nodeName == "i") {
     733                                        nodeName = "em";
     734                                }
     735
     736                                if (nodeName == "span") {
     737                                        var cn = tinyMCE.getAttrib(path[i], "class");
     738                                        if (cn != "" && cn.indexOf('mceItem') == -1)
     739                                                nodeData += "class: " + cn + " ";
     740
     741                                        var st = tinyMCE.getAttrib(path[i], "style");
     742                                        if (st != "") {
     743                                                st = tinyMCE.serializeStyle(tinyMCE.parseStyle(st));
     744                                                nodeData += "style: " + st + " ";
     745                                        }
     746                                }
     747
     748                                if (nodeName == "font") {
     749                                        if (tinyMCE.getParam("convert_fonts_to_spans"))
     750                                                nodeName = "span";
     751
     752                                        var face = tinyMCE.getAttrib(path[i], "face");
     753                                        if (face != "")
     754                                                nodeData += "font: " + face + " ";
     755
     756                                        var size = tinyMCE.getAttrib(path[i], "size");
     757                                        if (size != "")
     758                                                nodeData += "size: " + size + " ";
     759
     760                                        var color = tinyMCE.getAttrib(path[i], "color");
     761                                        if (color != "")
     762                                                nodeData += "color: " + color + " ";
     763                                }
     764
     765                                if (getAttrib(path[i], 'id') != "") {
     766                                        nodeData += "id: " + path[i].getAttribute('id') + " ";
     767                                }
     768
     769                                var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false);
     770                                if (className != "" && className.indexOf('mceItem') == -1)
     771                                        nodeData += "class: " + className + " ";
     772
     773                                if (getAttrib(path[i], 'src') != "") {
     774                                        var src = tinyMCE.getAttrib(path[i], "mce_src");
     775
     776                                        if (src == "")
     777                                                 src = tinyMCE.getAttrib(path[i], "src");
     778
     779                                        nodeData += "src: " + src + " ";
     780                                }
     781
     782                                if (getAttrib(path[i], 'href') != "") {
     783                                        var href = tinyMCE.getAttrib(path[i], "mce_href");
     784
     785                                        if (href == "")
     786                                                 href = tinyMCE.getAttrib(path[i], "href");
     787
     788                                        nodeData += "href: " + href + " ";
     789                                }
     790
     791                                if (nodeName == "img" && tinyMCE.getAttrib(path[i], "class").indexOf('mceItemFlash') != -1) {
     792                                        nodeName = "flash";
     793                                        nodeData = "src: " + path[i].getAttribute('title');
     794                                }
     795
     796                                if (nodeName == "a" && (anchor = tinyMCE.getAttrib(path[i], "name")) != "") {
     797                                        nodeName = "a";
     798                                        nodeName += "#" + anchor;
     799                                        nodeData = "";
     800                                }
     801
     802                                if (getAttrib(path[i], 'name').indexOf("mce_") != 0) {
     803                                        var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false);
     804                                        if (className != "" && className.indexOf('mceItem') == -1) {
     805                                                nodeName += "." + className;
     806                                        }
     807                                }
     808
     809                                var cmd = 'tinyMCE.execInstanceCommand(\'' + editor_id + '\',\'mceSelectNodeDepth\',false,\'' + i + '\');';
     810                                html += '<a title="' + nodeData + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" target="_self" class="mcePathItem">' + nodeName + '</a>';
     811
     812                                if (i > 0) {
     813                                        html += " &raquo; ";
     814                                }
     815                        }
     816
     817                        pathElm.innerHTML = '<a href="#" accesskey="x"></a>' + tinyMCE.getLang('lang_theme_path') + ": " + html + '&nbsp;';
     818                }
     819
     820                // Reset old states
     821                tinyMCE.switchClass(editor_id + '_justifyleft', 'mceButtonNormal');
     822                tinyMCE.switchClass(editor_id + '_justifyright', 'mceButtonNormal');
     823                tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonNormal');
     824                tinyMCE.switchClass(editor_id + '_justifyfull', 'mceButtonNormal');
     825                tinyMCE.switchClass(editor_id + '_bold', 'mceButtonNormal');
     826                tinyMCE.switchClass(editor_id + '_italic', 'mceButtonNormal');
     827                tinyMCE.switchClass(editor_id + '_underline', 'mceButtonNormal');
     828                tinyMCE.switchClass(editor_id + '_strikethrough', 'mceButtonNormal');
     829                tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonNormal');
     830                tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonNormal');
     831                tinyMCE.switchClass(editor_id + '_sub', 'mceButtonNormal');
     832                tinyMCE.switchClass(editor_id + '_sup', 'mceButtonNormal');
     833                tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonNormal');
     834                tinyMCE.switchClass(editor_id + '_link', 'mceButtonDisabled');
     835                tinyMCE.switchClass(editor_id + '_unlink', 'mceButtonDisabled');
     836                tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonDisabled');
     837                tinyMCE.switchClass(editor_id + '_image', 'mceButtonNormal');
     838                tinyMCE.switchClass(editor_id + '_hr', 'mceButtonNormal');
     839
     840                if (node.nodeName == "A" && tinyMCE.getAttrib(node, "class").indexOf('mceItemAnchor') != -1)
     841                        tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonSelected');
     842
     843                // Get link
     844                var anchorLink = tinyMCE.getParentElement(node, "a", "href");
     845
     846                if (anchorLink || any_selection) {
     847                        tinyMCE.switchClass(editor_id + '_link', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal');
     848                        tinyMCE.switchClass(editor_id + '_unlink', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal');
     849                }
     850
     851                // Handle visual aid
     852                tinyMCE.switchClass(editor_id + '_visualaid', visual_aid ? 'mceButtonSelected' : 'mceButtonNormal');
     853
     854                if (undo_levels != -1) {
     855                        tinyMCE.switchClass(editor_id + '_undo', 'mceButtonDisabled');
     856                        tinyMCE.switchClass(editor_id + '_redo', 'mceButtonDisabled');
     857                }
     858
     859                // Within li, blockquote
     860                if (tinyMCE.getParentElement(node, "li,blockquote"))
     861                        tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonNormal');
     862
     863                // Has redo levels
     864                if (undo_index != -1 && (undo_index < undo_levels-1 && undo_levels > 0))
     865                        tinyMCE.switchClass(editor_id + '_redo', 'mceButtonNormal');
     866
     867                // Has undo levels
     868                if (undo_index != -1 && (undo_index > 0 && undo_levels > 0))
     869                        tinyMCE.switchClass(editor_id + '_undo', 'mceButtonNormal');
     870
     871                // Select class in select box
     872                var selectElm = document.getElementById(editor_id + "_styleSelect");
     873               
     874                if (selectElm) {
     875                        TinyMCE_AdvancedTheme._setupCSSClasses(editor_id);
     876
     877                        classNode = node;
     878                        breakOut = false;
     879                        var index = 0;
     880
     881                        do {
     882                                if (classNode && classNode.className) {
     883                                        for (var i=0; i<selectElm.options.length; i++) {
     884                                                if (selectElm.options[i].value == classNode.className) {
     885                                                        index = i;
     886                                                        breakOut = true;
     887                                                        break;
     888                                                }
     889                                        }
     890                                }
     891                        } while (!breakOut && classNode != null && (classNode = classNode.parentNode) != null);
     892
     893                        selectElm.selectedIndex = index;
     894                }
     895
     896                // Select formatblock
     897                var selectElm = document.getElementById(editor_id + "_formatSelect");
     898                if (selectElm) {
     899                        var elm = tinyMCE.getParentElement(node, "p,div,h1,h2,h3,h4,h5,h6,pre,address");
     900
     901                        if (elm)
     902                                selectByValue(selectElm, "<" + elm.nodeName.toLowerCase() + ">");
     903                        else
     904                                selectByValue(selectElm, "");
     905                }
     906
     907                // Select fontselect
     908                var selectElm = document.getElementById(editor_id + "_fontNameSelect");
     909                if (selectElm) {
     910                        if (!tinyMCE.isSafari && !(tinyMCE.isMSIE && !tinyMCE.isOpera)) {
     911                                var face = inst.queryCommandValue('FontName');
     912
     913                                face = face == null || face == "" ? "" : face;
     914
     915                                selectByValue(selectElm, face, face != "");
     916                        } else {
     917                                var elm = tinyMCE.getParentElement(node, "font", "face");
     918
     919                                if (elm) {
     920                                        var family = tinyMCE.getAttrib(elm, "face");
     921
     922                                        if (family == '')
     923                                                family = '' + elm.style.fontFamily;
     924
     925                                        if (!selectByValue(selectElm, family, family != ""))
     926                                                selectByValue(selectElm, "");
     927                                } else
     928                                        selectByValue(selectElm, "");
     929                        }
     930                }
     931
     932                // Select fontsize
     933                var selectElm = document.getElementById(editor_id + "_fontSizeSelect");
     934                if (selectElm) {
     935                        if (!tinyMCE.isSafari && !tinyMCE.isOpera) {
     936                                var size = inst.queryCommandValue('FontSize');
     937                                selectByValue(selectElm, size == null || size == "" ? "0" : size);
     938                        } else {
     939                                var elm = tinyMCE.getParentElement(node, "font", "size");
     940                                if (elm) {
     941                                        var size = tinyMCE.getAttrib(elm, "size");
     942
     943                                        if (size == '') {
     944                                                var sizes = new Array('', '8px', '10px', '12px', '14px', '18px', '24px', '36px');
     945
     946                                                size = '' + elm.style.fontSize;
     947
     948                                                for (var i=0; i<sizes.length; i++) {
     949                                                        if (('' + sizes[i]) == size) {
     950                                                                size = i;
     951                                                                break;
     952                                                        }
     953                                                }
     954                                        }
     955
     956                                        if (!selectByValue(selectElm, size))
     957                                                selectByValue(selectElm, "");
     958                                } else
     959                                        selectByValue(selectElm, "0");
     960                        }
     961                }
     962
     963                // Handle align attributes
     964                alignNode = node;
     965                breakOut = false;
     966                do {
     967                        if (!alignNode.getAttribute || !alignNode.getAttribute('align'))
     968                                continue;
     969
     970                        switch (alignNode.getAttribute('align').toLowerCase()) {
     971                                case "left":
     972                                        tinyMCE.switchClass(editor_id + '_justifyleft', 'mceButtonSelected');
     973                                        breakOut = true;
     974                                break;
     975
     976                                case "right":
     977                                        tinyMCE.switchClass(editor_id + '_justifyright', 'mceButtonSelected');
     978                                        breakOut = true;
     979                                break;
     980
     981                                case "middle":
     982                                case "center":
     983                                        tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonSelected');
     984                                        breakOut = true;
     985                                break;
     986
     987                                case "justify":
     988                                        tinyMCE.switchClass(editor_id + '_justifyfull', 'mceButtonSelected');
     989                                        breakOut = true;
     990                                break;
     991                        }
     992                } while (!breakOut && (alignNode = alignNode.parentNode) != null);
     993
     994                // Div justification
     995                var div = tinyMCE.getParentElement(node, "div");
     996                if (div && div.style.textAlign == "center")
     997                        tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonSelected');
     998
     999                // Do special text
     1000                if (!setup_content) {
     1001                        // , "JustifyLeft", "_justifyleft", "JustifyCenter", "justifycenter", "JustifyRight", "justifyright", "JustifyFull", "justifyfull", "InsertUnorderedList", "bullist", "InsertOrderedList", "numlist", "InsertUnorderedList", "bullist", "Outdent", "outdent", "Indent", "indent", "subscript", "sub"
     1002                        var ar = new Array("Bold", "_bold", "Italic", "_italic", "Strikethrough", "_strikethrough", "superscript", "_sup", "subscript", "_sub");
     1003                        for (var i=0; i<ar.length; i+=2) {
     1004                                if (inst.queryCommandState(ar[i]))
     1005                                        tinyMCE.switchClass(editor_id + ar[i+1], 'mceButtonSelected');
     1006                        }
     1007
     1008                        if (inst.queryCommandState("Underline") && (node.parentNode == null || node.parentNode.nodeName != "A"))
     1009                                tinyMCE.switchClass(editor_id + '_underline', 'mceButtonSelected');
     1010                }
     1011
     1012                // Handle elements
     1013                do {
     1014                        switch (node.nodeName) {
     1015                                case "UL":
     1016                                        tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonSelected');
     1017                                break;
     1018
     1019                                case "OL":
     1020                                        tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonSelected');
     1021                                break;
     1022
     1023                                case "HR":
     1024                                         tinyMCE.switchClass(editor_id + '_hr', 'mceButtonSelected');
     1025                                break;
     1026
     1027                                case "IMG":
     1028                                if (getAttrib(node, 'name').indexOf('mce_') != 0) {
     1029                                        tinyMCE.switchClass(editor_id + '_image', 'mceButtonSelected');
     1030                                }
     1031                                break;
     1032                        }
     1033                } while ((node = node.parentNode) != null);
     1034        },
     1035
     1036        // Private theme internal functions
     1037
     1038        // This function auto imports CSS classes into the class selection droplist
     1039        _setupCSSClasses : function(editor_id) {
     1040                var i, selectElm;
     1041
     1042                if (!TinyMCE_AdvancedTheme._autoImportCSSClasses)
     1043                        return;
     1044
     1045                selectElm = document.getElementById(editor_id + '_styleSelect');
     1046
     1047                if (selectElm && selectElm.getAttribute('cssImported') != 'true') {
     1048                        var csses = tinyMCE.getCSSClasses(editor_id);
     1049                        if (csses && selectElm) {
     1050                                for (i=0; i<csses.length; i++)
     1051                                        selectElm.options[selectElm.options.length] = new Option(csses[i], csses[i]);
     1052                        }
     1053
     1054                        // Only do this once
     1055                        if (csses != null && csses.length > 0)
     1056                                selectElm.setAttribute('cssImported', 'true');
     1057                }
     1058        },
     1059
     1060        _setCookie : function(name, value, expires, path, domain, secure) {
     1061                var curCookie = name + "=" + escape(value) +
     1062                        ((expires) ? "; expires=" + expires.toGMTString() : "") +
     1063                        ((path) ? "; path=" + escape(path) : "") +
     1064                        ((domain) ? "; domain=" + domain : "") +
     1065                        ((secure) ? "; secure" : "");
     1066
     1067                document.cookie = curCookie;
     1068        },
     1069
     1070        _getCookie : function(name) {
     1071                var dc = document.cookie;
     1072                var prefix = name + "=";
     1073                var begin = dc.indexOf("; " + prefix);
     1074
     1075                if (begin == -1) {
     1076                        begin = dc.indexOf(prefix);
     1077
     1078                        if (begin != 0)
     1079                                return null;
     1080                } else
     1081                        begin += 2;
     1082
     1083                var end = document.cookie.indexOf(";", begin);
     1084
     1085                if (end == -1)
     1086                        end = dc.length;
     1087
     1088                return unescape(dc.substring(begin + prefix.length, end));
     1089        },
     1090
     1091        _resizeTo : function(inst, w, h, set_w) {
     1092                var editorContainer = document.getElementById(inst.editorId + '_parent');
     1093                var tableElm = editorContainer.firstChild;
     1094                var iframe = inst.iframeElement;
     1095
     1096                if (w == null || w == "null") {
     1097                        set_w = false;
     1098                        w = 0;
     1099                }
     1100
     1101                if (h == null || h == "null")
     1102                        return;
     1103
     1104                w = parseInt(w);
     1105                h = parseInt(h);
     1106
     1107                if (tinyMCE.isGecko) {
     1108                        w += 2;
     1109                        h += 2;
     1110                }
     1111
     1112                var dx = w - tableElm.clientWidth;
     1113                var dy = h - tableElm.clientHeight;
     1114
     1115                w = w < 1 ? 30 : w;
     1116                h = h < 1 ? 30 : h;
     1117
     1118                if (set_w)
     1119                        tableElm.style.width = w + "px";
     1120
     1121                tableElm.style.height = h + "px";
     1122
     1123                iw = iframe.clientWidth + dx;
     1124                ih = iframe.clientHeight + dy;
     1125
     1126                iw = iw < 1 ? 30 : iw;
     1127                ih = ih < 1 ? 30 : ih;
     1128
     1129                if (tinyMCE.isGecko) {
     1130                        iw -= 2;
     1131                        ih -= 2;
     1132                }
     1133
     1134                if (set_w)
     1135                        iframe.style.width = iw + "px";
     1136
     1137                iframe.style.height = ih + "px";
     1138
     1139                // Is it to small, make it bigger again
     1140                if (set_w) {
     1141                        var tableBodyElm = tableElm.firstChild;
     1142                        var minIframeWidth = tableBodyElm.scrollWidth;
     1143                        if (inst.iframeElement.clientWidth < minIframeWidth) {
     1144                                dx = minIframeWidth - inst.iframeElement.clientWidth;
     1145
     1146                                inst.iframeElement.style.width = (iw + dx) + "px";
     1147                        }
     1148                }
     1149        },
     1150
     1151        /**
     1152         * Handles resizing events.
     1153         */
     1154        _resizeEventHandler : function(e) {
     1155                var resizer = TinyMCE_AdvancedTheme._resizer;
     1156
     1157                // Do nothing
     1158                if (!resizer.resizing)
     1159                        return;
     1160
     1161                e = typeof(e) == "undefined" ? window.event : e;
     1162
     1163                var dx = e.screenX - resizer.downX;
     1164                var dy = e.screenY - resizer.downY;
     1165                var resizeBox = resizer.resizeBox;
     1166                var editorId = resizer.editorId;
     1167
     1168                switch (e.type) {
     1169                        case "mousemove":
     1170                                var w, h;
     1171
     1172                                w = resizer.width + dx;
     1173                                h = resizer.height + dy;
     1174
     1175                                w = w < 1 ? 1 : w;
     1176                                h = h < 1 ? 1 : h;
     1177
     1178                                if (resizer.horizontal)
     1179                                        resizeBox.style.width = w + "px";
     1180
     1181                                resizeBox.style.height = h + "px";
     1182                                break;
     1183
     1184                        case "mouseup":
     1185                                TinyMCE_AdvancedTheme._setResizing(e, editorId, false);
     1186                                TinyMCE_AdvancedTheme._resizeTo(tinyMCE.getInstanceById(editorId), resizer.width + dx, resizer.height + dy, resizer.horizontal);
     1187
     1188                                // Expire in a month
     1189                                if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) {
     1190                                        var expires = new Date();
     1191                                        expires.setTime(expires.getTime() + 3600000 * 24 * 30);
     1192
     1193                                        // Set the cookies
     1194                                        TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_width", "" + (resizer.horizontal ? resizer.width + dx : ""), expires);
     1195                                        TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_height", "" + (resizer.height + dy), expires);
     1196                                }
     1197                                break;
     1198                }
     1199        },
     1200
     1201        /**
     1202         * Starts/stops the editor resizing.
     1203         */
     1204        _setResizing : function(e, editor_id, state) {
     1205                e = typeof(e) == "undefined" ? window.event : e;
     1206
     1207                var resizer = TinyMCE_AdvancedTheme._resizer;
     1208                var editorContainer = document.getElementById(editor_id + '_parent');
     1209                var editorArea = document.getElementById(editor_id + '_parent').firstChild;
     1210                var resizeBox = document.getElementById(editor_id + '_resize_box');
     1211                var inst = tinyMCE.getInstanceById(editor_id);
     1212
     1213                if (state) {
     1214                        // Place box over editor area
     1215                        var width = editorArea.clientWidth;
     1216                        var height = editorArea.clientHeight;
     1217
     1218                        resizeBox.style.width = width + "px";
     1219                        resizeBox.style.height = height + "px";
     1220
     1221                        resizer.iframeWidth = inst.iframeElement.clientWidth;
     1222                        resizer.iframeHeight = inst.iframeElement.clientHeight;
     1223
     1224                        // Hide editor and show resize box
     1225                        editorArea.style.display = "none";
     1226                        resizeBox.style.display = "block";
     1227
     1228                        // Add event handlers, only once
     1229                        if (!resizer.eventHandlers) {
     1230                                if (tinyMCE.isMSIE)
     1231                                        tinyMCE.addEvent(document, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler);
     1232                                else
     1233                                        tinyMCE.addEvent(window, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler);
     1234
     1235                                tinyMCE.addEvent(document, "mouseup", TinyMCE_AdvancedTheme._resizeEventHandler);
     1236
     1237                                resizer.eventHandlers = true;
     1238                        }
     1239
     1240                        resizer.resizing = true;
     1241                        resizer.downX = e.screenX;
     1242                        resizer.downY = e.screenY;
     1243                        resizer.width = parseInt(resizeBox.style.width);
     1244                        resizer.height = parseInt(resizeBox.style.height);
     1245                        resizer.editorId = editor_id;
     1246                        resizer.resizeBox = resizeBox;
     1247                        resizer.horizontal = tinyMCE.getParam("theme_advanced_resize_horizontal", true);
     1248                } else {
     1249                        resizer.resizing = false;
     1250                        resizeBox.style.display = "none";
     1251                        editorArea.style.display = tinyMCE.isMSIE && !tinyMCE.isOpera ? "block" : "table";
     1252                        tinyMCE.execCommand('mceResetDesignMode');
     1253                }
     1254        },
     1255
     1256        _insertImage : function(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout) {
     1257                tinyMCE.execCommand('mceBeginUndoLevel');
     1258
     1259                if (src == "")
     1260                        return;
     1261
     1262                if (!tinyMCE.imgElement && tinyMCE.isSafari) {
     1263                        var html = "";
     1264
     1265                        html += '<img src="' + src + '" alt="' + alt + '"';
     1266                        html += ' border="' + border + '" hspace="' + hspace + '"';
     1267                        html += ' vspace="' + vspace + '" width="' + width + '"';
     1268                        html += ' height="' + height + '" align="' + align + '" title="' + title + '" onmouseover="' + onmouseover + '" onmouseout="' + onmouseout + '" />';
     1269
     1270                        tinyMCE.execCommand("mceInsertContent", false, html);
     1271                } else {
     1272                        if (!tinyMCE.imgElement && tinyMCE.selectedInstance) {
     1273                                if (tinyMCE.isSafari)
     1274                                        tinyMCE.execCommand("mceInsertContent", false, '<img src="' + tinyMCE.uniqueURL + '" />');
     1275                                else
     1276                                        tinyMCE.selectedInstance.contentDocument.execCommand("insertimage", false, tinyMCE.uniqueURL);
     1277
     1278                                tinyMCE.imgElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "img", "src", tinyMCE.uniqueURL);
     1279                        }
     1280                }
     1281
     1282                if (tinyMCE.imgElement) {
     1283                        var needsRepaint = false;
     1284                        var msrc = src;
     1285
     1286                        src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, tinyMCE.imgElement);");
     1287
     1288                        if (tinyMCE.getParam('convert_urls'))
     1289                                msrc = src;
     1290
     1291                        if (onmouseover && onmouseover != "")
     1292                                onmouseover = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, tinyMCE.imgElement);") + "';";
     1293
     1294                        if (onmouseout && onmouseout != "")
     1295                                onmouseout = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, tinyMCE.imgElement);") + "';";
     1296
     1297                        // Use alt as title if it's undefined
     1298                        if (typeof(title) == "undefined")
     1299                                title = alt;
     1300
     1301                        if (width != tinyMCE.imgElement.getAttribute("width") || height != tinyMCE.imgElement.getAttribute("height") || align != tinyMCE.imgElement.getAttribute("align"))
     1302                                needsRepaint = true;
     1303
     1304                        tinyMCE.setAttrib(tinyMCE.imgElement, 'src', src);
     1305                        tinyMCE.setAttrib(tinyMCE.imgElement, 'mce_src', msrc);
     1306                        tinyMCE.setAttrib(tinyMCE.imgElement, 'alt', alt);
     1307                        tinyMCE.setAttrib(tinyMCE.imgElement, 'title', title);
     1308                        tinyMCE.setAttrib(tinyMCE.imgElement, 'align', align);
     1309                        tinyMCE.setAttrib(tinyMCE.imgElement, 'border', border, true);
     1310                        tinyMCE.setAttrib(tinyMCE.imgElement, 'hspace', hspace, true);
     1311                        tinyMCE.setAttrib(tinyMCE.imgElement, 'vspace', vspace, true);
     1312                        tinyMCE.setAttrib(tinyMCE.imgElement, 'width', width, true);
     1313                        tinyMCE.setAttrib(tinyMCE.imgElement, 'height', height, true);
     1314                        tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseover', onmouseover);
     1315                        tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseout', onmouseout);
     1316
     1317                        // Fix for bug #989846 - Image resize bug
     1318                        if (width && width != "")
     1319                                tinyMCE.imgElement.style.pixelWidth = width;
     1320
     1321                        if (height && height != "")
     1322                                tinyMCE.imgElement.style.pixelHeight = height;
     1323
     1324                        if (needsRepaint)
     1325                                tinyMCE.selectedInstance.repaint();
     1326                }
     1327
     1328                tinyMCE.execCommand('mceEndUndoLevel');
     1329        },
     1330
     1331        _insertLink : function(href, target, title, onclick, style_class) {
     1332                tinyMCE.execCommand('mceBeginUndoLevel');
     1333
     1334                if (tinyMCE.selectedInstance && tinyMCE.selectedElement && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") {
     1335                        var doc = tinyMCE.selectedInstance.getDoc();
     1336                        var linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
     1337                        var newLink = false;
     1338
     1339                        if (!linkElement) {
     1340                                linkElement = doc.createElement("a");
     1341                                newLink = true;
     1342                        }
     1343
     1344                        var mhref = href;
     1345                        var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);");
     1346                        mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
     1347
     1348                        tinyMCE.setAttrib(linkElement, 'href', thref);
     1349                        tinyMCE.setAttrib(linkElement, 'mce_href', mhref);
     1350                        tinyMCE.setAttrib(linkElement, 'target', target);
     1351                        tinyMCE.setAttrib(linkElement, 'title', title);
     1352                        tinyMCE.setAttrib(linkElement, 'onclick', onclick);
     1353                        tinyMCE.setAttrib(linkElement, 'class', style_class);
     1354
     1355                        if (newLink) {
     1356                                linkElement.appendChild(tinyMCE.selectedElement.cloneNode(true));
     1357                                tinyMCE.selectedElement.parentNode.replaceChild(linkElement, tinyMCE.selectedElement);
     1358                        }
     1359
     1360                        return;
     1361                }
     1362
     1363                if (!tinyMCE.linkElement && tinyMCE.selectedInstance) {
     1364                        if (tinyMCE.isSafari) {
     1365                                tinyMCE.execCommand("mceInsertContent", false, '<a href="' + tinyMCE.uniqueURL + '">' + tinyMCE.selectedInstance.selection.getSelectedHTML() + '</a>');
     1366                        } else
     1367                                tinyMCE.selectedInstance.contentDocument.execCommand("createlink", false, tinyMCE.uniqueURL);
     1368
     1369                        tinyMCE.linkElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
     1370
     1371                        var elementArray = tinyMCE.getElementsByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
     1372
     1373                        for (var i=0; i<elementArray.length; i++) {
     1374                                var mhref = href;
     1375                                var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, elementArray[i]);");
     1376                                mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
     1377
     1378                                tinyMCE.setAttrib(elementArray[i], 'href', thref);
     1379                                tinyMCE.setAttrib(elementArray[i], 'mce_href', mhref);
     1380                                tinyMCE.setAttrib(elementArray[i], 'target', target);
     1381                                tinyMCE.setAttrib(elementArray[i], 'title', title);
     1382                                tinyMCE.setAttrib(elementArray[i], 'onclick', onclick);
     1383                                tinyMCE.setAttrib(elementArray[i], 'class', style_class);
     1384                        }
     1385
     1386                        tinyMCE.linkElement = elementArray[0];
     1387                }
     1388
     1389                if (tinyMCE.linkElement) {
     1390                        var mhref = href;
     1391                        href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement);");
     1392                        mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
     1393
     1394                        tinyMCE.setAttrib(tinyMCE.linkElement, 'href', href);
     1395                        tinyMCE.setAttrib(tinyMCE.linkElement, 'mce_href', mhref);
     1396                        tinyMCE.setAttrib(tinyMCE.linkElement, 'target', target);
     1397                        tinyMCE.setAttrib(tinyMCE.linkElement, 'title', title);
     1398                        tinyMCE.setAttrib(tinyMCE.linkElement, 'onclick', onclick);
     1399                        tinyMCE.setAttrib(tinyMCE.linkElement, 'class', style_class);
     1400                }
     1401
     1402                tinyMCE.execCommand('mceEndUndoLevel');
     1403        }
     1404};
     1405
     1406tinyMCE.addTheme("advanced", TinyMCE_AdvancedTheme);
     1407
     1408// Add default buttons maps for advanced theme and all internal plugins
     1409tinyMCE.addButtonMap(TinyMCE_AdvancedTheme._buttonMap);
  • trunk/wp-includes/js/tinymce/themes/advanced/image.htm

    r3163 r3664  
    33        <title>{$lang_insert_image_title}</title>
    44        <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
     5        <script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
    56        <script language="javascript" type="text/javascript" src="../../utils/form_utils.js"></script>
    67        <script language="javascript" type="text/javascript" src="jscripts/image.js"></script>
    7         <style type="text/css">
    8                 #insert, #cancel {
    9                         font: 13px Verdana, Arial, Helvetica, sans-serif;
    10                         height:auto;
    11                         width: auto;
    12                         background-color: transparent;
    13                         background-image: url(../../../../../wp-admin/images/fade-butt.png);
    14                         background-repeat: repeat;
    15                         border: 3px double;
    16                         border-right-color: rgb(153, 153, 153);
    17                         border-bottom-color: rgb(153, 153, 153);
    18                         border-left-color: rgb(204, 204, 204);
    19                         border-top-color: rgb(204, 204, 204);
    20                         color: rgb(51, 51, 51);
    21                         padding: 0.25em 1em;
    22                 }
    23                 #insert:active, #cancel:active {
    24                         background: #f4f4f4;
    25                         border-left-color: #999;
    26                         border-top-color: #999;
    27                 }
    28         </style>
     8        <base target="_self" />
    299</head>
    30 <body onload="tinyMCEPopup.executeOnLoad('init();');document.getElementById('src').focus();" style="display: none">
    31 <form onsubmit="insertImage();return false;">
    32   <table border="0" cellpadding="0" cellspacing="0" width="200">
    33     <tr>
    34       <td align="center" valign="middle"><table border="0" cellpadding="4" cellspacing="0">
     10<body id="image" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('src').focus();" style="display: none">
     11<form onsubmit="insertImage();return false;" action="#">
     12        <div class="tabs">
     13                <ul>
     14                        <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{$lang_insert_image_title}</a></span></li>
     15                </ul>
     16        </div>
     17
     18        <div class="panel_wrapper">
     19                <div id="general_panel" class="panel current">
     20     <table border="0" cellpadding="4" cellspacing="0">
    3521          <tr>
    36             <td colspan="2" class="title" nowrap="nowrap">{$lang_insert_image_title}</td>
    37           </tr>
    38           <tr>
    39             <td nowrap="nowrap">{$lang_insert_image_src}:</td>
     22            <td nowrap="nowrap"><label for="src">{$lang_insert_image_src}</label></td>
    4023            <td><table border="0" cellspacing="0" cellpadding="0">
    4124                <tr>
    42                   <td><input name="src" type="text" id="src" value="" style="width: 200px" onchange="getImageData();"></td>
     25                  <td><input id="src" name="src" type="text" value="" style="width: 200px" onchange="getImageData();"></td>
    4326                  <td id="srcbrowsercontainer">&nbsp;</td>
    4427                </tr>
    … …  
    5033                                var html = "";
    5134
    52                                 html += '<tr><td>{$lang_image_list}:</td>';
    53                                 html += '<td><select name="image_list" style="width: 200px" onchange="this.form.src.value=this.options[this.selectedIndex].value;resetImageData();getImageData();">';
     35                                html += '<tr><td><label for="image_list">{$lang_image_list}</label></td>';
     36                                html += '<td><select id="image_list" name="image_list" style="width: 200px" onchange="this.form.src.value=this.options[this.selectedIndex].value;resetImageData();getImageData();">';
    5437                                html += '<option value="">---</option>';
    5538
    … …  
    6447                  <!-- /Image list -->
    6548          <tr>
    66             <td nowrap="nowrap">{$lang_insert_image_alt}:</td>
    67             <td><input name="alt" type="text" id="alt" value="" style="width: 200px"></td>
     49            <td nowrap="nowrap"><label for="alt">{$lang_insert_image_alt}</label></td>
     50            <td><input id="alt" name="alt" type="text" value="" style="width: 200px"></td>
    6851          </tr>
    6952          <tr>
    70             <td nowrap="nowrap">{$lang_insert_image_align}:</td>
    71             <td><select name="align">
     53            <td nowrap="nowrap"><label for="align">{$lang_insert_image_align}</label></td>
     54            <td><select id="align" name="align">
    7255                <option value="">{$lang_insert_image_align_default}</option>
    7356                <option value="baseline">{$lang_insert_image_align_baseline}</option>
    … …  
    8366          </tr>
    8467          <tr>
    85             <td nowrap="nowrap"><!--{$lang_insert_image_dimensions}:</td>
    86             <td><input name="width" type="text" id="width" value="" size="3" maxlength="3">
     68            <td nowrap="nowrap"><label for="width">{$lang_insert_image_dimensions}</label></td>
     69            <td><input id="width" name="width" type="text" value="" size="3" maxlength="3">
    8770              x
    88               <input name="height" type="text" id="height" value="" size="3" maxlength="3">--></td>
    89           </tr>
    90 <!--          <tr>
    91             <td nowrap="nowrap">{$lang_insert_image_border}:</td>
    92             <td><input name="border" type="text" id="border" value="" size="3" maxlength="3"></td>
     71              <input id="height" name="height" type="text" value="" size="3" maxlength="3"></td>
    9372          </tr>
    9473          <tr>
    95             <td nowrap="nowrap">{$lang_insert_image_vspace}:</td>
    96             <td><input name="vspace" type="text" id="vspace" value="" size="3" maxlength="3"></td>
     74            <td nowrap="nowrap"><label for="border">{$lang_insert_image_border}</label></td>
     75            <td><input id="border" name="border" type="text" value="" size="3" maxlength="3"></td>
    9776          </tr>
    9877          <tr>
    99             <td nowrap="nowrap">{$lang_insert_image_hspace}:</td>
    100             <td><input name="hspace" type="text" id="hspace" value="" size="3" maxlength="3"></td>
     78            <td nowrap="nowrap"><label for="vspace">{$lang_insert_image_vspace}</label></td>
     79            <td><input id="vspace" name="vspace" type="text" value="" size="3" maxlength="3"></td>
    10180          </tr>
    102 -->          <tr>
    103             <td nowrap="nowrap"><input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertImage();">
    104             </td>
    105             <td align="right"><input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();"></td>
     81          <tr>
     82            <td nowrap="nowrap"><label for="hspace">{$lang_insert_image_hspace}</label></td>
     83            <td><input id="hspace" name="hspace" type="text" value="" size="3" maxlength="3"></td>
    10684          </tr>
    107         </table></td>
    108     </tr>
    109   </table>
     85        </table>
     86                </div>
     87        </div>
     88
     89        <div class="mceActionPanel">
     90                <div style="float: left">
     91                        <input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />
     92                </div>
     93
     94                <div style="float: right">
     95                        <input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertImage();" />
     96                </div>
     97        </div>
    11098</form>
    11199</body>
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/about.js

    r3062 r3664  
    11function init() {
     2        var inst;
     3
    24        tinyMCEPopup.resizeToInnerSize();
     5        inst = tinyMCE.selectedInstance;
    36
    47        // Give FF some time
    … …  
    2124        html += '<tbody>';
    2225
    23         for (var i=0; i<plugins.length; i++) {
    24                 var info = getPluginInfo(plugins[i]);
     26        for (var i=0; i<inst.plugins.length; i++) {
     27                var info = getPluginInfo(inst.plugins[i]);
    2528
    2629                html += '<tr>';
    … …  
    4750
    4851function getPluginInfo(name) {
    49         var fn = eval('tinyMCEPopup.windowOpener.TinyMCE_' + name + '_getInfo');
    50 
    51         if (typeof(fn) != 'undefined')
    52                 return fn();
     52        if (tinyMCE.plugins[name].getInfo)
     53                return tinyMCE.plugins[name].getInfo();
    5354
    5455        return {
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/anchor.js

    r3062 r3664  
    2727function insertAnchor() {
    2828        var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id'));
    29         var name = document.forms[0].anchorName.value;
     29        var name = document.forms[0].anchorName.value, e;
    3030
    3131        tinyMCEPopup.execCommand("mceBeginUndoLevel");
    … …  
    4545                name = name.replace(/\"/g, '&quot;');
    4646                name = name.replace(/</g, '&lt;');
    47                 name = name.replace(/>/g, '&gr;');
     47                name = name.replace(/>/g, '&gt;');
    4848
    49                 html = '<a name="' + name + '"></a>';
     49                // Fix for bug #1447335
     50                if (tinyMCE.isGecko)
     51                        html = '<a id="mceNewAnchor" name="' + name + '"></a>';
     52                else
     53                        html = '<a name="' + name + '"></a>';
    5054
    5155                tinyMCEPopup.execCommand("mceInsertContent", false, html);
     56
     57                // Fix for bug #1447335 force cursor after the anchor element
     58                if (tinyMCE.isGecko) {
     59                        e = inst.getDoc().getElementById('mceNewAnchor');
     60
     61                        if (e) {
     62                                inst.selection.selectNode(e, true, false, false);
     63                                e.removeAttribute('id');
     64                        }
     65                }
     66
    5267                tinyMCE.handleVisualAid(inst.getBody(), true, inst.visualAid, inst);
    5368        }
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/charmap.js

    r3062 r3664  
    171171        ['&thorn;',   '&#254;',  true, 'thorn'],
    172172        ['&yuml;',    '&#255;',  true, 'y - diaeresis'],
    173 // ['&Alpha;',   '&#913;',  true, 'Alpha'],
     173    ['&Alpha;',   '&#913;',  true, 'Alpha'],
    174174        ['&Beta;',    '&#914;',  true, 'Beta'],
    175175        ['&Gamma;',   '&#915;',  true, 'Gamma'],
    … …  
    280280                        html += ''
    281281                                + '<td width="' + tdWidth + '" height="' + tdHeight + '" class="charmap"'
    282                                 + ' onmouseover="tinyMCE.switchClass(this,\'charmapOver\');'
     282                                + ' onmouseover="this.className=\'charmapOver\';'
    283283                                + 'previewChar(\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\',\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\',\'' + charmap[i][3] + '\');"'
    284                                 + ' onmouseout="tinyMCE.restoreClass(this,\'charmapOver\');"'
     284                                + ' onmouseout="this.className=\'charmap\';"'
    285285                                + ' nowrap="nowrap" onclick="insertChar(\'' + charmap[i][1].substring(2,charmap[i][1].length-1) + '\');"><a style="text-decoration: none;" onfocus="previewChar(\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\',\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\',\'' + charmap[i][3] + '\');" href="javascript:insertChar(\'' + charmap[i][1].substring(2,charmap[i][1].length-1) + '\');" onclick="return false;" onmousedown="return false;" title="' + charmap[i][3] + '">'
    286286                                + charmap[i][1]
    … …  
    300300
    301301function insertChar(chr) {
    302         tinyMCEPopup.execCommand('mceInsertContent', false, '\&#' + chr + ';');
     302        tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';');
    303303
    304304        // Refocus in window
    305305        if (tinyMCEPopup.isWindow)
    306306                window.focus();
     307
     308        tinyMCEPopup.close();
    307309}
    308310
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/color_picker.js

    r3062 r3664  
    100100                + '</td></tr>'
    101101                + '</table>'
    102                 + '<input type="button" id="insert" name="insert" value="{$lang_theme_colorpicker_apply}" style="margin-top:3px" onclick="selectColor();">'
     102                + '<div style="float: left"><input type="button" id="insert" name="insert" value="{$lang_theme_colorpicker_apply}" style="margin-top:3px" onclick="selectColor();"></div>'
     103                + '<div style="float: right"><input type="button" name="cancel" value="{$lang_cancel}" style="margin-top:3px" onclick="tinyMCEPopup.close();" id="cancel" /></div>'
    103104                + '</td></tr>'
    104105                + '</table>';
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/image.js

    r3517 r3664  
    99
    1010function insertImage() {
    11         if (window.opener) {
    12                 var src = document.forms[0].src.value;
    13                 var alt = document.forms[0].alt.value;
    14                 var border = '';//document.forms[0].border.value;
    15                 var vspace = '';//document.forms[0].vspace.value;
    16                 var hspace = '';//document.forms[0].hspace.value;
    17                 var width = '';//document.forms[0].width.value;
    18                 var height = '';//document.forms[0].height.value;
    19                 var align = document.forms[0].align.options[document.forms[0].align.selectedIndex].value;
     11        var src = document.forms[0].src.value;
     12        var alt = document.forms[0].alt.value;
     13        var border = document.forms[0].border.value;
     14        var vspace = document.forms[0].vspace.value;
     15        var hspace = document.forms[0].hspace.value;
     16        var width = document.forms[0].width.value;
     17        var height = document.forms[0].height.value;
     18        var align = document.forms[0].align.options[document.forms[0].align.selectedIndex].value;
    2019
    21                 window.opener.tinyMCE.insertImage(src, alt, border, hspace, vspace, width, height, align);
    22                 top.close();
    23         }
     20        tinyMCEPopup.restoreSelection();
     21        tinyMCE.themes['advanced']._insertImage(src, alt, border, hspace, vspace, width, height, align);
     22        tinyMCEPopup.close();
    2423}
    2524
    … …  
    3837        formObj.src.value = tinyMCE.getWindowArg('src');
    3938        formObj.alt.value = tinyMCE.getWindowArg('alt');
    40 //      formObj.border.value = tinyMCE.getWindowArg('border');
    41 //      formObj.vspace.value = tinyMCE.getWindowArg('vspace');
    42 //      formObj.hspace.value = tinyMCE.getWindowArg('hspace');
    43 //      formObj.width.value = tinyMCE.getWindowArg('width');
    44 //      formObj.height.value = tinyMCE.getWindowArg('height');
     39        formObj.border.value = tinyMCE.getWindowArg('border');
     40        formObj.vspace.value = tinyMCE.getWindowArg('vspace');
     41        formObj.hspace.value = tinyMCE.getWindowArg('hspace');
     42        formObj.width.value = tinyMCE.getWindowArg('width');
     43        formObj.height.value = tinyMCE.getWindowArg('height');
    4544        formObj.insert.value = tinyMCE.getLang('lang_' + tinyMCE.getWindowArg('action'), 'Insert', true);
    4645
    … …  
    6261function resetImageData() {
    6362        var formObj = document.forms[0];
    64         formObj.width.value = formObj.height.value = "";
     63        formObj.width.value = formObj.height.value = "";       
    6564}
    6665
    … …  
    6867        var formObj = document.forms[0];
    6968
    70 //      if (formObj.width.value == "")
    71 //              formObj.width.value = preloadImg.width;
     69        if (formObj.width.value == "")
     70                formObj.width.value = preloadImg.width;
    7271
    73 //      if (formObj.height.value == "")
    74 //              formObj.height.value = preloadImg.height;
     72        if (formObj.height.value == "")
     73                formObj.height.value = preloadImg.height;
    7574}
    7675
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/link.js

    r3163 r3664  
    1111        tinyMCEPopup.resizeToInnerSize();
    1212
    13 //      document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','theme_advanced_link');
     13        document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','theme_advanced_link');
     14
     15        // Handle file browser
     16        if (isVisible('hrefbrowser'))
     17                document.getElementById('href').style.width = '180px';
    1418
    1519        var formObj = document.forms[0];
    … …  
    2630        document.forms[0].insert.value = tinyMCE.getLang('lang_' + tinyMCE.getWindowArg('action'), 'Insert', true);
    2731
    28 //      addClassesToList('styleSelect', 'theme_advanced_link_styles');
    29 //      selectByValue(formObj, 'styleSelect', tinyMCE.getWindowArg('className'), true);
     32        addClassesToList('styleSelect', 'theme_advanced_link_styles');
     33        selectByValue(formObj, 'styleSelect', tinyMCE.getWindowArg('className'), true);
    3034
    31         // Handle file browser
    32         if (isVisible('hrefbrowser'))
    33                 document.getElementById('href').style.width = '180px';
     35        // Hide css select row if no CSS classes
     36        if (formObj.styleSelect && formObj.styleSelect.options.length <= 1) {
     37                var sr = document.getElementById('styleSelectRow');
     38                sr.style.display = 'none';
     39                sr.parentNode.removeChild(sr);
     40        }
    3441
    3542        // Auto select link in list
    … …  
    4552
    4653function insertLink() {
    47         if (window.opener) {
    48                 var href = document.forms[0].href.value;
    49                 var target = document.forms[0].target.options[document.forms[0].target.selectedIndex].value;
    50                 var title = document.forms[0].linktitle.value;
    51                 var style_class = '';//document.forms[0].styleSelect.value;
    52                 var dummy;
     54        var href = document.forms[0].href.value;
     55        var target = document.forms[0].target.options[document.forms[0].target.selectedIndex].value;
     56        var title = document.forms[0].linktitle.value;
     57        var style_class = document.forms[0].styleSelect ? document.forms[0].styleSelect.value : "";
     58        var dummy;
    5359
    54                 // Make anchors absolute
    55                 if (href.charAt(0) == '#')
    56                         href = tinyMCE.settings['document_base_url'] + href;
     60        // Make anchors absolute
     61        if (href.charAt(0) == '#')
     62                href = tinyMCE.settings['document_base_url'] + href;
    5763
    58                 if (target == '_self')
    59                         target = '';
     64        if (target == '_self')
     65                target = '';
    6066
    61                 window.opener.tinyMCE.insertLink(href, target, title, dummy, style_class);
    62                 tinyMCEPopup.close();
    63         }
     67        tinyMCEPopup.restoreSelection();
     68        tinyMCE.themes['advanced']._insertLink(href, target, title, dummy, style_class);
     69        tinyMCEPopup.close();
    6470}
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/source_editor.js

    r3136 r3664  
    66// Fixes some charcode issues
    77function fixContent(html) {
    8         // WP
    9         return html;
    10 
    11         html = html.replace(new RegExp('<(p|hr|table|tr|td|ol|ul|object|embed|li|blockquote)', 'gi'),'\n<$1');
     8/*      html = html.replace(new RegExp('<(p|hr|table|tr|td|ol|ul|object|embed|li|blockquote)', 'gi'),'\n<$1');
    129        html = html.replace(new RegExp('<\/(p|ol|ul|li|table|tr|td|blockquote|object)>', 'gi'),'</$1>\n');
    1310        html = tinyMCE.regexpReplace(html, '<br />','<br />\n','gi');
    14         html = tinyMCE.regexpReplace(html, '\n\n','\n','gi');
     11        html = tinyMCE.regexpReplace(html, '\n\n','\n','gi');*/
    1512        return html;
    1613}
    … …  
    2118        document.forms[0].htmlSource.value = fixContent(tinyMCE.getContent(tinyMCE.getWindowArg('editor_id')));
    2219        resizeInputs();
    23         setWrap('off');
    2420}
    2521
    2622function setWrap(val) {
    27         // hard soft off
    28         document.forms[0].htmlSource.wrap = val;
     23        var s = document.forms[0].htmlSource;
     24
     25        s.wrap = val;
     26
     27        if (tinyMCE.isGecko) {
     28                var v = s.value;
     29                var n = s.cloneNode(false);
     30                n.setAttribute("wrap", val);
     31                s.parentNode.replaceChild(n, s);
     32                n.value = v;
     33        }
    2934}
    3035
    … …  
    5257
    5358function renderWordWrap() {
    54         if (tinyMCE.isMSIE)
     59        if (tinyMCE.isMSIE || tinyMCE.isGecko)
    5560                document.write('<input type="checkbox" name="wraped" id="wraped" onclick="toggleWordWrap(this);" class="wordWrapCode" /><label for="wraped">{$lang_theme_code_wordwrap}</label>');
    5661}
  • trunk/wp-includes/js/tinymce/themes/advanced/langs/en.js

    r3163 r3664  
    33tinyMCE.addToLang('',{
    44theme_style_select : '-- Styles --',
    5 theme_code_desc : 'Edit HTML Source (Alt+e)',
     5theme_code_desc : 'Edit HTML Source',
    66theme_code_title : 'HTML Source Editor',
    77theme_code_wordwrap : 'Word wrap',
  • trunk/wp-includes/js/tinymce/themes/advanced/link.htm

    r3163 r3664  
    33        <title>{$lang_insert_link_title}</title>
    44        <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
     5        <script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
    56        <script language="javascript" type="text/javascript" src="../../utils/form_utils.js"></script>
    67        <script language="javascript" type="text/javascript" src="jscripts/link.js"></script>
    7         <style type="text/css">
    8                 #insert, #cancel {
    9                         font: 13px Verdana, Arial, Helvetica, sans-serif;
    10                         height: auto;
    11                         width: auto;
    12                         background-color: transparent;
    13                         background-image: url(../../../../../wp-admin/images/fade-butt.png);
    14                         background-repeat: repeat;
    15                         border: 3px double;
    16                         border-right-color: rgb(153, 153, 153);
    17                         border-bottom-color: rgb(153, 153, 153);
    18                         border-left-color: rgb(204, 204, 204);
    19                         border-top-color: rgb(204, 204, 204);
    20                         color: rgb(51, 51, 51);
    21                         padding: 0.25em 0.75em;
    22                 }
    23                 #insert:active, #cancel:active {
    24                         background: #f4f4f4;
    25                         border-left-color: #999;
    26                         border-top-color: #999;
    27                 }
    28         </style>
     8        <base target="_self" />
    299</head>
    30 <body onload="tinyMCEPopup.executeOnLoad('init();');document.getElementById('href').focus();" style="display: none">
    31 <form onsubmit="insertLink();return false;">
    32   <table border="0" cellpadding="0" cellspacing="0" width="100">
    33     <tr>
    34       <td align="center" valign="middle"><table border="0" cellpadding="4" cellspacing="0">
     10<body id="link" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('href').focus();" style="display: none">
     11<form onsubmit="insertLink();return false;" action="#">
     12        <div class="tabs">
     13                <ul>
     14                        <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{$lang_insert_link_title}</a></span></li>
     15                </ul>
     16        </div>
     17
     18        <div class="panel_wrapper">
     19                <div id="general_panel" class="panel current">
     20
     21                <table border="0" cellpadding="4" cellspacing="0">
    3522          <tr>
    36             <td colspan="2" class="title" nowrap="nowrap">{$lang_insert_link_title}</td>
    37           </tr>
    38           <tr>
    39             <td nowrap="nowrap">{$lang_insert_link_url}:</td>
    40             <td>              <table border="0" cellspacing="0" cellpadding="0">
    41                 <tr>
    42                   <td><input name="href" type="text" id="href" value="" style="width: 200px"></td>
    43                   <td id="hrefbrowsercontainer">&nbsp;</td>
    44                 </tr>
    45               </table></td>
     23            <td nowrap="nowrap"><label for="href">{$lang_insert_link_url}</label></td>
     24            <td><table border="0" cellspacing="0" cellpadding="0">
     25                                  <tr>
     26                                        <td><input id="href" name="href" type="text" value="" style="width: 200px" /></td>
     27                                        <td id="hrefbrowsercontainer">&nbsp;</td>
     28                                  </tr>
     29                                </table></td>
    4630          </tr>
    4731                  <!-- Link list -->
    … …  
    5034                                var html = "";
    5135
    52                                 html += '<tr><td>{$lang_link_list}:</td>';
    53                                 html += '<td><select name="link_list" style="width: 200px" onchange="this.form.href.value=this.options[this.selectedIndex].value;">';
     36                                html += '<tr><td><label for="link_list">{$lang_link_list}</label></td>';
     37                                html += '<td><select id="link_list" name="link_list" style="width: 200px" onchange="this.form.href.value=this.options[this.selectedIndex].value;">';
    5438                                html += '<option value="">---</option>';
    5539
    … …  
    6448                  <!-- /Link list -->
    6549          <tr>
    66             <td nowrap="nowrap">{$lang_insert_link_target}:</td>
    67             <td><select name="target" style="width: 200px">
     50            <td nowrap="nowrap"><label for="target">{$lang_insert_link_target}</label></td>
     51            <td><select id="target" name="target" style="width: 200px">
    6852                <option value="_self">{$lang_insert_link_target_same}</option>
    6953                <option value="_blank">{$lang_insert_link_target_blank}</option>
    … …  
    8973          </tr>
    9074          <tr>
    91             <td nowrap="nowrap">{$lang_theme_insert_link_titlefield}:</td>
    92             <td><input name="linktitle" type="text" id="linktitle" value="" style="width: 200px"></td>
     75            <td nowrap="nowrap"><label for="linktitle">{$lang_theme_insert_link_titlefield}</label></td>
     76            <td><input id="linktitle" name="linktitle" type="text" value="" style="width: 200px"></td>
    9377          </tr>
    9478          <tr id="styleSelectRow">
    95             <td><!--{$lang_class_name}:</td>
     79            <td><label for="styleSelect">{$lang_class_name}</label></td>
    9680            <td>
    9781                         <select id="styleSelect" name="styleSelect">
    9882                <option value="" selected>{$lang_theme_style_select}</option>
    9983             </select></td>
    100             <td align="right">&nbsp;</td>
    101             <td align="right">&nbsp;--></td>
    10284          </tr>
    103           <tr>
    104             <td><input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertLink();">
    105             </td>
    106             <td align="right"><input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();"></td>
    107           </tr>
    108         </table></td>
    109     </tr>
    110   </table>
     85        </table>
     86                </div>
     87        </div>
     88
     89        <div class="mceActionPanel">
     90                <div style="float: left">
     91                        <input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />
     92                </div>
     93
     94                <div style="float: right">
     95                        <input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertLink();" />
     96                </div>
     97        </div>
    11198</form>
    11299</body>
  • trunk/wp-includes/js/tinymce/themes/advanced/source_editor.htm

    r3163 r3664  
    55        <script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
    66        <script language="javascript" type="text/javascript" src="jscripts/source_editor.js"></script>
    7         <style type="text/css">
    8                 #insert, #cancel {
    9                         font: 13px Verdana, Arial, Helvetica, sans-serif;
    10                         height: auto;
    11                         width: auto;
    12                         background-color: transparent;
    13                         background-image: url(../../../../../wp-admin/images/fade-butt.png);
    14                         background-repeat: repeat;
    15                         border: 3px double;
    16                         border-right-color: rgb(153, 153, 153);
    17                         border-bottom-color: rgb(153, 153, 153);
    18                         border-left-color: rgb(204, 204, 204);
    19                         border-top-color: rgb(204, 204, 204);
    20                         color: rgb(51, 51, 51);
    21                         padding: 0.25em 0.75em;
    22                 }
    23                 #insert:active, #cancel:active {
    24                         background: #f4f4f4;
    25                         border-left-color: #999;
    26                         border-top-color: #999;
    27                 }
    28         </style>
     7        <base target="_self" />
    298</head>
    30 <body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');document.getElementById('htmlSource').focus();" onresize="resizeInputs();" style="display: none">
     9<body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');document.body.style.display='';document.getElementById('htmlSource').focus();" onresize="resizeInputs();" style="display: none">
    3110        <form name="source" onsubmit="saveContent();" action="#">
    3211                <div style="float: left" class="title">{$lang_theme_code_title}</div>
    … …  
    3615                </div>
    3716
    38                 <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>
     17                <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="off"></textarea>
    3918
    4019                <div class="mceActionPanel">
    4120                        <div style="float: left">
    42                                 <input type="button" name="insert" value="{$lang_update}" onclick="saveContent();" id="insert" />
     21                                <input type="button" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />
    4322                        </div>
    4423
    4524                        <div style="float: right">
    46                                 <input type="button" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />
     25                                <input type="submit" name="insert" value="{$lang_update}" onclick="saveContent();" id="insert" />
    4726                        </div>
    4827                </div>
  • trunk/wp-includes/js/tinymce/tiny_mce.js

    r3517 r3664  
    1 /**
    2  * $RCSfile: tiny_mce_src.js,v $
    3  * $Revision: 1.281 $
    4  * $Date: 2005/12/02 08:12:07 $
    5  *
    6  * @author Moxiecode
    7  * @copyright Copyright © 2004, Moxiecode Systems AB, All rights reserved.
    8  */
    9 
    10 function TinyMCE() {
     1
     2/* file:jscripts/tiny_mce/classes/TinyMCE_Engine.class.js */
     3
     4function TinyMCE_Engine() {
    115        this.majorVersion = "2";
    12         this.minorVersion = "0";
    13         this.releaseDate = "2005-12-01";
     6        this.minorVersion = "0.5.1";
     7        this.releaseDate = "2006-03-22";
    148
    159        this.instances = new Array();
    16         this.stickyClassesLookup = new Array();
     10        this.switchClassCache = new Array();
    1711        this.windowArgs = new Array();
    1812        this.loadedFiles = new Array();
    … …  
    3327        this.isNS71 = ua.indexOf('Netscape/7.1') != -1;
    3428        this.dialogCounter = 0;
     29        this.plugins = new Array();
     30        this.themes = new Array();
     31        this.menus = new Array();
     32        this.loadedPlugins = new Array();
     33        this.buttonMap = new Array();
     34        this.isLoaded = false;
    3535
    3636        // Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those
    … …  
    4545};
    4646
    47 TinyMCE.prototype.defParam = function(key, def_val) {
    48         this.settings[key] = tinyMCE.getParam(key, def_val);
    49 };
    50 
    51 TinyMCE.prototype.init = function(settings) {
    52         var theme;
    53 
    54         this.settings = settings;
    55 
    56         // Check if valid browser has execcommand support
    57         if (typeof(document.execCommand) == 'undefined')
    58                 return;
    59 
    60         // Get script base path
    61         if (!tinyMCE.baseURL) {
    62                 var elements = document.getElementsByTagName('script');
    63 
    64                 for (var i=0; i<elements.length; i++) {
    65                         if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip") != -1)) {
    66                                 var src = elements[i].src;
    67 
    68                                 tinyMCE.srcMode = (src.indexOf('_src') != -1) ? '_src' : '';
    69                                 src = src.substring(0, src.lastIndexOf('/'));
    70 
    71                                 tinyMCE.baseURL = src;
    72                                 break;
    73                         }
    74                 }
    75         }
    76 
    77         // Get document base path
    78         this.documentBasePath = document.location.href;
    79         if (this.documentBasePath.indexOf('?') != -1)
    80                 this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.indexOf('?'));
    81         this.documentURL = this.documentBasePath;
    82         this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.lastIndexOf('/'));
    83 
    84         // If not HTTP absolute
    85         if (tinyMCE.baseURL.indexOf('://') == -1 && tinyMCE.baseURL.charAt(0) != '/') {
    86                 // If site absolute
    87                 tinyMCE.baseURL = this.documentBasePath + "/" + tinyMCE.baseURL;
    88         }
    89 
    90         // Set default values on settings
    91         this.defParam("mode", "none");
    92         this.defParam("theme", "advanced");
    93         this.defParam("plugins", "", true);
    94         this.defParam("language", "en");
    95         this.defParam("docs_language", this.settings['language']);
    96         this.defParam("elements", "");
    97         this.defParam("textarea_trigger", "mce_editable");
    98         this.defParam("editor_selector", "");
    99         this.defParam("editor_deselector", "mceNoEditor");
    100         this.defParam("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/b[class|style],-em/i[class|style],-strike[class|style],-u[class|style],+p[style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border=0|alt|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],-td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[style|dir|class|align],-h2[style|dir|class|align],-h3[style|dir|class|align],-h4[style|dir|class|align],-h5[style|dir|class|align],-h6[style|dir|class|align],hr[class|style],font[face|size|style|id|class|dir|color]");
    101         this.defParam("extended_valid_elements", "");
    102         this.defParam("invalid_elements", "");
    103         this.defParam("encoding", "");
    104         this.defParam("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE.prototype.convertURL"));
    105         this.defParam("save_callback", "");
    106         this.defParam("debug", false);
    107         this.defParam("force_br_newlines", false);
    108         this.defParam("force_p_newlines", true);
    109         this.defParam("add_form_submit_trigger", true);
    110         this.defParam("relative_urls", true);
    111         this.defParam("remove_script_host", true);
    112         this.defParam("focus_alert", true);
    113         this.defParam("document_base_url", this.documentURL);
    114         this.defParam("visual", true);
    115         this.defParam("visual_table_class", "mceVisualAid");
    116         this.defParam("setupcontent_callback", "");
    117         this.defParam("fix_content_duplication", true);
    118         this.defParam("custom_undo_redo", true);
    119         this.defParam("custom_undo_redo_levels", -1);
    120         this.defParam("custom_undo_redo_keyboard_shortcuts", true);
    121         this.defParam("verify_css_classes", false);
    122         this.defParam("verify_html", true);
    123         this.defParam("apply_source_formatting", false);
    124         this.defParam("directionality", "ltr");
    125         this.defParam("cleanup_on_startup", false);
    126         this.defParam("inline_styles", false);
    127         this.defParam("convert_newlines_to_brs", false);
    128         this.defParam("auto_reset_designmode", true);
    129         this.defParam("entities", "160,nbsp,38,amp,34,quot,162,cent,8364,euro,163,pound,165,yen,169,copy,174,reg,8482,trade,8240,permil,181,micro,183,middot,8226,bull,8230,hellip,8242,prime,8243,Prime,167,sect,182,para,223,szlig,8249,lsaquo,8250,rsaquo,171,laquo,187,raquo,8216,lsquo,8217,rsquo,8220,ldquo,8221,rdquo,8218,sbquo,8222,bdquo,60,lt,62,gt,8804,le,8805,ge,8211,ndash,8212,mdash,175,macr,8254,oline,164,curren,166,brvbar,168,uml,161,iexcl,191,iquest,710,circ,732,tilde,176,deg,8722,minus,177,plusmn,247,divide,8260,frasl,215,times,185,sup1,178,sup2,179,sup3,188,frac14,189,frac12,190,frac34,402,fnof,8747,int,8721,sum,8734,infin,8730,radic,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8712,isin,8713,notin,8715,ni,8719,prod,8743,and,8744,or,172,not,8745,cap,8746,cup,8706,part,8704,forall,8707,exist,8709,empty,8711,nabla,8727,lowast,8733,prop,8736,ang,180,acute,184,cedil,170,ordf,186,ordm,8224,dagger,8225,Dagger,192,Agrave,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,202,Ecirc,203,Euml,204,Igrave,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,212,Ocirc,213,Otilde,214,Ouml,216,Oslash,338,OElig,217,Ugrave,219,Ucirc,220,Uuml,376,Yuml,222,THORN,224,agrave,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,234,ecirc,235,euml,236,igrave,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,244,ocirc,245,otilde,246,ouml,248,oslash,339,oelig,249,ugrave,251,ucirc,252,uuml,254,thorn,255,yuml,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,8501,alefsym,982,piv,8476,real,977,thetasym,978,upsih,8472,weierp,8465,image,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8756,there4,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,173,shy,233,eacute,237,iacute,243,oacute,250,uacute,193,Aacute,225,aacute,201,Eacute,205,Iacute,211,Oacute,218,Uacute,221,Yacute,253,yacute");
    130         this.defParam("entity_encoding", "named");
    131         this.defParam("cleanup_callback", "");
    132         this.defParam("add_unload_trigger", true);
    133         this.defParam("ask", false);
    134         this.defParam("nowrap", false);
    135         this.defParam("auto_resize", false);
    136         this.defParam("auto_focus", false);
    137         this.defParam("cleanup", true);
    138         this.defParam("remove_linebreaks", true);
    139         this.defParam("button_tile_map", false);
    140         this.defParam("submit_patch", true);
    141         this.defParam("browsers", "msie,safari,gecko,opera");
    142         this.defParam("dialog_type", "window");
    143         this.defParam("accessibility_warnings", true);
    144         this.defParam("merge_styles_invalid_parents", "");
    145         this.defParam("force_hex_style_colors", true);
    146         this.defParam("trim_span_elements", true);
    147         this.defParam("convert_fonts_to_spans", false);
    148         this.defParam("doctype", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">');
    149         this.defParam("font_size_classes", '');
    150         this.defParam("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large');
    151         this.defParam("event_elements", 'a,img');
    152         this.defParam("convert_urls", true);
    153         this.defParam("table_inline_editing", false);
    154         this.defParam("object_resizing", true);
    155 
    156         // Browser check IE
    157         if (this.isMSIE && this.settings['browsers'].indexOf('msie') == -1)
    158                 return;
    159 
    160         // Browser check Gecko
    161         if (this.isGecko && this.settings['browsers'].indexOf('gecko') == -1)
    162                 return;
    163 
    164         // Browser check Safari
    165         if (this.isSafari && this.settings['browsers'].indexOf('safari') == -1)
    166                 return;
    167 
    168         // Browser check Opera
    169         if (this.isOpera && this.settings['browsers'].indexOf('opera') == -1)
    170                 return;
    171 
    172         // If not super absolute make it so
    173         var baseHREF = tinyMCE.settings['document_base_url'];
    174         var h = document.location.href;
    175         var p = h.indexOf('://');
    176         if (p > 0 && document.location.protocol != "file:") {
    177                 p = h.indexOf('/', p + 3);
    178                 h = h.substring(0, p);
    179 
    180                 if (baseHREF.indexOf('://') == -1)
    181                         baseHREF = h + baseHREF;
    182 
    183                 tinyMCE.settings['document_base_url'] = baseHREF;
    184                 tinyMCE.settings['document_base_prefix'] = h;
    185         }
    186 
    187         // Trim away query part
    188         if (baseHREF.indexOf('?') != -1)
    189                 baseHREF = baseHREF.substring(0, baseHREF.indexOf('?'));
    190 
    191         this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";
    192 
    193         theme = this.settings['theme'];
    194         this.blockRegExp = new RegExp("^(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|blockquote|center|dl|dir|fieldset|form|noscript|noframes|menu|isindex)$", "i");
    195         this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40);
    196         this.uniqueURL = 'http://tinymce.moxiecode.cp/mce_temp_url'; // Make unique URL non real URL
    197         this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>';
    198 
    199         // Theme url
    200         this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme;
    201 
    202         if (!tinyMCE.isMSIE)
    203                 this.settings['force_br_newlines'] = false;
    204 
    205         if (tinyMCE.getParam("content_css", false)) {
    206                 var cssPath = tinyMCE.getParam("content_css", "");
    207 
    208                 // Is relative
    209                 if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
    210                         this.settings['content_css'] = this.documentBasePath + "/" + cssPath;
    211                 else
    212                         this.settings['content_css'] = cssPath;
    213         } else
    214                 this.settings['content_css'] = '';
    215 
    216         if (tinyMCE.getParam("popups_css", false)) {
    217                 var cssPath = tinyMCE.getParam("popups_css", "");
    218 
    219                 // Is relative
    220                 if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
    221                         this.settings['popups_css'] = this.documentBasePath + "/" + cssPath;
    222                 else
    223                         this.settings['popups_css'] = cssPath;
    224         } else
    225                 this.settings['popups_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css";
    226 
    227         if (tinyMCE.getParam("editor_css", false)) {
    228                 var cssPath = tinyMCE.getParam("editor_css", "");
    229 
    230                 // Is relative
    231                 if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
    232                         this.settings['editor_css'] = this.documentBasePath + "/" + cssPath;
    233                 else
    234                         this.settings['editor_css'] = cssPath;
    235         } else
    236                 this.settings['editor_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css";
    237 
    238         if (tinyMCE.settings['debug']) {
    239                 var msg = "Debug: \n";
    240 
    241                 msg += "baseURL: " + this.baseURL + "\n";
    242                 msg += "documentBasePath: " + this.documentBasePath + "\n";
    243                 msg += "content_css: " + this.settings['content_css'] + "\n";
    244                 msg += "popups_css: " + this.settings['popups_css'] + "\n";
    245                 msg += "editor_css: " + this.settings['editor_css'] + "\n";
    246 
    247                 alert(msg);
    248         }
    249 
    250         // Init HTML cleanup
    251         this._initCleanup();
    252 
    253         // Only do this once
    254         if (this.configs.length == 0) {
    255                 // Is Safari enabled
    256                 if (this.isSafari && this.getParam('safari_warning', true))
    257                         alert("Safari support is very limited and should be considered experimental.\nSo there is no need to even submit bugreports on this early version.\nYou can disable this message by setting: safari_warning option to false");
    258 
    259                 tinyMCE.addEvent(window, "load", TinyMCE.prototype.onLoad);
    260 
     47TinyMCE_Engine.prototype = {
     48        init : function(settings) {
     49                var theme;
     50
     51                this.settings = settings;
     52
     53                // Check if valid browser has execcommand support
     54                if (typeof(document.execCommand) == 'undefined')
     55                        return;
     56
     57                // Get script base path
     58                if (!tinyMCE.baseURL) {
     59                        var elements = document.getElementsByTagName('script');
     60
     61                        for (var i=0; i<elements.length; i++) {
     62                                if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_dev.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip") != -1)) {
     63                                        var src = elements[i].src;
     64
     65                                        tinyMCE.srcMode = (src.indexOf('_src') != -1 || src.indexOf('_dev') != -1) ? '_src' : '';
     66                                        tinyMCE.gzipMode = src.indexOf('_gzip') != -1;
     67                                        src = src.substring(0, src.lastIndexOf('/'));
     68
     69                                        if (settings.exec_mode == "src" || settings.exec_mode == "normal")
     70                                                tinyMCE.srcMode = settings.exec_mode == "src" ? '_src' : '';
     71
     72                                        tinyMCE.baseURL = src;
     73                                        break;
     74                                }
     75                        }
     76                }
     77
     78                // Get document base path
     79                this.documentBasePath = document.location.href;
     80                if (this.documentBasePath.indexOf('?') != -1)
     81                        this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.indexOf('?'));
     82                this.documentURL = this.documentBasePath;
     83                this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.lastIndexOf('/'));
     84
     85                // If not HTTP absolute
     86                if (tinyMCE.baseURL.indexOf('://') == -1 && tinyMCE.baseURL.charAt(0) != '/') {
     87                        // If site absolute
     88                        tinyMCE.baseURL = this.documentBasePath + "/" + tinyMCE.baseURL;
     89                }
     90
     91                // Set default values on settings
     92                this._def("mode", "none");
     93                this._def("theme", "advanced");
     94                this._def("plugins", "", true);
     95                this._def("language", "en");
     96                this._def("docs_language", this.settings['language']);
     97                this._def("elements", "");
     98                this._def("textarea_trigger", "mce_editable");
     99                this._def("editor_selector", "");
     100                this._def("editor_deselector", "mceNoEditor");
     101                this._def("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],-td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[id|style|dir|class|align],-h2[id|style|dir|class|align],-h3[id|style|dir|class|align],-h4[id|style|dir|class|align],-h5[id|style|dir|class|align],-h6[id|style|dir|class|align],hr[class|style],-font[face|size|style|id|class|dir|color],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang]");
     102                this._def("extended_valid_elements", "");
     103                this._def("invalid_elements", "");
     104                this._def("encoding", "");
     105                this._def("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE_Engine.prototype.convertURL"));
     106                this._def("save_callback", "");
     107                this._def("debug", false);
     108                this._def("force_br_newlines", false);
     109                this._def("force_p_newlines", true);
     110                this._def("add_form_submit_trigger", true);
     111                this._def("relative_urls", true);
     112                this._def("remove_script_host", true);
     113                this._def("focus_alert", true);
     114                this._def("document_base_url", this.documentURL);
     115                this._def("visual", true);
     116                this._def("visual_table_class", "mceVisualAid");
     117                this._def("setupcontent_callback", "");
     118                this._def("fix_content_duplication", true);
     119                this._def("custom_undo_redo", true);
     120                this._def("custom_undo_redo_levels", -1);
     121                this._def("custom_undo_redo_keyboard_shortcuts", true);
     122                this._def("custom_undo_redo_restore_selection", true);
     123                this._def("verify_html", true);
     124                this._def("apply_source_formatting", false);
     125                this._def("directionality", "ltr");
     126                this._def("cleanup_on_startup", false);
     127                this._def("inline_styles", false);
     128                this._def("convert_newlines_to_brs", false);
     129                this._def("auto_reset_designmode", true);
     130                this._def("entities", "160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,34,quot,38,amp,60,lt,62,gt,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro", true);
     131                this._def("entity_encoding", "named");
     132                this._def("cleanup_callback", "");
     133                this._def("add_unload_trigger", true);
     134                this._def("ask", false);
     135                this._def("nowrap", false);
     136                this._def("auto_resize", false);
     137                this._def("auto_focus", false);
     138                this._def("cleanup", true);
     139                this._def("remove_linebreaks", true);
     140                this._def("button_tile_map", false);
     141                this._def("submit_patch", true);
     142                this._def("browsers", "msie,safari,gecko,opera", true);
     143                this._def("dialog_type", "window");
     144                this._def("accessibility_warnings", true);
     145                this._def("accessibility_focus", true);
     146                this._def("merge_styles_invalid_parents", "");
     147                this._def("force_hex_style_colors", true);
     148                this._def("trim_span_elements", true);
     149                this._def("convert_fonts_to_spans", false);
     150                this._def("doctype", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">');
     151                this._def("font_size_classes", '');
     152                this._def("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large', true);
     153                this._def("event_elements", 'a,img', true);
     154                this._def("convert_urls", true);
     155                this._def("table_inline_editing", false);
     156                this._def("object_resizing", true);
     157                this._def("custom_shortcuts", true);
     158                this._def("convert_on_click", false);
     159                this._def("content_css", '');
     160                this._def("fix_list_elements", false);
     161                this._def("fix_table_elements", false);
     162
     163                // Browser check IE
     164                if (this.isMSIE && this.settings['browsers'].indexOf('msie') == -1)
     165                        return;
     166
     167                // Browser check Gecko
     168                if (this.isGecko && this.settings['browsers'].indexOf('gecko') == -1)
     169                        return;
     170
     171                // Browser check Safari
     172                if (this.isSafari && this.settings['browsers'].indexOf('safari') == -1)
     173                        return;
     174
     175                // Browser check Opera
     176                if (this.isOpera && this.settings['browsers'].indexOf('opera') == -1)
     177                        return;
     178
     179                // If not super absolute make it so
     180                var baseHREF = tinyMCE.settings['document_base_url'];
     181                var h = document.location.href;
     182                var p = h.indexOf('://');
     183                if (p > 0 && document.location.protocol != "file:") {
     184                        p = h.indexOf('/', p + 3);
     185                        h = h.substring(0, p);
     186
     187                        if (baseHREF.indexOf('://') == -1)
     188                                baseHREF = h + baseHREF;
     189
     190                        tinyMCE.settings['document_base_url'] = baseHREF;
     191                        tinyMCE.settings['document_base_prefix'] = h;
     192                }
     193
     194                // Trim away query part
     195                if (baseHREF.indexOf('?') != -1)
     196                        baseHREF = baseHREF.substring(0, baseHREF.indexOf('?'));
     197
     198                this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";
     199
     200                theme = this.settings['theme'];
     201                this.blockRegExp = new RegExp("^(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|blockquote|center|dl|dir|fieldset|form|noscript|noframes|menu|isindex)$", "i");
     202                this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40);
     203                this.uniqueURL = 'http://tinymce.moxiecode.cp/mce_temp_url'; // Make unique URL non real URL
     204                this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>';
     205                this.callbacks = new Array('onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup');
     206
     207                // Theme url
     208                this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme;
     209
     210                if (!tinyMCE.isMSIE)
     211                        this.settings['force_br_newlines'] = false;
     212
     213                if (tinyMCE.getParam("popups_css", false)) {
     214                        var cssPath = tinyMCE.getParam("popups_css", "");
     215
     216                        // Is relative
     217                        if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
     218                                this.settings['popups_css'] = this.documentBasePath + "/" + cssPath;
     219                        else
     220                                this.settings['popups_css'] = cssPath;
     221                } else
     222                        this.settings['popups_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css";
     223
     224                if (tinyMCE.getParam("editor_css", false)) {
     225                        var cssPath = tinyMCE.getParam("editor_css", "");
     226
     227                        // Is relative
     228                        if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
     229                                this.settings['editor_css'] = this.documentBasePath + "/" + cssPath;
     230                        else
     231                                this.settings['editor_css'] = cssPath;
     232                } else
     233                        this.settings['editor_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css";
     234
     235                if (tinyMCE.settings['debug']) {
     236                        var msg = "Debug: \n";
     237
     238                        msg += "baseURL: " + this.baseURL + "\n";
     239                        msg += "documentBasePath: " + this.documentBasePath + "\n";
     240                        msg += "content_css: " + this.settings['content_css'] + "\n";
     241                        msg += "popups_css: " + this.settings['popups_css'] + "\n";
     242                        msg += "editor_css: " + this.settings['editor_css'] + "\n";
     243
     244                        alert(msg);
     245                }
     246
     247                // Only do this once
     248                if (this.configs.length == 0) {
     249                        // Is Safari enabled
     250                        if (this.isSafari && this.getParam('safari_warning', false))
     251                                alert("Safari support is very limited and should be considered experimental.\nSo there is no need to even submit bugreports on this early version.\nYou can disable this message by setting: safari_warning option to false");
     252
     253                        if (typeof(TinyMCECompressed) == "undefined") {
     254                                tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCE_Engine.prototype.onLoad);
     255
     256                                if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
     257                                        if (document.body)
     258                                                tinyMCE.addEvent(document.body, "readystatechange", TinyMCE_Engine.prototype.onLoad);
     259                                        else
     260                                                tinyMCE.addEvent(document, "readystatechange", TinyMCE_Engine.prototype.onLoad);
     261                                }
     262
     263                                tinyMCE.addEvent(window, "load", TinyMCE_Engine.prototype.onLoad);
     264                                tinyMCE._addUnloadEvents();
     265                        }
     266                }
     267
     268                this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings['theme'] + '/editor_template' + tinyMCE.srcMode + '.js');
     269                this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings['language'] +  '.js');
     270                this.loadCSS(this.settings['editor_css']);
     271
     272                // Add plugins
     273                var p = tinyMCE.getParam('plugins', '', true, ',');
     274                if (p.length > 0) {
     275                        for (var i=0; i<p.length; i++) {
     276                                if (p[i].charAt(0) != '-')
     277                                        this.loadScript(tinyMCE.baseURL + '/plugins/' + p[i] + '/editor_plugin' + tinyMCE.srcMode + '.js');
     278                        }
     279                }
     280
     281                // Setup entities
     282                settings['cleanup_entities'] = new Array();
     283                var entities = tinyMCE.getParam('entities', '', true, ',');
     284                for (var i=0; i<entities.length; i+=2)
     285                        settings['cleanup_entities']['c' + entities[i]] = entities[i+1];
     286
     287                // Save away this config
     288                settings['index'] = this.configs.length;
     289                this.configs[this.configs.length] = settings;
     290        },
     291
     292        _addUnloadEvents : function() {
    261293                if (tinyMCE.isMSIE) {
    262294                        if (tinyMCE.settings['add_unload_trigger']) {
    263                                 tinyMCE.addEvent(window, "unload", TinyMCE.prototype.unloadHandler);
    264                                 tinyMCE.addEvent(window.document, "beforeunload", TinyMCE.prototype.unloadHandler);
     295                                tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler);
     296                                tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler);
    265297                        }
    266298                } else {
    … …  
    268300                                tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);});
    269301                }
    270         }
    271 
    272         this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings['theme'] + '/editor_template' + tinyMCE.srcMode + '.js');
    273         this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings['language'] +  '.js');
    274         this.loadCSS(this.settings['editor_css']);
    275 
    276         // Add plugins
    277         var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
    278         if (this.settings['plugins'] != '') {
    279                 for (var i=0; i<themePlugins.length; i++)
    280                         this.loadScript(tinyMCE.baseURL + '/plugins/' + themePlugins[i] + '/editor_plugin' + tinyMCE.srcMode + '.js');
    281         }
    282 
    283         // Setup entities
    284         settings['cleanup_entities'] = new Array();
    285         var entities = tinyMCE.getParam('entities', '', true, ',');
    286         for (var i=0; i<entities.length; i+=2)
    287                 settings['cleanup_entities']['c' + entities[i]] = entities[i+1];
    288 
    289         // Save away this config
    290         settings['index'] = this.configs.length;
    291         this.configs[this.configs.length] = settings;
    292 };
    293 
    294 TinyMCE.prototype.loadScript = function(url) {
    295         for (var i=0; i<this.loadedFiles.length; i++) {
    296                 if (this.loadedFiles[i] == url)
    297                         return;
    298         }
    299 
    300         document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '"></script>');
    301 
    302         this.loadedFiles[this.loadedFiles.length] = url;
    303 };
    304 
    305 TinyMCE.prototype.loadCSS = function(url) {
    306         for (var i=0; i<this.loadedFiles.length; i++) {
    307                 if (this.loadedFiles[i] == url)
    308                         return;
    309         }
    310 
    311         document.write('<link href="' + url + '" rel="stylesheet" type="text/css" />');
    312 
    313         this.loadedFiles[this.loadedFiles.length] = url;
    314 };
    315 
    316 TinyMCE.prototype.importCSS = function(doc, css_file) {
    317         if (css_file == '')
    318                 return;
    319 
    320         if (typeof(doc.createStyleSheet) == "undefined") {
    321                 var elm = doc.createElement("link");
    322 
    323                 elm.rel = "stylesheet";
    324                 elm.href = css_file;
    325 
    326                 if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0)
    327                         headArr[0].appendChild(elm);
    328         } else
    329                 var styleSheet = doc.createStyleSheet(css_file);
    330 };
    331 
    332 TinyMCE.prototype.confirmAdd = function(e, settings) {
    333         var elm = tinyMCE.isMSIE ? event.srcElement : e.target;
    334         var elementId = elm.name ? elm.name : elm.id;
    335 
    336         tinyMCE.settings = settings;
    337 
    338         if (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm']))
    339                 tinyMCE.addMCEControl(elm, elementId);
    340 
    341         elm.setAttribute('mce_noask', 'true');
    342 };
    343 
    344 TinyMCE.prototype.updateContent = function(form_element_name) {
    345         // Find MCE instance linked to given form element and copy it's value
    346         var formElement = document.getElementById(form_element_name);
    347         for (var n in tinyMCE.instances) {
    348                 var inst = tinyMCE.instances[n];
    349                 if (!tinyMCE.isInstance(inst))
    350                         continue;
    351 
    352                 inst.switchSettings();
    353 
    354                 if (inst.formElement == formElement) {
    355                         var doc = inst.getDoc();
    356 
    357                         tinyMCE._setHTML(doc, inst.formElement.value);
    358 
    359                         if (!tinyMCE.isMSIE)
    360                                 doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid);
    361                 }
    362         }
    363 };
    364 
    365 TinyMCE.prototype.addMCEControl = function(replace_element, form_element_name, target_document) {
    366         var id = "mce_editor_" + tinyMCE.idCounter++;
    367         var inst = new TinyMCEControl(tinyMCE.settings);
    368 
    369         inst.editorId = id;
    370         this.instances[id] = inst;
    371 
    372         inst.onAdd(replace_element, form_element_name, target_document);
    373 };
    374 
    375 TinyMCE.prototype.triggerSave = function(skip_cleanup, skip_callback) {
    376         // Cleanup and set all form fields
    377         for (var n in tinyMCE.instances) {
    378                 var inst = tinyMCE.instances[n];
    379                 if (!tinyMCE.isInstance(inst))
    380                         continue;
    381 
    382                 inst.switchSettings();
    383 
    384                 tinyMCE.settings['preformatted'] = false;
     302        },
     303
     304        _def : function(key, def_val, t) {
     305                var v = tinyMCE.getParam(key, def_val);
     306
     307                v = t ? v.replace(/\s+/g,"") : v;
     308
     309                this.settings[key] = v;
     310        },
     311
     312        hasPlugin : function(n) {
     313                return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null;
     314        },
     315
     316        addPlugin : function(n, p) {
     317                var op = this.plugins[n];
     318
     319                // Use the previous plugin object base URL used when loading external plugins
     320                p.baseURL = op ? op.baseURL : tinyMCE.baseURL + "/plugins/" + n;
     321                this.plugins[n] = p;
     322        },
     323
     324        setPluginBaseURL : function(n, u) {
     325                var op = this.plugins[n];
     326
     327                if (op)
     328                        op.baseURL = u;
     329                else
     330                        this.plugins[n] = {baseURL : u};
     331        },
     332
     333        loadPlugin : function(n, u) {
     334                u = u.indexOf('.js') != -1 ? u.substring(0, u.lastIndexOf('/')) : u;
     335                u = u.charAt(u.length-1) == '/' ? u.substring(0, u.length-1) : u;
     336                this.plugins[n] = {baseURL : u};
     337                this.loadScript(u + "/editor_plugin" + (tinyMCE.srcMode ? '_src' : '') + ".js");
     338        },
     339
     340        hasTheme : function(n) {
     341                return typeof(this.themes[n]) != "undefined" && this.themes[n] != null;
     342        },
     343
     344        addTheme : function(n, t) {
     345                this.themes[n] = t;
     346        },
     347
     348        addMenu : function(n, m) {
     349                this.menus[n] = m;
     350        },
     351
     352        hasMenu : function(n) {
     353                return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null;
     354        },
     355
     356        loadScript : function(url) {
     357                for (var i=0; i<this.loadedFiles.length; i++) {
     358                        if (this.loadedFiles[i] == url)
     359                                return;
     360                }
     361
     362                document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '"></script>');
     363
     364                this.loadedFiles[this.loadedFiles.length] = url;
     365        },
     366
     367        loadCSS : function(url) {
     368                var ar = url.replace(/\s+/, '').split(',');
     369                var lflen = 0, csslen = 0;
     370                var skip = false;
     371                var x = 0, i = 0;
     372
     373                for (x = 0,csslen = ar.length; x<csslen; x++) {
     374                        ignore_css = false;
     375
     376                        if (ar[x] != null && ar[x] != 'null' && ar[x].length > 0) {
     377                                /* Make sure it doesn't exist. */
     378                                for (i=0, lflen=this.loadedFiles.length; i<lflen; i++) {
     379                                        if (this.loadedFiles[i] == ar[x]) {
     380                                                skip = true;
     381                                                break;
     382                                        }
     383                                }
     384
     385                                if (!skip) {
     386                                        document.write('<link href="' + ar[x] + '" rel="stylesheet" type="text/css" />');
     387                                        this.loadedFiles[this.loadedFiles.length] = ar[x];
     388                                }
     389                        }
     390                }
     391        },
     392
     393        importCSS : function(doc, css) {
     394                var css_ary = css.replace(/\s+/, '').split(',');
     395                var csslen, elm, headArr, x, css_file;
     396
     397                for (x = 0, csslen = css_ary.length; x<csslen; x++) {
     398                        css_file = css_ary[x];
     399
     400                        if (css_file != null && css_file != 'null' && css_file.length > 0) {
     401                                // Is relative, make absolute
     402                                if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/')
     403                                        css_file = this.documentBasePath + "/" + css_file;
     404
     405                                if (typeof(doc.createStyleSheet) == "undefined") {
     406                                        elm = doc.createElement("link");
     407
     408                                        elm.rel = "stylesheet";
     409                                        elm.href = css_file;
     410
     411                                        if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0)
     412                                                headArr[0].appendChild(elm);
     413                                } else
     414                                        doc.createStyleSheet(css_file);
     415                        }
     416                }
     417        },
     418
     419        confirmAdd : function(e, settings) {
     420                var elm = tinyMCE.isMSIE ? event.srcElement : e.target;
     421                var elementId = elm.name ? elm.name : elm.id;
     422
     423                tinyMCE.settings = settings;
     424
     425                if (tinyMCE.settings['convert_on_click'] || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm'])))
     426                        tinyMCE.addMCEControl(elm, elementId);
     427
     428                elm.setAttribute('mce_noask', 'true');
     429        },
     430
     431        updateContent : function(form_element_name) {
     432                // Find MCE instance linked to given form element and copy it's value
     433                var formElement = document.getElementById(form_element_name);
     434                for (var n in tinyMCE.instances) {
     435                        var inst = tinyMCE.instances[n];
     436                        if (!tinyMCE.isInstance(inst))
     437                                continue;
     438
     439                        inst.switchSettings();
     440
     441                        if (inst.formElement == formElement) {
     442                                var doc = inst.getDoc();
     443               
     444                                tinyMCE._setHTML(doc, inst.formElement.value);
     445
     446                                if (!tinyMCE.isMSIE)
     447                                        doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid);
     448                        }
     449                }
     450        },
     451
     452        addMCEControl : function(replace_element, form_element_name, target_document) {
     453                var id = "mce_editor_" + tinyMCE.idCounter++;
     454                var inst = new TinyMCE_Control(tinyMCE.settings);
     455
     456                inst.editorId = id;
     457                this.instances[id] = inst;
     458
     459                inst._onAdd(replace_element, form_element_name, target_document);
     460        },
     461
     462        removeMCEControl : function(editor_id) {
     463                var inst = tinyMCE.getInstanceById(editor_id);
     464
     465                if (inst) {
     466                        inst.switchSettings();
     467
     468                        editor_id = inst.editorId;
     469                        var html = tinyMCE.getContent(editor_id);
     470
     471                        // Remove editor instance from instances array
     472                        var tmpInstances = new Array();
     473                        for (var instanceName in tinyMCE.instances) {
     474                                var instance = tinyMCE.instances[instanceName];
     475                                if (!tinyMCE.isInstance(instance))
     476                                        continue;
     477
     478                                if (instanceName != editor_id)
     479                                                tmpInstances[instanceName] = instance;
     480                        }
     481                        tinyMCE.instances = tmpInstances;
     482
     483                        tinyMCE.selectedElement = null;
     484                        tinyMCE.selectedInstance = null;
     485
     486                        // Remove element
     487                        var replaceElement = document.getElementById(editor_id + "_parent");
     488                        var oldTargetElement = inst.oldTargetElement;
     489                        var targetName = oldTargetElement.nodeName.toLowerCase();
     490
     491                        if (targetName == "textarea" || targetName == "input") {
     492                                // Just show the old text area
     493                                replaceElement.parentNode.removeChild(replaceElement);
     494                                oldTargetElement.style.display = "inline";
     495                                oldTargetElement.value = html;
     496                        } else {
     497                                oldTargetElement.innerHTML = html;
     498                                oldTargetElement.style.display = 'block';
     499
     500                                replaceElement.parentNode.insertBefore(oldTargetElement, replaceElement);
     501                                replaceElement.parentNode.removeChild(replaceElement);
     502                        }
     503                }
     504        },
     505
     506        triggerSave : function(skip_cleanup, skip_callback) {
     507                var inst, n;
    385508
    386509                // Default to false
    … …  
    392515                        skip_callback = false;
    393516
    394                 tinyMCE._setHTML(inst.getDoc(), inst.getBody().innerHTML);
     517                // Cleanup and set all form fields
     518                for (n in tinyMCE.instances) {
     519                        inst = tinyMCE.instances[n];
     520
     521                        if (!tinyMCE.isInstance(inst))
     522                                continue;
     523
     524                        inst.triggerSave(skip_cleanup, skip_callback);
     525                }
     526        },
     527
     528        resetForm : function(form_index) {
     529                var i, inst, n, formObj = document.forms[form_index];
     530
     531                for (n in tinyMCE.instances) {
     532                        inst = tinyMCE.instances[n];
     533
     534                        if (!tinyMCE.isInstance(inst))
     535                                continue;
     536
     537                        inst.switchSettings();
     538
     539                        for (i=0; i<formObj.elements.length; i++) {
     540                                if (inst.formTargetElementId == formObj.elements[i].name)
     541                                        inst.getBody().innerHTML = inst.startContent;
     542                        }
     543                }
     544        },
     545
     546        execInstanceCommand : function(editor_id, command, user_interface, value, focus) {
     547                var inst = tinyMCE.getInstanceById(editor_id);
     548                if (inst) {
     549                        if (typeof(focus) == "undefined")
     550                                focus = true;
     551
     552                        if (focus)
     553                                inst.contentWindow.focus();
     554
     555                        // Reset design mode if lost
     556                        inst.autoResetDesignMode();
     557
     558                        this.selectedElement = inst.getFocusElement();
     559                        this.selectedInstance = inst;
     560                        tinyMCE.execCommand(command, user_interface, value);
     561
     562                        // Cancel event so it doesn't call onbeforeonunlaod
     563                        if (tinyMCE.isMSIE && window.event != null)
     564                                tinyMCE.cancelEvent(window.event);
     565                }
     566        },
     567
     568        execCommand : function(command, user_interface, value) {
     569                // Default input
     570                user_interface = user_interface ? user_interface : false;
     571                value = value ? value : null;
     572
     573                if (tinyMCE.selectedInstance)
     574                        tinyMCE.selectedInstance.switchSettings();
     575
     576                switch (command) {
     577                        case 'mceHelp':
     578                                tinyMCE.openWindow({
     579                                        file : 'about.htm',
     580                                        width : 480,
     581                                        height : 380
     582                                }, {
     583                                        tinymce_version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion,
     584                                        tinymce_releasedate : tinyMCE.releaseDate,
     585                                        inline : "yes"
     586                                });
     587                        return;
     588
     589                        case 'mceFocus':
     590                                var inst = tinyMCE.getInstanceById(value);
     591                                if (inst)
     592                                        inst.contentWindow.focus();
     593                        return;
     594
     595                        case "mceAddControl":
     596                        case "mceAddEditor":
     597                                tinyMCE.addMCEControl(tinyMCE._getElementById(value), value);
     598                                return;
     599
     600                        case "mceAddFrameControl":
     601                                tinyMCE.addMCEControl(tinyMCE._getElementById(value['element'], value['document']), value['element'], value['document']);
     602                                return;
     603
     604                        case "mceRemoveControl":
     605                        case "mceRemoveEditor":
     606                                tinyMCE.removeMCEControl(value);
     607                                return;
     608
     609                        case "mceResetDesignMode":
     610                                // Resets the designmode state of the editors in Gecko
     611                                if (!tinyMCE.isMSIE) {
     612                                        for (var n in tinyMCE.instances) {
     613                                                if (!tinyMCE.isInstance(tinyMCE.instances[n]))
     614                                                        continue;
     615
     616                                                try {
     617                                                        tinyMCE.instances[n].getDoc().designMode = "on";
     618                                                } catch (e) {
     619                                                        // Ignore any errors
     620                                                }
     621                                        }
     622                                }
     623
     624                                return;
     625                }
     626
     627                if (this.selectedInstance) {
     628                        this.selectedInstance.execCommand(command, user_interface, value);
     629                } else if (tinyMCE.settings['focus_alert'])
     630                        alert(tinyMCELang['lang_focus_alert']);
     631        },
     632
     633        _createIFrame : function(replace_element, doc, win) {
     634                var iframe, id = replace_element.getAttribute("id");
     635                var aw, ah;
     636
     637                if (typeof(doc) == "undefined")
     638                        doc = document;
     639
     640                if (typeof(win) == "undefined")
     641                        win = window;
     642
     643                iframe = doc.createElement("iframe");
     644
     645                aw = "" + tinyMCE.settings['area_width'];
     646                ah = "" + tinyMCE.settings['area_height'];
     647
     648                if (aw.indexOf('%') == -1) {
     649                        aw = parseInt(aw);
     650                        aw = aw < 0 ? 300 : aw;
     651                        aw = aw + "px";
     652                }
     653
     654                if (ah.indexOf('%') == -1) {
     655                        ah = parseInt(ah);
     656                        ah = ah < 0 ? 240 : ah;
     657                        ah = ah + "px";
     658                }
     659
     660                iframe.setAttribute("id", id);
     661                iframe.setAttribute("className", "mceEditorIframe");
     662                iframe.setAttribute("border", "0");
     663                iframe.setAttribute("frameBorder", "0");
     664                iframe.setAttribute("marginWidth", "0");
     665                iframe.setAttribute("marginHeight", "0");
     666                iframe.setAttribute("leftMargin", "0");
     667                iframe.setAttribute("topMargin", "0");
     668                iframe.setAttribute("width", aw);
     669                iframe.setAttribute("height", ah);
     670                iframe.setAttribute("allowtransparency", "true");
     671
     672                if (tinyMCE.settings["auto_resize"])
     673                        iframe.setAttribute("scrolling", "no");
     674
     675                // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs
     676                if (tinyMCE.isMSIE && !tinyMCE.isOpera)
     677                        iframe.setAttribute("src", this.settings['default_document']);
     678
     679                iframe.style.width = aw;
     680                iframe.style.height = ah;
     681
     682                // MSIE 5.0 issue
     683                if (tinyMCE.isMSIE && !tinyMCE.isOpera)
     684                        replace_element.outerHTML = iframe.outerHTML;
     685                else
     686                        replace_element.parentNode.replaceChild(iframe, replace_element);
     687
     688                if (tinyMCE.isMSIE && !tinyMCE.isOpera)
     689                        return win.frames[id];
     690                else
     691                        return iframe;
     692        },
     693
     694        setupContent : function(editor_id) {
     695                var inst = tinyMCE.instances[editor_id];
     696                var doc = inst.getDoc();
     697                var head = doc.getElementsByTagName('head').item(0);
     698                var content = inst.startContent;
     699
     700                inst.switchSettings();
     701
     702                // Not loaded correctly hit it again, Mozilla bug #997860
     703                if (!tinyMCE.isMSIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") {
     704                        // This part will remove the designMode status
     705                        // Failes first time in Firefox 1.5b2 on Mac
     706                        try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {}
     707                        window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000);
     708                        return;
     709                }
     710
     711                if (!head) {
     712                        window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10);
     713                        return;
     714                }
     715
     716                // Import theme specific content CSS the user specific
     717                tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css");
     718                tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']);
     719                tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst);
     720
     721                // Setup keyboard shortcuts
     722                if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) {
     723                        inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo');
     724                        inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo');
     725                }
     726
     727                // Add default shortcuts for gecko
     728                if (tinyMCE.isGecko) {
     729                        inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold');
     730                        inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic');
     731                        inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline');
     732                }
     733
     734                // Setup span styles
     735                if (tinyMCE.getParam("convert_fonts_to_spans"))
     736                        inst.getDoc().body.setAttribute('id', 'mceSpanFonts');
     737
     738                if (tinyMCE.settings['nowrap'])
     739                        doc.body.style.whiteSpace = "nowrap";
     740
     741                doc.body.dir = this.settings['directionality'];
     742                doc.editorId = editor_id;
     743
     744                // Add on document element in Mozilla
     745                if (!tinyMCE.isMSIE)
     746                        doc.documentElement.editorId = editor_id;
     747
     748                inst.setBaseHREF(tinyMCE.settings['base_href']);
     749
     750                // Replace new line characters to BRs
     751                if (tinyMCE.settings['convert_newlines_to_brs']) {
     752                        content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi");
     753                        content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi");
     754                        content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi");
     755                }
     756
     757                // Open closed anchors
     758        //      content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
     759
     760                // Call custom cleanup code
     761                content = tinyMCE.storeAwayURLs(content);
     762                content = tinyMCE._customCleanup(inst, "insert_to_editor", content);
     763
     764                if (tinyMCE.isMSIE) {
     765                        // Ugly!!!
     766                        window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500);
     767
     768                        if (tinyMCE.settings["force_br_newlines"])
     769                                doc.styleSheets[0].addRule("p", "margin: 0;");
     770
     771                        var body = inst.getBody();
     772                        body.editorId = editor_id;
     773                }
     774
     775                content = tinyMCE.cleanupHTMLCode(content);
     776
     777                // Fix for bug #958637
     778                if (!tinyMCE.isMSIE) {
     779                        var contentElement = inst.getDoc().createElement("body");
     780                        var doc = inst.getDoc();
     781
     782                        contentElement.innerHTML = content;
     783
     784                        // Remove weridness!
     785                        if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt'])
     786                                content = content.replace(new RegExp('&lt;&gt;', 'g'), "");
     787
     788                        if (tinyMCE.settings['cleanup_on_startup'])
     789                                tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement));
     790                        else {
     791                                // Convert all strong/em to b/i
     792                                content = tinyMCE.regexpReplace(content, "<strong", "<b", "gi");
     793                                content = tinyMCE.regexpReplace(content, "<em(/?)>", "<i$1>", "gi");
     794                                content = tinyMCE.regexpReplace(content, "<em ", "<i ", "gi");
     795                                content = tinyMCE.regexpReplace(content, "</strong>", "</b>", "gi");
     796                                content = tinyMCE.regexpReplace(content, "</em>", "</i>", "gi");
     797                                tinyMCE.setInnerHTML(inst.getBody(), content);
     798                        }
     799
     800                        tinyMCE.convertAllRelativeURLs(inst.getBody());
     801                } else {
     802                        if (tinyMCE.settings['cleanup_on_startup']) {
     803                                tinyMCE._setHTML(inst.getDoc(), content);
     804
     805                                // Produces permission denied error in MSIE 5.5
     806                                eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}');
     807                        } else
     808                                tinyMCE._setHTML(inst.getDoc(), content);
     809                }
     810
     811                // Fix for bug #957681
     812                //inst.getDoc().designMode = inst.getDoc().designMode;
     813
     814                // Setup element references
     815                var parentElm = inst.targetDoc.getElementById(inst.editorId + '_parent');
     816                inst.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling;
     817
     818                tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst);
     819                tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc());
     820
     821                // Re-add design mode on mozilla
     822                if (!tinyMCE.isMSIE)
     823                        tinyMCE.addEventHandlers(inst);
     824
     825                // Add blur handler
     826                if (tinyMCE.isMSIE) {
     827                        tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch);
     828                        tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953
     829
     830                        // Workaround for drag drop/copy paste base href bug
     831                        if (!tinyMCE.isOpera) {
     832                                tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove);
     833                                tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch);
     834                                tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch);
     835                        }
     836                }
     837
     838                // Trigger node change, this call locks buttons for tables and so forth
     839                tinyMCE.selectedInstance = inst;
     840                tinyMCE.selectedElement = inst.contentWindow.document.body;
     841
     842                // Call custom DOM cleanup
     843                tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody());
     844                tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody());
     845                tinyMCE._setEventsEnabled(inst.getBody(), false);
     846                tinyMCE.cleanupAnchors(inst.getDoc());
     847
     848                if (tinyMCE.getParam("convert_fonts_to_spans"))
     849                        tinyMCE.convertSpansToFonts(inst.getDoc());
     850
     851                inst.startContent = tinyMCE.trim(inst.getBody().innerHTML);
     852                inst.undoRedo.add({ content : inst.startContent });
     853
     854                tinyMCE.selectedInstance = inst;
     855                tinyMCE.triggerNodeChange(false, true);
     856        },
     857
     858        storeAwayURLs : function(s) {
     859                // Remove all mce_src, mce_href and replace them with new ones
     860        //      s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
     861        //      s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
     862
     863                if (!s.match(/(mce_src|mce_href)/gi, s)) {
     864                        s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"');
     865                        s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"');
     866                }
     867
     868                return s;
     869        },
     870
     871        removeTinyMCEFormElements : function(form_obj) {
     872                // Check if form is valid
     873                if (typeof(form_obj) == "undefined" || form_obj == null)
     874                        return;
     875
     876                // If not a form, find the form
     877                if (form_obj.nodeName != "FORM") {
     878                        if (form_obj.form)
     879                                form_obj = form_obj.form;
     880                        else
     881                                form_obj = tinyMCE.getParentElement(form_obj, "form");
     882                }
     883
     884                // Still nothing
     885                if (form_obj == null)
     886                        return;
     887
     888                // Disable all UI form elements that TinyMCE created
     889                for (var i=0; i<form_obj.elements.length; i++) {
     890                        var elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id;
     891
     892                        if (elementId.indexOf('mce_editor_') == 0)
     893                                form_obj.elements[i].disabled = true;
     894                }
     895        },
     896
     897        handleEvent : function(e) {
     898                var inst = tinyMCE.selectedInstance;
     899
     900                // Remove odd, error
     901                if (typeof(tinyMCE) == "undefined")
     902                        return true;
     903
     904                //tinyMCE.debug(e.type + " " + e.target.nodeName + " " + (e.relatedTarget ? e.relatedTarget.nodeName : ""));
     905
     906                if (tinyMCE.executeCallback(tinyMCE.selectedInstance, 'handle_event_callback', 'handleEvent', e))
     907                        return false;
     908
     909                switch (e.type) {
     910                        case "beforedeactivate": // Was added due to bug #1439953
     911                        case "blur":
     912                                if (tinyMCE.selectedInstance)
     913                                        tinyMCE.selectedInstance.execCommand('mceEndTyping');
     914
     915                                tinyMCE.hideMenus();
     916
     917                                return;
     918
     919                        // Workaround for drag drop/copy paste base href bug
     920                        case "drop":
     921                        case "beforepaste":
     922                                if (tinyMCE.selectedInstance)
     923                                        tinyMCE.selectedInstance.setBaseHREF(null);
     924
     925                                window.setTimeout("tinyMCE.selectedInstance.setBaseHREF(tinyMCE.settings['base_href']);", 1);
     926                                return;
     927
     928                        case "submit":
     929                                tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target);
     930                                tinyMCE.triggerSave();
     931                                tinyMCE.isNotDirty = true;
     932                                return;
     933
     934                        case "reset":
     935                                var formObj = tinyMCE.isMSIE ? window.event.srcElement : e.target;
     936
     937                                for (var i=0; i<document.forms.length; i++) {
     938                                        if (document.forms[i] == formObj)
     939                                                window.setTimeout('tinyMCE.resetForm(' + i + ');', 10);
     940                                }
     941
     942                                return;
     943
     944                        case "keypress":
     945                                if (inst && inst.handleShortcut(e))
     946                                        return false;
     947
     948                                if (e.target.editorId) {
     949                                        tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
     950                                } else {
     951                                        if (e.target.ownerDocument.editorId)
     952                                                tinyMCE.selectedInstance = tinyMCE.instances[e.target.ownerDocument.editorId];
     953                                }
     954
     955                                if (tinyMCE.selectedInstance)
     956                                        tinyMCE.selectedInstance.switchSettings();
     957
     958                                // Insert P element
     959                                if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && e.keyCode == 13 && !e.shiftKey) {
     960                                        // Insert P element instead of BR
     961                                        if (TinyMCE_ForceParagraphs._insertPara(tinyMCE.selectedInstance, e)) {
     962                                                // Cancel event
     963                                                tinyMCE.execCommand("mceAddUndoLevel");
     964                                                tinyMCE.cancelEvent(e);
     965                                                return false;
     966                                        }
     967                                }
     968
     969                                // Handle backspace
     970                                if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
     971                                        // Insert P element instead of BR
     972                                        if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
     973                                                // Cancel event
     974                                                tinyMCE.execCommand("mceAddUndoLevel");
     975                                                tinyMCE.cancelEvent(e);
     976                                                return false;
     977                                        }
     978                                }
     979
     980                                // Return key pressed
     981                                if (tinyMCE.isMSIE && tinyMCE.settings['force_br_newlines'] && e.keyCode == 13) {
     982                                        if (e.target.editorId)
     983                                                tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
     984
     985                                        if (tinyMCE.selectedInstance) {
     986                                                var sel = tinyMCE.selectedInstance.getDoc().selection;
     987                                                var rng = sel.createRange();
     988
     989                                                if (tinyMCE.getParentElement(rng.parentElement(), "li") != null)
     990                                                        return false;
     991
     992                                                // Cancel event
     993                                                e.returnValue = false;
     994                                                e.cancelBubble = true;
     995
     996                                                // Insert BR element
     997                                                rng.pasteHTML("<br />");
     998                                                rng.collapse(false);
     999                                                rng.select();
     1000
     1001                                                tinyMCE.execCommand("mceAddUndoLevel");
     1002                                                tinyMCE.triggerNodeChange(false);
     1003                                                return false;
     1004                                        }
     1005                                }
     1006
     1007                                // Backspace or delete
     1008                                if (e.keyCode == 8 || e.keyCode == 46) {
     1009                                        tinyMCE.selectedElement = e.target;
     1010                                        tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a");
     1011                                        tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img");
     1012                                        tinyMCE.triggerNodeChange(false);
     1013                                }
     1014
     1015                                return false;
     1016                        break;
     1017
     1018                        case "keyup":
     1019                        case "keydown":
     1020                                tinyMCE.hideMenus();
     1021                                tinyMCE.hasMouseMoved = false;
     1022
     1023                                if (inst && inst.handleShortcut(e))
     1024                                        return false;
     1025
     1026                                if (e.target.editorId)
     1027                                        tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
     1028                                else
     1029                                        return;
     1030
     1031                                if (tinyMCE.selectedInstance)
     1032                                        tinyMCE.selectedInstance.switchSettings();
     1033
     1034                                var inst = tinyMCE.selectedInstance;
     1035
     1036                                // Handle backspace
     1037                                if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
     1038                                        // Insert P element instead of BR
     1039                                        if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
     1040                                                // Cancel event
     1041                                                tinyMCE.execCommand("mceAddUndoLevel");
     1042                                                e.preventDefault();
     1043                                                return false;
     1044                                        }
     1045                                }
     1046
     1047                                tinyMCE.selectedElement = null;
     1048                                tinyMCE.selectedNode = null;
     1049                                var elm = tinyMCE.selectedInstance.getFocusElement();
     1050                                tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a");
     1051                                tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img");
     1052                                tinyMCE.selectedElement = elm;
     1053
     1054                                // Update visualaids on tabs
     1055                                if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9)
     1056                                        tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance);
     1057
     1058                                // Fix empty elements on return/enter, check where enter occured
     1059                                if (tinyMCE.isMSIE && e.type == "keydown" && e.keyCode == 13)
     1060                                        tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement();
     1061
     1062                                // Fix empty elements on return/enter
     1063                                if (tinyMCE.isMSIE && e.type == "keyup" && e.keyCode == 13) {
     1064                                        var elm = tinyMCE.enterKeyElement;
     1065                                        if (elm) {
     1066                                                var re = new RegExp('^HR|IMG|BR$','g'); // Skip these
     1067                                                var dre = new RegExp('^H[1-6]$','g'); // Add double on these
     1068
     1069                                                if (!elm.hasChildNodes() && !re.test(elm.nodeName)) {
     1070                                                        if (dre.test(elm.nodeName))
     1071                                                                elm.innerHTML = "&nbsp;&nbsp;";
     1072                                                        else
     1073                                                                elm.innerHTML = "&nbsp;";
     1074                                                }
     1075                                        }
     1076                                }
     1077
     1078                                // Check if it's a position key
     1079                                var keys = tinyMCE.posKeyCodes;
     1080                                var posKey = false;
     1081                                for (var i=0; i<keys.length; i++) {
     1082                                        if (keys[i] == e.keyCode) {
     1083                                                posKey = true;
     1084                                                break;
     1085                                        }
     1086                                }
     1087
     1088                                // MSIE custom key handling
     1089                                if (tinyMCE.isMSIE && tinyMCE.settings['custom_undo_redo']) {
     1090                                        var keys = new Array(8,46); // Backspace,Delete
     1091                                        for (var i=0; i<keys.length; i++) {
     1092                                                if (keys[i] == e.keyCode) {
     1093                                                        if (e.type == "keyup")
     1094                                                                tinyMCE.triggerNodeChange(false);
     1095                                                }
     1096                                        }
     1097                                }
     1098
     1099                                // If Ctrl key
     1100                                if (e.keyCode == 17)
     1101                                        return true;
     1102
     1103                                // Handle Undo/Redo when typing content
     1104
     1105                                // Start typing (non position key)
     1106                                if (!posKey && e.type == "keyup")
     1107                                        tinyMCE.execCommand("mceStartTyping");
     1108
     1109                                // Store undo bookmark
     1110                                if (e.type == "keydown" && (posKey || e.ctrlKey) && inst)
     1111                                        inst.undoBookmark = inst.selection.getBookmark();
     1112
     1113                                // End typing (position key) or some Ctrl event
     1114                                if (e.type == "keyup" && (posKey || e.ctrlKey))
     1115                                        tinyMCE.execCommand("mceEndTyping");
     1116
     1117                                if (posKey && e.type == "keyup")
     1118                                        tinyMCE.triggerNodeChange(false);
     1119
     1120                                if (tinyMCE.isMSIE && e.ctrlKey)
     1121                                        window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
     1122                        break;
     1123
     1124                        case "mousedown":
     1125                        case "mouseup":
     1126                        case "click":
     1127                        case "focus":
     1128                                tinyMCE.hideMenus();
     1129
     1130                                if (tinyMCE.selectedInstance) {
     1131                                        tinyMCE.selectedInstance.switchSettings();
     1132                                        tinyMCE.selectedInstance.isFocused = true;
     1133                                }
     1134
     1135                                // Check instance event trigged on
     1136                                var targetBody = tinyMCE.getParentElement(e.target, "body");
     1137                                for (var instanceName in tinyMCE.instances) {
     1138                                        if (!tinyMCE.isInstance(tinyMCE.instances[instanceName]))
     1139                                                continue;
     1140
     1141                                        var inst = tinyMCE.instances[instanceName];
     1142
     1143                                        // Reset design mode if lost (on everything just in case)
     1144                                        inst.autoResetDesignMode();
     1145
     1146                                        if (inst.getBody() == targetBody) {
     1147                                                tinyMCE.selectedInstance = inst;
     1148                                                tinyMCE.selectedElement = e.target;
     1149                                                tinyMCE.linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
     1150                                                tinyMCE.imgElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "img");
     1151                                                break;
     1152                                        }
     1153                                }
     1154
     1155                                // Add first bookmark location
     1156                                if (!tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark)
     1157                                        tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark = tinyMCE.selectedInstance.selection.getBookmark();
     1158
     1159                                if (tinyMCE.isSafari) {
     1160                                        tinyMCE.selectedInstance.lastSafariSelection = tinyMCE.selectedInstance.selection.getBookmark();
     1161                                        tinyMCE.selectedInstance.lastSafariSelectedElement = tinyMCE.selectedElement;
     1162
     1163                                        var lnk = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
     1164
     1165                                        // Patch the darned link
     1166                                        if (lnk && e.type == "mousedown") {
     1167                                                lnk.setAttribute("mce_real_href", lnk.getAttribute("href"));
     1168                                                lnk.setAttribute("href", "javascript:void(0);");
     1169                                        }
     1170
     1171                                        // Patch back
     1172                                        if (lnk && e.type == "click") {
     1173                                                window.setTimeout(function() {
     1174                                                        lnk.setAttribute("href", lnk.getAttribute("mce_real_href"));
     1175                                                        lnk.removeAttribute("mce_real_href");
     1176                                                }, 10);
     1177                                        }
     1178                                }
     1179
     1180                                // Reset selected node
     1181                                if (e.type != "focus")
     1182                                        tinyMCE.selectedNode = null;
     1183
     1184                                tinyMCE.triggerNodeChange(false);
     1185                                tinyMCE.execCommand("mceEndTyping");
     1186
     1187                                if (e.type == "mouseup")
     1188                                        tinyMCE.execCommand("mceAddUndoLevel");
     1189
     1190                                // Just in case
     1191                                if (!tinyMCE.selectedInstance && e.target.editorId)
     1192                                        tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
     1193
     1194                                return false;
     1195                        break;
     1196                }
     1197        },
     1198
     1199        getButtonHTML : function(id, lang, img, cmd, ui, val) {
     1200                var h = '', m, x;
     1201
     1202                cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\'';
     1203
     1204                if (typeof(ui) != "undefined" && ui != null)
     1205                        cmd += ',' + ui;
     1206
     1207                if (typeof(val) != "undefined" && val != null)
     1208                        cmd += ",'" + val + "'";
     1209
     1210                cmd += ');';
     1211
     1212                // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled
     1213                if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isMSIE || tinyMCE.isOpera) && (m = this.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) {
     1214                        // Tiled button
     1215                        x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20);
     1216                        h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceTiledButton mceButtonNormal" target="_self">';
     1217                        h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" title="{$' + lang + '}" />';
     1218                        h += '</a>';
     1219                } else {
     1220                        // Normal button
     1221                        h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceButtonNormal" target="_self">';
     1222                        h += '<img src="' + img + '" title="{$' + lang + '}" />';
     1223                        h += '</a>';
     1224                }
     1225
     1226                return h;
     1227        },
     1228
     1229        addButtonMap : function(m) {
     1230                var i, a = m.replace(/\s+/, '').split(',');
     1231
     1232                for (i=0; i<a.length; i++)
     1233                        this.buttonMap[a[i]] = i;
     1234        },
     1235
     1236        submitPatch : function() {
     1237                tinyMCE.removeTinyMCEFormElements(this);
     1238                tinyMCE.triggerSave();
     1239                this.mceOldSubmit();
     1240                tinyMCE.isNotDirty = true;
     1241        },
     1242
     1243        onLoad : function() {
     1244                if (tinyMCE.isMSIE && !tinyMCE.isOpera && window.event.type == "readystatechange" && document.readyState != "complete")
     1245                        return true;
     1246
     1247                if (tinyMCE.isLoaded)
     1248                        return true;
     1249
     1250                tinyMCE.isLoaded = true;
     1251
     1252                tinyMCE.dispatchCallback(null, 'onpageload', 'onPageLoad');
     1253
     1254                for (var c=0; c<tinyMCE.configs.length; c++) {
     1255                        tinyMCE.settings = tinyMCE.configs[c];
     1256
     1257                        var selector = tinyMCE.getParam("editor_selector");
     1258                        var deselector = tinyMCE.getParam("editor_deselector");
     1259                        var elementRefAr = new Array();
     1260
     1261                        // Add submit triggers
     1262                        if (document.forms && tinyMCE.settings['add_form_submit_trigger'] && !tinyMCE.submitTriggers) {
     1263                                for (var i=0; i<document.forms.length; i++) {
     1264                                        var form = document.forms[i];
     1265
     1266                                        tinyMCE.addEvent(form, "submit", TinyMCE_Engine.prototype.handleEvent);
     1267                                        tinyMCE.addEvent(form, "reset", TinyMCE_Engine.prototype.handleEvent);
     1268                                        tinyMCE.submitTriggers = true; // Do it only once
     1269
     1270                                        // Patch the form.submit function
     1271                                        if (tinyMCE.settings['submit_patch']) {
     1272                                                try {
     1273                                                        form.mceOldSubmit = form.submit;
     1274                                                        form.submit = TinyMCE_Engine.prototype.submitPatch;
     1275                                                } catch (e) {
     1276                                                        // Do nothing
     1277                                                }
     1278                                        }
     1279                                }
     1280                        }
     1281
     1282                        // Add editor instances based on mode
     1283                        var mode = tinyMCE.settings['mode'];
     1284                        switch (mode) {
     1285                                case "exact":
     1286                                        var elements = tinyMCE.getParam('elements', '', true, ',');
     1287
     1288                                        for (var i=0; i<elements.length; i++) {
     1289                                                var element = tinyMCE._getElementById(elements[i]);
     1290                                                var trigger = element ? element.getAttribute(tinyMCE.settings['textarea_trigger']) : "";
     1291
     1292                                                if (tinyMCE.getAttrib(element, "class").indexOf(deselector) != -1)
     1293                                                        continue;
     1294
     1295                                                if (trigger == "false")
     1296                                                        continue;
     1297
     1298                                                if ((tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) && element) {
     1299                                                        elementRefAr[elementRefAr.length] = element;
     1300                                                        continue;
     1301                                                }
     1302
     1303                                                if (element)
     1304                                                        tinyMCE.addMCEControl(element, elements[i]);
     1305                                                else if (tinyMCE.settings['debug'])
     1306                                                        alert("Error: Could not find element by id or name: " + elements[i]);
     1307                                        }
     1308                                break;
     1309
     1310                                case "specific_textareas":
     1311                                case "textareas":
     1312                                        var nodeList = document.getElementsByTagName("textarea");
     1313
     1314                                        for (var i=0; i<nodeList.length; i++) {
     1315                                                var elm = nodeList.item(i);
     1316                                                var trigger = elm.getAttribute(tinyMCE.settings['textarea_trigger']);
     1317
     1318                                                if (selector != '' && tinyMCE.getAttrib(elm, "class").indexOf(selector) == -1)
     1319                                                        continue;
     1320
     1321                                                if (selector != '')
     1322                                                        trigger = selector != "" ? "true" : "";
     1323
     1324                                                if (tinyMCE.getAttrib(elm, "class").indexOf(deselector) != -1)
     1325                                                        continue;
     1326
     1327                                                if ((mode == "specific_textareas" && trigger == "true") || (mode == "textareas" && trigger != "false"))
     1328                                                        elementRefAr[elementRefAr.length] = elm;
     1329                                        }
     1330                                break;
     1331                        }
     1332
     1333                        for (var i=0; i<elementRefAr.length; i++) {
     1334                                var element = elementRefAr[i];
     1335                                var elementId = element.name ? element.name : element.id;
     1336
     1337                                if (tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) {
     1338                                        // Focus breaks in Mozilla
     1339                                        if (tinyMCE.isGecko) {
     1340                                                var settings = tinyMCE.settings;
     1341
     1342                                                tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
     1343
     1344                                                if (element.nodeName != "TEXTAREA" && element.nodeName != "INPUT")
     1345                                                        tinyMCE.addEvent(element, "click", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
     1346                                                // tinyMCE.addEvent(element, "mouseover", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
     1347                                        } else {
     1348                                                var settings = tinyMCE.settings;
     1349
     1350                                                tinyMCE.addEvent(element, "focus", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
     1351                                                tinyMCE.addEvent(element, "click", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
     1352                                                // tinyMCE.addEvent(element, "mouseenter", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
     1353                                        }
     1354                                } else
     1355                                        tinyMCE.addMCEControl(element, elementId);
     1356                        }
     1357
     1358                        // Handle auto focus
     1359                        if (tinyMCE.settings['auto_focus']) {
     1360                                window.setTimeout(function () {
     1361                                        var inst = tinyMCE.getInstanceById(tinyMCE.settings['auto_focus']);
     1362                                        inst.selection.selectNode(inst.getBody(), true, true);
     1363                                        inst.contentWindow.focus();
     1364                                }, 10);
     1365                        }
     1366
     1367                        tinyMCE.dispatchCallback(null, 'oninit', 'onInit');
     1368                }
     1369        },
     1370
     1371        isInstance : function(o) {
     1372                return o != null && typeof(o) == "object" && o.isTinyMCE_Control;
     1373        },
     1374
     1375        getParam : function(name, default_value, strip_whitespace, split_chr) {
     1376                var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
     1377
     1378                // Fix bool values
     1379                if (value == "true" || value == "false")
     1380                        return (value == "true");
     1381
     1382                if (strip_whitespace)
     1383                        value = tinyMCE.regexpReplace(value, "[ \t\r\n]", "");
     1384
     1385                if (typeof(split_chr) != "undefined" && split_chr != null) {
     1386                        value = value.split(split_chr);
     1387                        var outArray = new Array();
     1388
     1389                        for (var i=0; i<value.length; i++) {
     1390                                if (value[i] && value[i] != "")
     1391                                        outArray[outArray.length] = value[i];
     1392                        }
     1393
     1394                        value = outArray;
     1395                }
     1396
     1397                return value;
     1398        },
     1399
     1400        getLang : function(name, default_value, parse_entities, va) {
     1401                var v = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name], n;
     1402
     1403                if (parse_entities)
     1404                        v = tinyMCE.entityDecode(v);
     1405
     1406                if (va) {
     1407                        for (n in va)
     1408                                v = this.replaceVar(v, n, va[n]);
     1409                }
     1410
     1411                return v;
     1412        },
     1413
     1414        entityDecode : function(s) {
     1415                var e = document.createElement("div");
     1416                e.innerHTML = s;
     1417                return e.innerHTML;
     1418        },
     1419
     1420        addToLang : function(prefix, ar) {
     1421                for (var key in ar) {
     1422                        if (typeof(ar[key]) == 'function')
     1423                                continue;
     1424
     1425                        tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = ar[key];
     1426                }
     1427
     1428        //      for (var key in ar)
     1429        //              tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = "|" + ar[key] + "|";
     1430        },
     1431
     1432        triggerNodeChange : function(focus, setup_content) {
     1433                if (tinyMCE.selectedInstance) {
     1434                        var inst = tinyMCE.selectedInstance;
     1435                        var editorId = inst.editorId;
     1436                        var elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement();
     1437                        var undoIndex = -1;
     1438                        var undoLevels = -1;
     1439                        var anySelection = false;
     1440                        var selectedText = inst.selection.getSelectedText();
     1441
     1442                        if (setup_content && tinyMCE.isGecko && inst.isHidden())
     1443                                elm = inst.getBody();
     1444
     1445                        inst.switchSettings();
     1446
     1447                        if (tinyMCE.settings["auto_resize"]) {
     1448                                var doc = inst.getDoc();
     1449
     1450                                inst.iframeElement.style.width = doc.body.offsetWidth + "px";
     1451                                inst.iframeElement.style.height = doc.body.offsetHeight + "px";
     1452                        }
     1453
     1454                        if (tinyMCE.selectedElement)
     1455                                anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (selectedText && selectedText.length > 0);
     1456
     1457                        if (tinyMCE.settings['custom_undo_redo']) {
     1458                                undoIndex = inst.undoRedo.undoIndex;
     1459                                undoLevels = inst.undoRedo.undoLevels.length;
     1460                        }
     1461
     1462                        tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content);
     1463                }
     1464
     1465                if (this.selectedInstance && (typeof(focus) == "undefined" || focus))
     1466                        this.selectedInstance.contentWindow.focus();
     1467        },
     1468
     1469        _customCleanup : function(inst, type, content) {
     1470                var pl, po, i;
     1471
     1472                // Call custom cleanup
     1473                var customCleanup = tinyMCE.settings['cleanup_callback'];
     1474                if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined")
     1475                        content = eval(customCleanup + "(type, content, inst);");
     1476
     1477                // Trigger plugin cleanups
     1478                pl = inst.plugins;
     1479                for (i=0; i<pl.length; i++) {
     1480                        po = tinyMCE.plugins[pl[i]];
     1481
     1482                        if (po && po.cleanup)
     1483                                content = po.cleanup(type, content, inst);
     1484                }
     1485
     1486                return content;
     1487        },
     1488
     1489        setContent : function(h) {
     1490                if (tinyMCE.selectedInstance) {
     1491                        tinyMCE.selectedInstance.execCommand('mceSetContent', false, h);
     1492                        tinyMCE.selectedInstance.repaint();
     1493                }
     1494        },
     1495
     1496        importThemeLanguagePack : function(name) {
     1497                if (typeof(name) == "undefined")
     1498                        name = tinyMCE.settings['theme'];
     1499
     1500                tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings['language'] + '.js');
     1501        },
     1502
     1503        importPluginLanguagePack : function(name, valid_languages) {
     1504                var lang = "en", b = tinyMCE.baseURL + '/plugins/' + name;
     1505
     1506                valid_languages = valid_languages.split(',');
     1507                for (var i=0; i<valid_languages.length; i++) {
     1508                        if (tinyMCE.settings['language'] == valid_languages[i])
     1509                                lang = tinyMCE.settings['language'];
     1510                }
     1511
     1512                if (this.plugins[name])
     1513                        b = this.plugins[name].baseURL;
     1514
     1515                tinyMCE.loadScript(b + '/langs/' + lang +  '.js');
     1516        },
     1517
     1518        applyTemplate : function(h, as) {
     1519                var i, s, ar = h.match(new RegExp('\\{\\$[a-z0-9_]+\\}', 'gi'));
     1520
     1521                if (ar && ar.length > 0) {
     1522                        for (i=ar.length-1; i>=0; i--) {
     1523                                s = ar[i].substring(2, ar[i].length-1);
     1524
     1525                                if (s.indexOf('lang_') == 0 && tinyMCELang[s])
     1526                                        h = tinyMCE.replaceVar(h, s, tinyMCELang[s]);
     1527                                else if (as && as[s])
     1528                                        h = tinyMCE.replaceVar(h, s, as[s]);
     1529                                else if (tinyMCE.settings[s])
     1530                                        h = tinyMCE.replaceVar(h, s, tinyMCE.settings[s]);
     1531                        }
     1532                }
     1533
     1534                h = tinyMCE.replaceVar(h, "themeurl", tinyMCE.themeURL);
     1535
     1536                return h;
     1537        },
     1538
     1539        replaceVar : function(h, r, v) {
     1540                return h.replace(new RegExp('{\\\$' + r + '}', 'g'), v);
     1541        },
     1542
     1543        openWindow : function(template, args) {
     1544                var html, width, height, x, y, resizable, scrollbars, url;
     1545
     1546                args['mce_template_file'] = template['file'];
     1547                args['mce_width'] = template['width'];
     1548                args['mce_height'] = template['height'];
     1549                tinyMCE.windowArgs = args;
     1550
     1551                html = template['html'];
     1552                if (!(width = parseInt(template['width'])))
     1553                        width = 320;
     1554
     1555                if (!(height = parseInt(template['height'])))
     1556                        height = 200;
     1557
     1558                // Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!!
     1559                if (tinyMCE.isMSIE)
     1560                        height += 40;
     1561                else
     1562                        height += 20;
     1563
     1564                x = parseInt(screen.width / 2.0) - (width / 2.0);
     1565                y = parseInt(screen.height / 2.0) - (height / 2.0);
     1566
     1567                resizable = (args && args['resizable']) ? args['resizable'] : "no";
     1568                scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
     1569
     1570                if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
     1571                        url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
     1572                else
     1573                        url = template['file'];
     1574
     1575                // Replace all args as variables in URL
     1576                for (var name in args) {
     1577                        if (typeof(args[name]) == 'function')
     1578                                continue;
     1579
     1580                        url = tinyMCE.replaceVar(url, name, escape(args[name]));
     1581                }
     1582
     1583                if (html) {
     1584                        html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']);
     1585                        html = tinyMCE.applyTemplate(html, args);
     1586
     1587                        var win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable);
     1588                        if (win == null) {
     1589                                alert(tinyMCELang['lang_popup_blocked']);
     1590                                return;
     1591                        }
     1592
     1593                        win.document.write(html);
     1594                        win.document.close();
     1595                        win.resizeTo(width, height);
     1596                        win.focus();
     1597                } else {
     1598                        if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {
     1599                                height += 10;
     1600
     1601                                var features = "resizable:" + resizable
     1602                                        + ";scroll:"
     1603                                        + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:"
     1604                                        + width + "px;dialogHeight:" + height + "px;";
     1605
     1606                                window.showModalDialog(url, window, features);
     1607                        } else {
     1608                                var modal = (resizable == "yes") ? "no" : "yes";
     1609
     1610                                if (tinyMCE.isGecko && tinyMCE.isMac)
     1611                                        modal = "no";
     1612
     1613                                if (template['close_previous'] != "no")
     1614                                        try {tinyMCE.lastWindow.close();} catch (ex) {}
     1615
     1616                                var win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable);
     1617                                if (win == null) {
     1618                                        alert(tinyMCELang['lang_popup_blocked']);
     1619                                        return;
     1620                                }
     1621
     1622                                if (template['close_previous'] != "no")
     1623                                        tinyMCE.lastWindow = win;
     1624
     1625                                eval('try { win.resizeTo(width, height); } catch(e) { }');
     1626
     1627                                // Make it bigger if statusbar is forced
     1628                                if (tinyMCE.isGecko) {
     1629                                        if (win.document.defaultView.statusbar.visible)
     1630                                                win.resizeBy(0, tinyMCE.isMac ? 10 : 24);
     1631                                }
     1632
     1633                                win.focus();
     1634                        }
     1635                }
     1636        },
     1637
     1638        closeWindow : function(win) {
     1639                win.close();
     1640        },
     1641
     1642        getVisualAidClass : function(class_name, state) {
     1643                var aidClass = tinyMCE.settings['visual_table_class'];
     1644
     1645                if (typeof(state) == "undefined")
     1646                        state = tinyMCE.settings['visual'];
     1647
     1648                // Split
     1649                var classNames = new Array();
     1650                var ar = class_name.split(' ');
     1651                for (var i=0; i<ar.length; i++) {
     1652                        if (ar[i] == aidClass)
     1653                                ar[i] = "";
     1654
     1655                        if (ar[i] != "")
     1656                                classNames[classNames.length] = ar[i];
     1657                }
     1658
     1659                if (state)
     1660                        classNames[classNames.length] = aidClass;
     1661
     1662                // Glue
     1663                var className = "";
     1664                for (var i=0; i<classNames.length; i++) {
     1665                        if (i > 0)
     1666                                className += " ";
     1667
     1668                        className += classNames[i];
     1669                }
     1670
     1671                return className;
     1672        },
     1673
     1674        handleVisualAid : function(el, deep, state, inst) {
     1675                if (!el)
     1676                        return;
     1677
     1678                var tableElement = null;
     1679
     1680                switch (el.nodeName) {
     1681                        case "TABLE":
     1682                                var oldW = el.style.width;
     1683                                var oldH = el.style.height;
     1684                                var bo = tinyMCE.getAttrib(el, "border");
     1685
     1686                                bo = bo == "" || bo == "0" ? true : false;
     1687
     1688                                tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo));
     1689
     1690                                el.style.width = oldW;
     1691                                el.style.height = oldH;
     1692
     1693                                for (var y=0; y<el.rows.length; y++) {
     1694                                        for (var x=0; x<el.rows[y].cells.length; x++) {
     1695                                                var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);
     1696                                                tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn);
     1697                                        }
     1698                                }
     1699
     1700                                break;
     1701
     1702                        case "A":
     1703                                var anchorName = tinyMCE.getAttrib(el, "name");
     1704
     1705                                if (anchorName != '' && state) {
     1706                                        el.title = anchorName;
     1707                                        el.className = 'mceItemAnchor';
     1708                                } else if (anchorName != '' && !state)
     1709                                        el.className = '';
     1710
     1711                                break;
     1712                }
     1713
     1714                if (deep && el.hasChildNodes()) {
     1715                        for (var i=0; i<el.childNodes.length; i++)
     1716                                tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst);
     1717                }
     1718        },
     1719
     1720        /*
     1721        applyClassesToFonts : function(doc, size) {
     1722                var f = doc.getElementsByTagName("font");
     1723                for (var i=0; i<f.length; i++) {
     1724                        var s = tinyMCE.getAttrib(f[i], "size");
     1725
     1726                        if (s != "")
     1727                                tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s);
     1728                }
     1729
     1730                if (typeof(size) != "undefined") {
     1731                        var css = "";
     1732
     1733                        for (var x=0; x<doc.styleSheets.length; x++) {
     1734                                for (var i=0; i<doc.styleSheets[x].rules.length; i++) {
     1735                                        if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) {
     1736                                                css = doc.styleSheets[x].rules[i].style.cssText;
     1737                                                break;
     1738                                        }
     1739                                }
     1740
     1741                                if (css != "")
     1742                                        break;
     1743                        }
     1744
     1745                        if (doc.styleSheets[0].rules[0].selectorText == "FONT")
     1746                                doc.styleSheets[0].removeRule(0);
     1747
     1748                        doc.styleSheets[0].addRule("FONT", css, 0);
     1749                }
     1750        },
     1751        */
     1752
     1753        fixGeckoBaseHREFBug : function(m, e, h) {
     1754                var nl, i;
     1755
     1756                if (tinyMCE.isGecko) {
     1757                        if (m == 1) {
     1758                                h = h.replace(/\ssrc=/gi, " xsrc=");
     1759                                h = h.replace(/\shref=/gi, " xhref=");
     1760
     1761                                return h;
     1762                        } else {
     1763                                var el = new Array('a','img','select','area','iframe','base','input','script','embed','object','link');
     1764
     1765                                for (var a=0; a<el.length; a++) {
     1766                                        var n = e.getElementsByTagName(el[a]);
     1767
     1768                                        for (i=0; i<n.length; i++) {
     1769                                                var xsrc = tinyMCE.getAttrib(n[i], "xsrc");
     1770                                                var xhref = tinyMCE.getAttrib(n[i], "xhref");
     1771
     1772                                                if (xsrc != "") {
     1773                                                        n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
     1774                                                        n[i].removeAttribute("xsrc");
     1775                                                }
     1776
     1777                                                if (xhref != "") {
     1778                                                        n[i].href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref);
     1779                                                        n[i].removeAttribute("xhref");
     1780                                                }
     1781                                        }
     1782                                }
     1783                        }
     1784                }
     1785
     1786                return h;
     1787        },
     1788
     1789        _setHTML : function(doc, html_content) {
     1790                // Force closed anchors open
     1791                //html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
     1792
     1793                html_content = tinyMCE.cleanupHTMLCode(html_content);
     1794
     1795                // Try innerHTML if it fails use pasteHTML in MSIE
     1796                try {
     1797                        tinyMCE.setInnerHTML(doc.body, html_content);
     1798                } catch (e) {
     1799                        if (this.isMSIE)
     1800                                doc.body.createTextRange().pasteHTML(html_content);
     1801                }
     1802
     1803                // Content duplication bug fix
     1804                if (tinyMCE.isMSIE && tinyMCE.settings['fix_content_duplication']) {
     1805                        // Remove P elements in P elements
     1806                        var paras = doc.getElementsByTagName("P");
     1807                        for (var i=0; i<paras.length; i++) {
     1808                                var node = paras[i];
     1809                                while ((node = node.parentNode) != null) {
     1810                                        if (node.nodeName == "P")
     1811                                                node.outerHTML = node.innerHTML;
     1812                                }
     1813                        }
     1814
     1815                        // Content duplication bug fix (Seems to be word crap)
     1816                        var html = doc.body.innerHTML;
     1817/*
     1818                        if (html.indexOf('="mso') != -1) {
     1819                                for (var i=0; i<doc.body.all.length; i++) {
     1820                                        var el = doc.body.all[i];
     1821                                        el.removeAttribute("className","",0);
     1822                                        el.removeAttribute("style","",0);
     1823                                }
     1824
     1825                                html = doc.body.innerHTML;
     1826                                html = tinyMCE.regexpReplace(html, "<o:p><\/o:p>", "<br />");
     1827                                html = tinyMCE.regexpReplace(html, "<o:p>&nbsp;<\/o:p>", "");
     1828                                html = tinyMCE.regexpReplace(html, "<st1:.*?>", "");
     1829                                html = tinyMCE.regexpReplace(html, "<p><\/p>", "");
     1830                                html = tinyMCE.regexpReplace(html, "<p><\/p>\r\n<p><\/p>", "");
     1831                                html = tinyMCE.regexpReplace(html, "<p>&nbsp;<\/p>", "<br />");
     1832                                html = tinyMCE.regexpReplace(html, "<p>\s*(<p>\s*)?", "<p>");
     1833                                html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "</p>");
     1834                        }*/
     1835
     1836                        // Always set the htmlText output
     1837                        tinyMCE.setInnerHTML(doc.body, html);
     1838                }
     1839
     1840                tinyMCE.cleanupAnchors(doc);
     1841
     1842                if (tinyMCE.getParam("convert_fonts_to_spans"))
     1843                        tinyMCE.convertSpansToFonts(doc);
     1844        },
     1845
     1846        getEditorId : function(form_element) {
     1847                var inst = this.getInstanceById(form_element);
     1848                if (!inst)
     1849                        return null;
     1850
     1851                return inst.editorId;
     1852        },
     1853
     1854        getInstanceById : function(editor_id) {
     1855                var inst = this.instances[editor_id];
     1856                if (!inst) {
     1857                        for (var n in tinyMCE.instances) {
     1858                                var instance = tinyMCE.instances[n];
     1859                                if (!tinyMCE.isInstance(instance))
     1860                                        continue;
     1861
     1862                                if (instance.formTargetElementId == editor_id) {
     1863                                        inst = instance;
     1864                                        break;
     1865                                }
     1866                        }
     1867                }
     1868
     1869                return inst;
     1870        },
     1871
     1872        queryInstanceCommandValue : function(editor_id, command) {
     1873                var inst = tinyMCE.getInstanceById(editor_id);
     1874                if (inst)
     1875                        return inst.queryCommandValue(command);
     1876
     1877                return false;
     1878        },
     1879
     1880        queryInstanceCommandState : function(editor_id, command) {
     1881                var inst = tinyMCE.getInstanceById(editor_id);
     1882                if (inst)
     1883                        return inst.queryCommandState(command);
     1884
     1885                return null;
     1886        },
     1887
     1888        setWindowArg : function(n, v) {
     1889                this.windowArgs[n] = v;
     1890        },
     1891
     1892        getWindowArg : function(n, d) {
     1893                return (typeof(this.windowArgs[n]) == "undefined") ? d : this.windowArgs[n];
     1894        },
     1895
     1896        getCSSClasses : function(editor_id, doc) {
     1897                var output = new Array();
     1898
     1899                // Is cached, use that
     1900                if (typeof(tinyMCE.cssClasses) != "undefined")
     1901                        return tinyMCE.cssClasses;
     1902
     1903                if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") {
     1904                        var instance;
     1905
     1906                        for (var instanceName in tinyMCE.instances) {
     1907                                instance = tinyMCE.instances[instanceName];
     1908                                if (!tinyMCE.isInstance(instance))
     1909                                        continue;
     1910
     1911                                break;
     1912                        }
     1913
     1914                        doc = instance.getDoc();
     1915                }
     1916
     1917                if (typeof(doc) == "undefined") {
     1918                        var instance = tinyMCE.getInstanceById(editor_id);
     1919                        doc = instance.getDoc();
     1920                }
     1921
     1922                if (doc) {
     1923                        var styles = tinyMCE.isMSIE ? doc.styleSheets : doc.styleSheets;
     1924
     1925                        if (styles && styles.length > 0) {
     1926                                for (var x=0; x<styles.length; x++) {
     1927                                        var csses = null;
     1928
     1929                                        // Just ignore any errors
     1930                                        eval("try {var csses = tinyMCE.isMSIE ? doc.styleSheets(" + x + ").rules : doc.styleSheets[" + x + "].cssRules;} catch(e) {}");
     1931                                        if (!csses)
     1932                                                return new Array();
     1933
     1934                                        for (var i=0; i<csses.length; i++) {
     1935                                                var selectorText = csses[i].selectorText;
     1936
     1937                                                // Can be multiple rules per selector
     1938                                                if (selectorText) {
     1939                                                        var rules = selectorText.split(',');
     1940                                                        for (var c=0; c<rules.length; c++) {
     1941                                                                // Invalid rule
     1942                                                                if (rules[c].indexOf(' ') != -1 || rules[c].indexOf(':') != -1 || rules[c].indexOf('mceItem') != -1)
     1943                                                                        continue;
     1944
     1945                                                                if (rules[c] == "." + tinyMCE.settings['visual_table_class'] || rules[c].indexOf('mceEditable') != -1 || rules[c].indexOf('mceNonEditable') != -1)
     1946                                                                        continue;
     1947
     1948                                                                // Is class rule
     1949                                                                if (rules[c].indexOf('.') != -1) {
     1950                                                                        //alert(rules[c].substring(rules[c].indexOf('.')));
     1951                                                                        output[output.length] = rules[c].substring(rules[c].indexOf('.')+1);
     1952                                                                }
     1953                                                        }
     1954                                                }
     1955                                        }
     1956                                }
     1957                        }
     1958                }
     1959
     1960                // Cache em
     1961                if (output.length > 0)
     1962                        tinyMCE.cssClasses = output;
     1963
     1964                return output;
     1965        },
     1966
     1967        regexpReplace : function(in_str, reg_exp, replace_str, opts) {
     1968                if (in_str == null)
     1969                        return in_str;
     1970
     1971                if (typeof(opts) == "undefined")
     1972                        opts = 'g';
     1973
     1974                var re = new RegExp(reg_exp, opts);
     1975                return in_str.replace(re, replace_str);
     1976        },
     1977
     1978        trim : function(s) {
     1979                return s.replace(/^\s*|\s*$/g, "");
     1980        },
     1981
     1982        cleanupEventStr : function(s) {
     1983                s = "" + s;
     1984                s = s.replace('function anonymous()\n{\n', '');
     1985                s = s.replace('\n}', '');
     1986                s = s.replace(/^return true;/gi, ''); // Remove event blocker
     1987
     1988                return s;
     1989        },
     1990
     1991        getControlHTML : function(c) {
     1992                var i, l, n, o, v;
     1993
     1994                l = tinyMCE.plugins;
     1995                for (n in l) {
     1996                        o = l[n];
     1997
     1998                        if (o.getControlHTML && (v = o.getControlHTML(c)) != '')
     1999                                return tinyMCE.replaceVar(v, "pluginurl", o.baseURL);
     2000                }
     2001
     2002                o = tinyMCE.themes[tinyMCE.settings['theme']];
     2003                if (o.getControlHTML && (v = o.getControlHTML(c)) != '')
     2004                        return v;
     2005
     2006                return '';
     2007        },
     2008
     2009        evalFunc : function(f, idx, a) {
     2010                var s = '(', i;
     2011
     2012                for (i=idx; i<a.length; i++) {
     2013                        s += 'a[' + i + ']';
     2014
     2015                        if (i < a.length-1)
     2016                                s += ',';
     2017                }
     2018
     2019                s += ');';
     2020
     2021                return eval("f" + s);
     2022        },
     2023
     2024        dispatchCallback : function(i, p, n) {
     2025                return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments);
     2026        },
     2027
     2028        executeCallback : function(i, p, n) {
     2029                return this.callFunc(i, p, n, 1, this.executeCallback.arguments);
     2030        },
     2031
     2032        execCommandCallback : function(i, p, n) {
     2033                return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments);
     2034        },
     2035
     2036        callFunc : function(ins, p, n, m, a) {
     2037                var l, i, on, o, s, v;
     2038
     2039                s = m == 2;
     2040
     2041                l = tinyMCE.getParam(p, '');
     2042
     2043                if (l != '' && (v = tinyMCE.evalFunc(typeof(l) == "function" ? l : eval(l), 3, a)) == s && m > 0)
     2044                        return true;
     2045
     2046                if (ins != null) {
     2047                        for (i=0, l = ins.plugins; i<l.length; i++) {
     2048                                o = tinyMCE.plugins[l[i]];
     2049
     2050                                if (o[n] && (v = tinyMCE.evalFunc(o[n], 3, a)) == s && m > 0)
     2051                                        return true;
     2052                        }
     2053                }
     2054
     2055                l = tinyMCE.themes;
     2056                for (on in l) {
     2057                        o = l[on];
     2058
     2059                        if (o[n] && (v = tinyMCE.evalFunc(o[n], 3, a)) == s && m > 0)
     2060                                return true;
     2061                }
     2062
     2063                return false;
     2064        },
     2065
     2066        xmlEncode : function(s) {
     2067                s = "" + s;
     2068                s = s.replace(/&/g, '&amp;');
     2069                s = s.replace(new RegExp('"', 'g'), '&quot;');
     2070                s = s.replace(/\'/g, '&#39;'); // &apos; is not working in MSIE
     2071                s = s.replace(/</g, '&lt;');
     2072                s = s.replace(/>/g, '&gt;');
     2073
     2074                return s;
     2075        },
     2076
     2077        extend : function(p, np) {
     2078                var o = {};
     2079
     2080                o.parent = p;
     2081
     2082                for (n in p)
     2083                        o[n] = p[n];
     2084
     2085                for (n in np)
     2086                        o[n] = np[n];
     2087
     2088                return o;
     2089        },
     2090
     2091        hideMenus : function() {
     2092                var e = tinyMCE.lastSelectedMenuBtn;
     2093
     2094                if (tinyMCE.lastMenu) {
     2095                        tinyMCE.lastMenu.hide();
     2096                        tinyMCE.lastMenu = null;
     2097                }
     2098
     2099                if (e) {
     2100                        tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass);
     2101                        tinyMCE.lastSelectedMenuBtn = null;
     2102                }
     2103        }
     2104};
     2105
     2106// Global instances
     2107var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors
     2108var tinyMCE = new TinyMCE_Engine();
     2109var tinyMCELang = {};
     2110
     2111/* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */
     2112
     2113function TinyMCE_Control(settings) {
     2114        var t, i, to, fu, p, x, fn, fu, pn, s = settings;
     2115
     2116        this.undoRedoLevel = true;
     2117        this.isTinyMCE_Control = true;
     2118
     2119        // Default settings
     2120        this.settings = s;
     2121        this.settings['theme'] = tinyMCE.getParam("theme", "default");
     2122        this.settings['width'] = tinyMCE.getParam("width", -1);
     2123        this.settings['height'] = tinyMCE.getParam("height", -1);
     2124        this.selection = new TinyMCE_Selection(this);
     2125        this.undoRedo = new TinyMCE_UndoRedo(this);
     2126        this.cleanup = new TinyMCE_Cleanup();
     2127        this.shortcuts = new Array();
     2128        this.hasMouseMoved = false;
     2129
     2130        this.cleanup.init({
     2131                valid_elements : s.valid_elements,
     2132                extended_valid_elements : s.extended_valid_elements,
     2133                entities : s.entities,
     2134                entity_encoding : s.entity_encoding,
     2135                debug : s.cleanup_debug,
     2136                url_converter : 'TinyMCE_Cleanup.prototype._urlConverter',
     2137                indent : s.apply_source_formatting,
     2138                invalid_elements : s.invalid_elements,
     2139                verify_html : s.verify_html,
     2140                fix_content_duplication : s.fix_content_duplication
     2141        });
     2142
     2143        // Wrap old theme
     2144        t = this.settings['theme'];
     2145        if (!tinyMCE.hasTheme(t)) {
     2146                fn = tinyMCE.callbacks;
     2147                to = {};
     2148
     2149                for (i=0; i<fn.length; i++) {
     2150                        if ((fu = window['TinyMCE_' + t + "_" + fn[i]]))
     2151                                to[fn[i]] = fu;
     2152                }
     2153
     2154                tinyMCE.addTheme(t, to);
     2155        }
     2156
     2157        // Wrap old plugins
     2158        this.plugins = new Array();
     2159        p = tinyMCE.getParam('plugins', '', true, ',');
     2160        if (p.length > 0) {
     2161                for (i=0; i<p.length; i++) {
     2162                        pn = p[i];
     2163
     2164                        if (pn.charAt(0) == '-')
     2165                                pn = pn.substring(1);
     2166
     2167                        if (!tinyMCE.hasPlugin(pn)) {
     2168                                fn = tinyMCE.callbacks;
     2169                                to = {};
     2170
     2171                                for (x=0; x<fn.length; x++) {
     2172                                        if ((fu = window['TinyMCE_' + pn + "_" + fn[x]]))
     2173                                                to[fn[x]] = fu;
     2174                                }
     2175
     2176                                tinyMCE.addPlugin(pn, to);
     2177                        }
     2178
     2179                        this.plugins[this.plugins.length] = pn;
     2180                }
     2181        }
     2182};
     2183
     2184TinyMCE_Control.prototype = {
     2185        hasPlugin : function(n) {
     2186                var i;
     2187
     2188                for (i=0; i<this.plugins.length; i++) {
     2189                        if (this.plugins[i] == n)
     2190                                return true;
     2191                }
     2192
     2193                return false;
     2194        },
     2195
     2196        addPlugin : function(n, p) {
     2197                if (!this.hasPlugin(n)) {
     2198                        tinyMCE.addPlugin(n, p);
     2199                        this.plugins[this.plugins.length] = n;
     2200                }
     2201        },
     2202
     2203        repaint : function() {
     2204                if (tinyMCE.isMSIE && !tinyMCE.isOpera)
     2205                        return;
     2206
     2207                try {
     2208                        var s = this.selection;
     2209                        var b = s.getBookmark(true);
     2210                        this.getBody().style.display = 'none';
     2211                        this.getDoc().execCommand('selectall', false, null);
     2212                        this.getSel().collapseToStart();
     2213                        this.getBody().style.display = 'block';
     2214                        s.moveToBookmark(b);
     2215                } catch (ex) {
     2216                        // Ignore
     2217                }
     2218        },
     2219
     2220        switchSettings : function() {
     2221                if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings['index']) {
     2222                        tinyMCE.settings = this.settings;
     2223                        tinyMCE.currentConfig = this.settings['index'];
     2224                }
     2225        },
     2226
     2227        getBody : function() {
     2228                return this.getDoc().body;
     2229        },
     2230
     2231        getDoc : function() {
     2232                return this.contentWindow.document;
     2233        },
     2234
     2235        getWin : function() {
     2236                return this.contentWindow;
     2237        },
     2238
     2239        addShortcut : function(m, k, d, cmd, ui, va) {
     2240                var n = typeof(k) == "number", ie = tinyMCE.isMSIE, c, sc, i;
     2241                var scl = this.shortcuts;
     2242
     2243                if (!tinyMCE.getParam('custom_shortcuts'))
     2244                        return false;
     2245
     2246                m = m.toLowerCase();
     2247                k = ie && !n ? k.toUpperCase() : k;
     2248                c = n ? null : k.charCodeAt(0);
     2249                d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d;
     2250
     2251                sc = {
     2252                        alt : m.indexOf('alt') != -1,
     2253                        ctrl : m.indexOf('ctrl') != -1,
     2254                        shift : m.indexOf('shift') != -1,
     2255                        charCode : c,
     2256                        keyCode : n ? k : (ie ? c : null),
     2257                        desc : d,
     2258                        cmd : cmd,
     2259                        ui : ui,
     2260                        val : va
     2261                };
     2262
     2263                for (i=0; i<scl.length; i++) {
     2264                        if (sc.alt == scl[i].alt && sc.ctrl == scl[i].ctrl && sc.shift == scl[i].shift
     2265                                && sc.charCode == scl[i].charCode && sc.keyCode == scl[i].keyCode) {
     2266                                return false;
     2267                        }
     2268                }
     2269
     2270                scl[scl.length] = sc;
     2271
     2272                return true;
     2273        },
     2274
     2275        handleShortcut : function(e) {
     2276                var i, s = this.shortcuts, o;
     2277
     2278                for (i=0; i<s.length; i++) {
     2279                        o = s[i];
     2280                        if (o.alt == e.altKey && o.ctrl == e.ctrlKey && (o.keyCode == e.keyCode || o.charCode == e.charCode)) {
     2281                                if (o.cmd && (e.type == "keydown" || (e.type == "keypress" && !tinyMCE.isOpera)))
     2282                                        tinyMCE.execCommand(o.cmd, o.ui, o.val);
     2283
     2284                                tinyMCE.cancelEvent(e);
     2285                                return true;
     2286                        }
     2287                }
     2288
     2289                return false;
     2290        },
     2291
     2292        autoResetDesignMode : function() {
     2293                // Add fix for tab/style.display none/block problems in Gecko
     2294                if (!tinyMCE.isMSIE && this.isHidden() && tinyMCE.getParam('auto_reset_designmode'))
     2295                        eval('try { this.getDoc().designMode = "On"; } catch(e) {}');
     2296        },
     2297
     2298        isHidden : function() {
     2299                if (tinyMCE.isMSIE)
     2300                        return false;
     2301
     2302                var s = this.getSel();
     2303
     2304                // Weird, wheres that cursor selection?
     2305                return (!s || !s.rangeCount || s.rangeCount == 0);
     2306        },
     2307
     2308        isDirty : function() {
     2309                // Is content modified and not in a submit procedure
     2310                return this.startContent != tinyMCE.trim(this.getBody().innerHTML) && !tinyMCE.isNotDirty;
     2311        },
     2312
     2313        _mergeElements : function(scmd, pa, ch, override) {
     2314                if (scmd == "removeformat") {
     2315                        pa.className = "";
     2316                        pa.style.cssText = "";
     2317                        ch.className = "";
     2318                        ch.style.cssText = "";
     2319                        return;
     2320                }
     2321
     2322                var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style"));
     2323                var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style"));
     2324                var className = tinyMCE.getAttrib(pa, "class");
     2325
     2326                className += " " + tinyMCE.getAttrib(ch, "class");
     2327
     2328                if (override) {
     2329                        for (var n in st) {
     2330                                if (typeof(st[n]) == 'function')
     2331                                        continue;
     2332
     2333                                stc[n] = st[n];
     2334                        }
     2335                } else {
     2336                        for (var n in stc) {
     2337                                if (typeof(stc[n]) == 'function')
     2338                                        continue;
     2339
     2340                                st[n] = stc[n];
     2341                        }
     2342                }
     2343
     2344                tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st));
     2345                tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className));
     2346                ch.className = "";
     2347                ch.style.cssText = "";
     2348                ch.removeAttribute("class");
     2349                ch.removeAttribute("style");
     2350        },
     2351
     2352        _setUseCSS : function(b) {
     2353                var d = this.getDoc();
     2354
     2355                try {d.execCommand("useCSS", false, !b);} catch (ex) {}
     2356                try {d.execCommand("styleWithCSS", false, b);} catch (ex) {}
     2357
     2358                if (!tinyMCE.getParam("table_inline_editing"))
     2359                        try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {}
     2360
     2361                if (!tinyMCE.getParam("object_resizing"))
     2362                        try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {}
     2363        },
     2364
     2365        execCommand : function(command, user_interface, value) {
     2366                var doc = this.getDoc();
     2367                var win = this.getWin();
     2368                var focusElm = this.getFocusElement();
     2369
     2370                // Is non udno specific command
     2371                if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command))
     2372                        this.undoBookmark = null;
     2373
     2374                if (this.lastSafariSelection && !new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) {
     2375                        this.selection.moveToBookmark(this.lastSafariSelection);
     2376                        tinyMCE.selectedElement = this.lastSafariSelectedElement;
     2377                }
     2378
     2379                // Mozilla issue
     2380                if (!tinyMCE.isMSIE && !this.useCSS) {
     2381                        this._setUseCSS(false);
     2382                        this.useCSS = true;
     2383                }
     2384
     2385                //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value);
     2386                this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks
     2387
     2388                if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value))
     2389                        return;
     2390
     2391                // Fix align on images
     2392                if (focusElm && focusElm.nodeName == "IMG") {
     2393                        var align = focusElm.getAttribute('align');
     2394                        var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm;
     2395
     2396                        switch (command) {
     2397                                case "JustifyLeft":
     2398                                        if (align == 'left')
     2399                                                img.removeAttribute('align');
     2400                                        else
     2401                                                img.setAttribute('align', 'left');
     2402
     2403                                        // Remove the div
     2404                                        var div = focusElm.parentNode;
     2405                                        if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
     2406                                                div.parentNode.replaceChild(img, div);
     2407
     2408                                        this.selection.selectNode(img);
     2409                                        this.repaint();
     2410                                        tinyMCE.triggerNodeChange();
     2411                                        return;
     2412
     2413                                case "JustifyCenter":
     2414                                        img.removeAttribute('align');
     2415
     2416                                        // Is centered
     2417                                        var div = tinyMCE.getParentElement(focusElm, "div");
     2418                                        if (div && div.style.textAlign == "center") {
     2419                                                // Remove div
     2420                                                if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
     2421                                                        div.parentNode.replaceChild(img, div);
     2422                                        } else {
     2423                                                // Add div
     2424                                                var div = this.getDoc().createElement("div");
     2425                                                div.style.textAlign = 'center';
     2426                                                div.appendChild(img);
     2427                                                focusElm.parentNode.replaceChild(div, focusElm);
     2428                                        }
     2429
     2430                                        this.selection.selectNode(img);
     2431                                        this.repaint();
     2432                                        tinyMCE.triggerNodeChange();
     2433                                        return;
     2434
     2435                                case "JustifyRight":
     2436                                        if (align == 'right')
     2437                                                img.removeAttribute('align');
     2438                                        else
     2439                                                img.setAttribute('align', 'right');
     2440
     2441                                        // Remove the div
     2442                                        var div = focusElm.parentNode;
     2443                                        if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
     2444                                                div.parentNode.replaceChild(img, div);
     2445
     2446                                        this.selection.selectNode(img);
     2447                                        this.repaint();
     2448                                        tinyMCE.triggerNodeChange();
     2449                                        return;
     2450                        }
     2451                }
     2452
     2453                if (tinyMCE.settings['force_br_newlines']) {
     2454                        var alignValue = "";
     2455
     2456                        if (doc.selection.type != "Control") {
     2457                                switch (command) {
     2458                                                case "JustifyLeft":
     2459                                                        alignValue = "left";
     2460                                                        break;
     2461
     2462                                                case "JustifyCenter":
     2463                                                        alignValue = "center";
     2464                                                        break;
     2465
     2466                                                case "JustifyFull":
     2467                                                        alignValue = "justify";
     2468                                                        break;
     2469
     2470                                                case "JustifyRight":
     2471                                                        alignValue = "right";
     2472                                                        break;
     2473                                }
     2474
     2475                                if (alignValue != "") {
     2476                                        var rng = doc.selection.createRange();
     2477
     2478                                        if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null)
     2479                                                divElm.setAttribute("align", alignValue);
     2480                                        else if (rng.pasteHTML && rng.htmlText.length > 0)
     2481                                                rng.pasteHTML('<div align="' + alignValue + '">' + rng.htmlText + "</div>");
     2482
     2483                                        tinyMCE.triggerNodeChange();
     2484                                        return;
     2485                                }
     2486                        }
     2487                }
     2488
     2489                switch (command) {
     2490                        case "mceRepaint":
     2491                                this.repaint();
     2492                                return true;
     2493
     2494                        case "InsertUnorderedList":
     2495                        case "InsertOrderedList":
     2496                                var tag = (command == "InsertUnorderedList") ? "ul" : "ol";
     2497
     2498                                if (tinyMCE.isSafari)
     2499                                        this.execCommand("mceInsertContent", false, "<" + tag + "><li>&nbsp;</li><" + tag + ">");
     2500                                else
     2501                                        this.getDoc().execCommand(command, user_interface, value);
     2502
     2503                                tinyMCE.triggerNodeChange();
     2504                                break;
     2505
     2506                        case "Strikethrough":
     2507                                if (tinyMCE.isSafari)
     2508                                        this.execCommand("mceInsertContent", false, "<strike>" + this.selection.getSelectedHTML() + "</strike>");
     2509                                else
     2510                                        this.getDoc().execCommand(command, user_interface, value);
     2511
     2512                                tinyMCE.triggerNodeChange();
     2513                                break;
     2514
     2515                        case "mceSelectNode":
     2516                                this.selection.selectNode(value);
     2517                                tinyMCE.triggerNodeChange();
     2518                                tinyMCE.selectedNode = value;
     2519                                break;
     2520
     2521                        case "FormatBlock":
     2522                                if (value == null || value == "") {
     2523                                        var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address");
     2524
     2525                                        if (elm)
     2526                                                this.execCommand("mceRemoveNode", false, elm);
     2527                                } else {
     2528                                        if (value == '<div>' && tinyMCE.isGecko)
     2529                                                value = 'div';
     2530
     2531                                        this.getDoc().execCommand("FormatBlock", false, value);
     2532                                }
     2533
     2534                                tinyMCE.triggerNodeChange();
     2535
     2536                                break;
     2537
     2538                        case "mceRemoveNode":
     2539                                if (!value)
     2540                                        value = tinyMCE.getParentElement(this.getFocusElement());
     2541
     2542                                if (tinyMCE.isMSIE) {
     2543                                        value.outerHTML = value.innerHTML;
     2544                                } else {
     2545                                        var rng = value.ownerDocument.createRange();
     2546                                        rng.setStartBefore(value);
     2547                                        rng.setEndAfter(value);
     2548                                        rng.deleteContents();
     2549                                        rng.insertNode(rng.createContextualFragment(value.innerHTML));
     2550                                }
     2551
     2552                                tinyMCE.triggerNodeChange();
     2553
     2554                                break;
     2555
     2556                        case "mceSelectNodeDepth":
     2557                                var parentNode = this.getFocusElement();
     2558                                for (var i=0; parentNode; i++) {
     2559                                        if (parentNode.nodeName.toLowerCase() == "body")
     2560                                                break;
     2561
     2562                                        if (parentNode.nodeName.toLowerCase() == "#text") {
     2563                                                i--;
     2564                                                parentNode = parentNode.parentNode;
     2565                                                continue;
     2566                                        }
     2567
     2568                                        if (i == value) {
     2569                                                this.selection.selectNode(parentNode, false);
     2570                                                tinyMCE.triggerNodeChange();
     2571                                                tinyMCE.selectedNode = parentNode;
     2572                                                return;
     2573                                        }
     2574
     2575                                        parentNode = parentNode.parentNode;
     2576                                }
     2577
     2578                                break;
     2579
     2580                        case "SetStyleInfo":
     2581                                var rng = this.getRng();
     2582                                var sel = this.getSel();
     2583                                var scmd = value['command'];
     2584                                var sname = value['name'];
     2585                                var svalue = value['value'] == null ? '' : value['value'];
     2586                                //var svalue = value['value'] == null ? '' : value['value'];
     2587                                var wrapper = value['wrapper'] ? value['wrapper'] : "span";
     2588                                var parentElm = null;
     2589                                var invalidRe = new RegExp("^BODY|HTML$", "g");
     2590                                var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null;
     2591
     2592                                // Whole element selected check
     2593                                if (tinyMCE.isMSIE) {
     2594                                        // Control range
     2595                                        if (rng.item)
     2596                                                parentElm = rng.item(0);
     2597                                        else {
     2598                                                var pelm = rng.parentElement();
     2599                                                var prng = doc.selection.createRange();
     2600                                                prng.moveToElementText(pelm);
     2601
     2602                                                if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) {
     2603                                                        if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName))
     2604                                                                parentElm = pelm;
     2605                                                }
     2606                                        }
     2607                                } else {
     2608                                        var felm = this.getFocusElement();
     2609                                        if (sel.isCollapsed || (new RegExp('td|tr|tbody|table', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode))
     2610                                                parentElm = felm;
     2611                                }
     2612
     2613                                // Whole element selected
     2614                                if (parentElm && !invalidRe.test(parentElm.nodeName)) {
     2615                                        if (scmd == "setstyle")
     2616                                                tinyMCE.setStyleAttrib(parentElm, sname, svalue);
     2617
     2618                                        if (scmd == "setattrib")
     2619                                                tinyMCE.setAttrib(parentElm, sname, svalue);
     2620
     2621                                        if (scmd == "removeformat") {
     2622                                                parentElm.style.cssText = '';
     2623                                                tinyMCE.setAttrib(parentElm, 'class', '');
     2624                                        }
     2625
     2626                                        // Remove style/attribs from all children
     2627                                        var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1);
     2628                                        for (var z=0; z<ch.length; z++) {
     2629                                                if (ch[z] == parentElm)
     2630                                                        continue;
     2631
     2632                                                if (scmd == "setstyle")
     2633                                                        tinyMCE.setStyleAttrib(ch[z], sname, '');
     2634
     2635                                                if (scmd == "setattrib")
     2636                                                        tinyMCE.setAttrib(ch[z], sname, '');
     2637
     2638                                                if (scmd == "removeformat") {
     2639                                                        ch[z].style.cssText = '';
     2640                                                        tinyMCE.setAttrib(ch[z], 'class', '');
     2641                                                }
     2642                                        }
     2643                                } else {
     2644                                        this._setUseCSS(false); // Bug in FF when running in fullscreen
     2645                                        doc.execCommand("FontName", false, "#mce_temp_font#");
     2646                                        var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#");
     2647
     2648                                        // Change them all
     2649                                        for (var x=0; x<elementArray.length; x++) {
     2650                                                elm = elementArray[x];
     2651                                                if (elm) {
     2652                                                        var spanElm = doc.createElement(wrapper);
     2653
     2654                                                        if (scmd == "setstyle")
     2655                                                                tinyMCE.setStyleAttrib(spanElm, sname, svalue);
     2656
     2657                                                        if (scmd == "setattrib")
     2658                                                                tinyMCE.setAttrib(spanElm, sname, svalue);
     2659
     2660                                                        if (scmd == "removeformat") {
     2661                                                                spanElm.style.cssText = '';
     2662                                                                tinyMCE.setAttrib(spanElm, 'class', '');
     2663                                                        }
     2664
     2665                                                        if (elm.hasChildNodes()) {
     2666                                                                for (var i=0; i<elm.childNodes.length; i++)
     2667                                                                        spanElm.appendChild(elm.childNodes[i].cloneNode(true));
     2668                                                        }
     2669
     2670                                                        spanElm.setAttribute("mce_new", "true");
     2671                                                        elm.parentNode.replaceChild(spanElm, elm);
     2672
     2673                                                        // Remove style/attribs from all children
     2674                                                        var ch = tinyMCE.getNodeTree(spanElm, new Array(), 1);
     2675                                                        for (var z=0; z<ch.length; z++) {
     2676                                                                if (ch[z] == spanElm)
     2677                                                                        continue;
     2678
     2679                                                                if (scmd == "setstyle")
     2680                                                                        tinyMCE.setStyleAttrib(ch[z], sname, '');
     2681
     2682                                                                if (scmd == "setattrib")
     2683                                                                        tinyMCE.setAttrib(ch[z], sname, '');
     2684
     2685                                                                if (scmd == "removeformat") {
     2686                                                                        ch[z].style.cssText = '';
     2687                                                                        tinyMCE.setAttrib(ch[z], 'class', '');
     2688                                                                }
     2689                                                        }
     2690                                                }
     2691                                        }
     2692                                }
     2693
     2694                                // Cleaup wrappers
     2695                                var nodes = doc.getElementsByTagName(wrapper);
     2696                                for (var i=nodes.length-1; i>=0; i--) {
     2697                                        var elm = nodes[i];
     2698                                        var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true";
     2699
     2700                                        elm.removeAttribute("mce_new");
     2701
     2702                                        // Is only child a element
     2703                                        if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) {
     2704                                                //tinyMCE.debug("merge1" + isNew);
     2705                                                this._mergeElements(scmd, elm, elm.childNodes[0], isNew);
     2706                                                continue;
     2707                                        }
     2708
     2709                                        // Is I the only child
     2710                                        if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) {
     2711                                                //tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName);
     2712                                                if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName))
     2713                                                        this._mergeElements(scmd, elm.parentNode, elm, false);
     2714                                        }
     2715                                }
     2716
     2717                                // Remove empty wrappers
     2718                                var nodes = doc.getElementsByTagName(wrapper);
     2719                                for (var i=nodes.length-1; i>=0; i--) {
     2720                                        var elm = nodes[i];
     2721                                        var isEmpty = true;
     2722
     2723                                        // Check if it has any attribs
     2724                                        var tmp = doc.createElement("body");
     2725                                        tmp.appendChild(elm.cloneNode(false));
     2726
     2727                                        // Is empty span, remove it
     2728                                        tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), '');
     2729                                        //tinyMCE.debug(tmp.innerHTML);
     2730                                        if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) {
     2731                                                for (var x=0; x<elm.childNodes.length; x++) {
     2732                                                        if (elm.parentNode != null)
     2733                                                                elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm);
     2734                                                }
     2735
     2736                                                elm.parentNode.removeChild(elm);
     2737                                        }
     2738                                }
     2739
     2740                                // Re add the visual aids
     2741                                if (scmd == "removeformat")
     2742                                        tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
     2743
     2744                                tinyMCE.triggerNodeChange();
     2745
     2746                                break;
     2747
     2748                        case "FontName":
     2749                                if (value == null) {
     2750                                        var s = this.getSel();
     2751
     2752                                        // Find font and select it
     2753                                        if (tinyMCE.isGecko && s.isCollapsed) {
     2754                                                var f = tinyMCE.getParentElement(this.getFocusElement(), "font");
     2755
     2756                                                if (f != null)
     2757                                                        this.selection.selectNode(f, false);
     2758                                        }
     2759
     2760                                        // Remove format
     2761                                        this.getDoc().execCommand("RemoveFormat", false, null);
     2762
     2763                                        // Collapse range if font was found
     2764                                        if (f != null && tinyMCE.isGecko) {
     2765                                                var r = this.getRng().cloneRange();
     2766                                                r.collapse(true);
     2767                                                s.removeAllRanges();
     2768                                                s.addRange(r);
     2769                                        }
     2770                                } else
     2771                                        this.getDoc().execCommand('FontName', false, value);
     2772
     2773                                if (tinyMCE.isGecko)
     2774                                        window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
     2775
     2776                                return;
     2777
     2778                        case "FontSize":
     2779                                this.getDoc().execCommand('FontSize', false, value);
     2780
     2781                                if (tinyMCE.isGecko)
     2782                                        window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
     2783
     2784                                return;
     2785
     2786                        case "forecolor":
     2787                                this.getDoc().execCommand('forecolor', false, value);
     2788                                break;
     2789
     2790                        case "HiliteColor":
     2791                                if (tinyMCE.isGecko) {
     2792                                        this._setUseCSS(true);
     2793                                        this.getDoc().execCommand('hilitecolor', false, value);
     2794                                        this._setUseCSS(false);
     2795                                } else
     2796                                        this.getDoc().execCommand('BackColor', false, value);
     2797                                break;
     2798
     2799                        case "Cut":
     2800                        case "Copy":
     2801                        case "Paste":
     2802                                var cmdFailed = false;
     2803
     2804                                // Try executing command
     2805                                eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}');
     2806
     2807                                if (tinyMCE.isOpera && cmdFailed)
     2808                                        alert('Currently not supported by your browser, use keyboard shortcuts instead.');
     2809
     2810                                // Alert error in gecko if command failed
     2811                                if (tinyMCE.isGecko && cmdFailed) {
     2812                                        // Confirm more info
     2813                                        if (confirm(tinyMCE.entityDecode(tinyMCE.getLang('lang_clipboard_msg'))))
     2814                                                window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
     2815
     2816                                        return;
     2817                                } else
     2818                                        tinyMCE.triggerNodeChange();
     2819                        break;
     2820
     2821                        case "mceSetContent":
     2822                                if (!value)
     2823                                        value = "";
     2824
     2825                                // Call custom cleanup code
     2826                                value = tinyMCE.storeAwayURLs(value);
     2827                                value = tinyMCE._customCleanup(this, "insert_to_editor", value);
     2828                                tinyMCE._setHTML(doc, value);
     2829                                tinyMCE.setInnerHTML(doc.body, tinyMCE._cleanupHTML(this, doc, tinyMCE.settings, doc.body));
     2830                                tinyMCE.convertAllRelativeURLs(doc.body);
     2831
     2832                                // When editing always use fonts internaly
     2833                                if (tinyMCE.getParam("convert_fonts_to_spans"))
     2834                                        tinyMCE.convertSpansToFonts(doc);
     2835
     2836                                tinyMCE.handleVisualAid(doc.body, true, this.visualAid, this);
     2837                                tinyMCE._setEventsEnabled(doc.body, false);
     2838                                return true;
     2839
     2840                        case "mceCleanup":
     2841                                var b = this.selection.getBookmark();
     2842                                tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML);
     2843                                tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid));
     2844                                tinyMCE.convertAllRelativeURLs(doc.body);
     2845
     2846                                // When editing always use fonts internaly
     2847                                if (tinyMCE.getParam("convert_fonts_to_spans"))
     2848                                        tinyMCE.convertSpansToFonts(doc);
     2849
     2850                                tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
     2851                                tinyMCE._setEventsEnabled(this.getBody(), false);
     2852                                this.repaint();
     2853                                this.selection.moveToBookmark(b);
     2854                                tinyMCE.triggerNodeChange();
     2855                        break;
     2856
     2857                        case "mceReplaceContent":
     2858                                // Force empty string
     2859                                if (!value)
     2860                                        value = '';
     2861
     2862                                this.getWin().focus();
     2863
     2864                                var selectedText = "";
     2865
     2866                                if (tinyMCE.isMSIE) {
     2867                                        var rng = doc.selection.createRange();
     2868                                        selectedText = rng.text;
     2869                                } else
     2870                                        selectedText = this.getSel().toString();
     2871
     2872                                if (selectedText.length > 0) {
     2873                                        value = tinyMCE.replaceVar(value, "selection", selectedText);
     2874                                        tinyMCE.execCommand('mceInsertContent', false, value);
     2875                                }
     2876
     2877                                tinyMCE.triggerNodeChange();
     2878                        break;
     2879
     2880                        case "mceSetAttribute":
     2881                                if (typeof(value) == 'object') {
     2882                                        var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets'];
     2883                                        var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms);
     2884
     2885                                        if (targetNode) {
     2886                                                targetNode.setAttribute(value['name'], value['value']);
     2887                                                tinyMCE.triggerNodeChange();
     2888                                        }
     2889                                }
     2890                        break;
     2891
     2892                        case "mceSetCSSClass":
     2893                                this.execCommand("SetStyleInfo", false, {command : "setattrib", name : "class", value : value});
     2894                        break;
     2895
     2896                        case "mceInsertRawHTML":
     2897                                var key = 'tiny_mce_marker';
     2898
     2899                                this.execCommand('mceBeginUndoLevel');
     2900
     2901                                // Insert marker key
     2902                                this.execCommand('mceInsertContent', false, key);
     2903
     2904                                // Store away scroll pos
     2905                                var scrollX = this.getDoc().body.scrollLeft + this.getDoc().documentElement.scrollLeft;
     2906                                var scrollY = this.getDoc().body.scrollTop + this.getDoc().documentElement.scrollTop;
     2907
     2908                                // Find marker and replace with RAW HTML
     2909                                var html = this.getBody().innerHTML;
     2910                                if ((pos = html.indexOf(key)) != -1)
     2911                                        tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length));
     2912
     2913                                // Restore scoll pos
     2914                                this.contentWindow.scrollTo(scrollX, scrollY);
     2915
     2916                                this.execCommand('mceEndUndoLevel');
     2917
     2918                                break;
     2919
     2920                        case "mceInsertContent":
     2921                                // Force empty string
     2922                                if (!value)
     2923                                        value = '';
     2924
     2925                                var insertHTMLFailed = false;
     2926                                this.getWin().focus();
     2927
     2928                                if (tinyMCE.isGecko || tinyMCE.isOpera) {
     2929                                        try {
     2930                                                // Is plain text or HTML, &amp;, &nbsp; etc will be encoded wrong in FF
     2931                                                if (value.indexOf('<') == -1 && !value.match(/(&#38;|&#160;|&#60;|&#62;)/g)) {
     2932                                                        var r = this.getRng();
     2933                                                        var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value));
     2934                                                        var s = this.getSel();
     2935                                                        var r2 = r.cloneRange();
     2936
     2937                                                        // Insert text at cursor position
     2938                                                        s.removeAllRanges();
     2939                                                        r.deleteContents();
     2940                                                        r.insertNode(n);
     2941
     2942                                                        // Move the cursor to the end of text
     2943                                                        r2.selectNode(n);
     2944                                                        r2.collapse(false);
     2945                                                        s.removeAllRanges();
     2946                                                        s.addRange(r2);
     2947                                                } else {
     2948                                                        value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value);
     2949                                                        this.getDoc().execCommand('inserthtml', false, value);
     2950                                                        tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
     2951                                                }
     2952                                        } catch (ex) {
     2953                                                insertHTMLFailed = true;
     2954                                        }
     2955
     2956                                        if (!insertHTMLFailed) {
     2957                                                tinyMCE.triggerNodeChange();
     2958                                                return;
     2959                                        }
     2960                                }
     2961
     2962                                // Ugly hack in Opera due to non working "inserthtml"
     2963                                if (tinyMCE.isOpera && insertHTMLFailed) {
     2964                                        this.getDoc().execCommand("insertimage", false, tinyMCE.uniqueURL);
     2965                                        var ar = tinyMCE.getElementsByAttributeValue(this.getBody(), "img", "src", tinyMCE.uniqueURL);
     2966                                        ar[0].outerHTML = value;
     2967                                        return;
     2968                                }
     2969
     2970                                if (!tinyMCE.isMSIE) {
     2971                                        var isHTML = value.indexOf('<') != -1;
     2972                                        var sel = this.getSel();
     2973                                        var rng = this.getRng();
     2974
     2975                                        if (isHTML) {
     2976                                                if (tinyMCE.isSafari) {
     2977                                                        var tmpRng = this.getDoc().createRange();
     2978
     2979                                                        tmpRng.setStart(this.getBody(), 0);
     2980                                                        tmpRng.setEnd(this.getBody(), 0);
     2981
     2982                                                        value = tmpRng.createContextualFragment(value);
     2983                                                } else
     2984                                                        value = rng.createContextualFragment(value);
     2985                                        } else {
     2986                                                // Setup text node
     2987                                                var el = document.createElement("div");
     2988                                                el.innerHTML = value;
     2989                                                value = el.firstChild.nodeValue;
     2990                                                value = doc.createTextNode(value);
     2991                                        }
     2992
     2993                                        // Insert plain text in Safari
     2994                                        if (tinyMCE.isSafari && !isHTML) {
     2995                                                this.execCommand('InsertText', false, value.nodeValue);
     2996                                                tinyMCE.triggerNodeChange();
     2997                                                return true;
     2998                                        } else if (tinyMCE.isSafari && isHTML) {
     2999                                                rng.deleteContents();
     3000                                                rng.insertNode(value);
     3001                                                tinyMCE.triggerNodeChange();
     3002                                                return true;
     3003                                        }
     3004
     3005                                        rng.deleteContents();
     3006
     3007                                        // If target node is text do special treatment, (Mozilla 1.3 fix)
     3008                                        if (rng.startContainer.nodeType == 3) {
     3009                                                var node = rng.startContainer.splitText(rng.startOffset);
     3010                                                node.parentNode.insertBefore(value, node);
     3011                                        } else
     3012                                                rng.insertNode(value);
     3013
     3014                                        if (!isHTML) {
     3015                                                // Removes weird selection trails
     3016                                                sel.selectAllChildren(doc.body);
     3017                                                sel.removeAllRanges();
     3018
     3019                                                // Move cursor to end of content
     3020                                                var rng = doc.createRange();
     3021
     3022                                                rng.selectNode(value);
     3023                                                rng.collapse(false);
     3024
     3025                                                sel.addRange(rng);
     3026                                        } else
     3027                                                rng.collapse(false);
     3028
     3029                                        tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
     3030                                } else {
     3031                                        var rng = doc.selection.createRange();
     3032                                        var c = value.indexOf('<!--') != -1;
     3033
     3034                                        // Fix comment bug, add tag before comments
     3035                                        if (c)
     3036                                                value = tinyMCE.uniqueTag + value;
     3037
     3038                                        if (rng.item)
     3039                                                rng.item(0).outerHTML = value;
     3040                                        else
     3041                                                rng.pasteHTML(value);
     3042
     3043                                        // Remove unique tag
     3044                                        if (c) {
     3045                                                var e = this.getDoc().getElementById('mceTMPElement');
     3046                                                e.parentNode.removeChild(e);
     3047                                        }
     3048                                }
     3049
     3050                                tinyMCE.triggerNodeChange();
     3051                        break;
     3052
     3053                        case "mceStartTyping":
     3054                                if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex == -1) {
     3055                                        this.undoRedo.typingUndoIndex = this.undoRedo.undoIndex;
     3056                                        this.execCommand('mceAddUndoLevel');
     3057                                        //tinyMCE.debug("mceStartTyping");
     3058                                }
     3059                                break;
     3060
     3061                        case "mceEndTyping":
     3062                                if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex != -1) {
     3063                                        this.execCommand('mceAddUndoLevel');
     3064                                        this.undoRedo.typingUndoIndex = -1;
     3065                                        //tinyMCE.debug("mceEndTyping");
     3066                                }
     3067                                break;
     3068
     3069                        case "mceBeginUndoLevel":
     3070                                this.undoRedoLevel = false;
     3071                                break;
     3072
     3073                        case "mceEndUndoLevel":
     3074                                this.undoRedoLevel = true;
     3075                                this.execCommand('mceAddUndoLevel');
     3076                                break;
     3077
     3078                        case "mceAddUndoLevel":
     3079                                if (tinyMCE.settings['custom_undo_redo'] && this.undoRedoLevel) {
     3080                                        if (this.undoRedo.add())
     3081                                                tinyMCE.triggerNodeChange(false);
     3082                                }
     3083                                break;
     3084
     3085                        case "Undo":
     3086                                if (tinyMCE.settings['custom_undo_redo']) {
     3087                                        tinyMCE.execCommand("mceEndTyping");
     3088                                        this.undoRedo.undo();
     3089                                        tinyMCE.triggerNodeChange();
     3090                                } else
     3091                                        this.getDoc().execCommand(command, user_interface, value);
     3092                                break;
     3093
     3094                        case "Redo":
     3095                                if (tinyMCE.settings['custom_undo_redo']) {
     3096                                        tinyMCE.execCommand("mceEndTyping");
     3097                                        this.undoRedo.redo();
     3098                                        tinyMCE.triggerNodeChange();
     3099                                } else
     3100                                        this.getDoc().execCommand(command, user_interface, value);
     3101                                break;
     3102
     3103                        case "mceToggleVisualAid":
     3104                                this.visualAid = !this.visualAid;
     3105                                tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
     3106                                tinyMCE.triggerNodeChange();
     3107                                break;
     3108
     3109                        case "Indent":
     3110                                this.getDoc().execCommand(command, user_interface, value);
     3111                                tinyMCE.triggerNodeChange();
     3112                                if (tinyMCE.isMSIE) {
     3113                                        var n = tinyMCE.getParentElement(this.getFocusElement(), "blockquote");
     3114                                        do {
     3115                                                if (n && n.nodeName == "BLOCKQUOTE") {
     3116                                                        n.removeAttribute("dir");
     3117                                                        n.removeAttribute("style");
     3118                                                }
     3119                                        } while (n != null && (n = n.parentNode) != null);
     3120                                }
     3121                                break;
     3122
     3123                        case "removeformat":
     3124                                var text = this.selection.getSelectedText();
     3125
     3126                                if (tinyMCE.isOpera) {
     3127                                        this.getDoc().execCommand("RemoveFormat", false, null);
     3128                                        return;
     3129                                }
     3130
     3131                                if (tinyMCE.isMSIE) {
     3132                                        try {
     3133                                                var rng = doc.selection.createRange();
     3134                                                rng.execCommand("RemoveFormat", false, null);
     3135                                        } catch (e) {
     3136                                                // Do nothing
     3137                                        }
     3138
     3139                                        this.execCommand("SetStyleInfo", false, {command : "removeformat"});
     3140                                } else {
     3141                                        this.getDoc().execCommand(command, user_interface, value);
     3142
     3143                                        this.execCommand("SetStyleInfo", false, {command : "removeformat"});
     3144                                }
     3145
     3146                                // Remove class
     3147                                if (text.length == 0)
     3148                                        this.execCommand("mceSetCSSClass", false, "");
     3149
     3150                                tinyMCE.triggerNodeChange();
     3151                                break;
     3152
     3153                        default:
     3154                                this.getDoc().execCommand(command, user_interface, value);
     3155
     3156                                if (tinyMCE.isGecko)
     3157                                        window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
     3158                                else
     3159                                        tinyMCE.triggerNodeChange();
     3160                }
     3161
     3162                // Add undo level after modification
     3163                if (command != "mceAddUndoLevel" && command != "Undo" && command != "Redo" && command != "mceStartTyping" && command != "mceEndTyping")
     3164                        tinyMCE.execCommand("mceAddUndoLevel");
     3165        },
     3166
     3167        queryCommandValue : function(c) {
     3168                try {
     3169                        return this.getDoc().queryCommandValue(c);
     3170                } catch (e) {
     3171                        return null;
     3172                }
     3173        },
     3174
     3175        queryCommandState : function(c) {
     3176                return this.getDoc().queryCommandState(c);
     3177        },
     3178
     3179        _onAdd : function(replace_element, form_element_name, target_document) {
     3180                var hc, th, to, editorTemplate;
     3181
     3182                th = this.settings['theme'];
     3183                to = tinyMCE.themes[th];
     3184
     3185                var targetDoc = target_document ? target_document : document;
     3186
     3187                this.targetDoc = targetDoc;
     3188
     3189                tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme'];
     3190                this.settings['themeurl'] = tinyMCE.themeURL;
     3191
     3192                if (!replace_element) {
     3193                        alert("Error: Could not find the target element.");
     3194                        return false;
     3195                }
     3196
     3197                if (to.getEditorTemplate)
     3198                        editorTemplate = to.getEditorTemplate(this.settings, this.editorId);
     3199
     3200                var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0;
     3201                var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0;
     3202                var html = '<span id="' + this.editorId + '_parent" class="mceEditorContainer">' + editorTemplate['html'];
     3203
     3204                html = tinyMCE.replaceVar(html, "editor_id", this.editorId);
     3205                this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm";
     3206
     3207                this.settings['old_width'] = this.settings['width'];
     3208                this.settings['old_height'] = this.settings['height'];
     3209
     3210                // Set default width, height
     3211                if (this.settings['width'] == -1)
     3212                        this.settings['width'] = replace_element.offsetWidth;
     3213
     3214                if (this.settings['height'] == -1)
     3215                        this.settings['height'] = replace_element.offsetHeight;
     3216
     3217                // Try the style width
     3218                if (this.settings['width'] == 0)
     3219                        this.settings['width'] = replace_element.style.width;
     3220
     3221                // Try the style height
     3222                if (this.settings['height'] == 0)
     3223                        this.settings['height'] = replace_element.style.height;
     3224
     3225                // If no width/height then default to 320x240, better than nothing
     3226                if (this.settings['width'] == 0)
     3227                        this.settings['width'] = 320;
     3228
     3229                if (this.settings['height'] == 0)
     3230                        this.settings['height'] = 240;
     3231
     3232                this.settings['area_width'] = parseInt(this.settings['width']);
     3233                this.settings['area_height'] = parseInt(this.settings['height']);
     3234                this.settings['area_width'] += deltaWidth;
     3235                this.settings['area_height'] += deltaHeight;
     3236
     3237                // Special % handling
     3238                if (("" + this.settings['width']).indexOf('%') != -1)
     3239                        this.settings['area_width'] = "100%";
     3240
     3241                if (("" + this.settings['height']).indexOf('%') != -1)
     3242                        this.settings['area_height'] = "100%";
     3243
     3244                if (("" + replace_element.style.width).indexOf('%') != -1) {
     3245                        this.settings['width'] = replace_element.style.width;
     3246                        this.settings['area_width'] = "100%";
     3247                }
     3248
     3249                if (("" + replace_element.style.height).indexOf('%') != -1) {
     3250                        this.settings['height'] = replace_element.style.height;
     3251                        this.settings['area_height'] = "100%";
     3252                }
     3253
     3254                html = tinyMCE.applyTemplate(html);
     3255
     3256                this.settings['width'] = this.settings['old_width'];
     3257                this.settings['height'] = this.settings['old_height'];
     3258
     3259                this.visualAid = this.settings['visual'];
     3260                this.formTargetElementId = form_element_name;
     3261
     3262                // Get replace_element contents
     3263                if (replace_element.nodeName == "TEXTAREA" || replace_element.nodeName == "INPUT")
     3264                        this.startContent = replace_element.value;
     3265                else
     3266                        this.startContent = replace_element.innerHTML;
     3267
     3268                // If not text area or input
     3269                if (replace_element.nodeName != "TEXTAREA" && replace_element.nodeName != "INPUT") {
     3270                        this.oldTargetElement = replace_element;
     3271
     3272                        // Debug mode
     3273                        if (tinyMCE.settings['debug']) {
     3274                                hc = '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>';
     3275                        } else {
     3276                                hc = '<input type="hidden" type="text" id="' + form_element_name + '" name="' + form_element_name + '" />';
     3277                                this.oldTargetElement.style.display = "none";
     3278                        }
     3279
     3280                        html += '</span>';
     3281
     3282                        if (tinyMCE.isGecko)
     3283                                html = hc + html;
     3284                        else
     3285                                html += hc;
     3286
     3287                        // Output HTML and set editable
     3288                        if (tinyMCE.isGecko) {
     3289                                var rng = replace_element.ownerDocument.createRange();
     3290                                rng.setStartBefore(replace_element);
     3291
     3292                                var fragment = rng.createContextualFragment(html);
     3293                                tinyMCE.insertAfter(fragment, replace_element);
     3294                        } else
     3295                                replace_element.insertAdjacentHTML("beforeBegin", html);
     3296                } else {
     3297                        html += '</span>';
     3298
     3299                        // Just hide the textarea element
     3300                        this.oldTargetElement = replace_element;
     3301
     3302                        if (!tinyMCE.settings['debug'])
     3303                                this.oldTargetElement.style.display = "none";
     3304
     3305                        // Output HTML and set editable
     3306                        if (tinyMCE.isGecko) {
     3307                                var rng = replace_element.ownerDocument.createRange();
     3308                                rng.setStartBefore(replace_element);
     3309
     3310                                var fragment = rng.createContextualFragment(html);
     3311                                tinyMCE.insertAfter(fragment, replace_element);
     3312                        } else
     3313                                replace_element.insertAdjacentHTML("beforeBegin", html);
     3314                }
     3315
     3316                // Setup iframe
     3317                var dynamicIFrame = false;
     3318                var tElm = targetDoc.getElementById(this.editorId);
     3319
     3320                if (!tinyMCE.isMSIE) {
     3321                        if (tElm && tElm.nodeName == "SPAN") {
     3322                                tElm = tinyMCE._createIFrame(tElm, targetDoc);
     3323                                dynamicIFrame = true;
     3324                        }
     3325
     3326                        this.targetElement = tElm;
     3327                        this.iframeElement = tElm;
     3328                        this.contentDocument = tElm.contentDocument;
     3329                        this.contentWindow = tElm.contentWindow;
     3330
     3331                        //this.getDoc().designMode = "on";
     3332                } else {
     3333                        if (tElm && tElm.nodeName == "SPAN")
     3334                                tElm = tinyMCE._createIFrame(tElm, targetDoc, targetDoc.parentWindow);
     3335                        else
     3336                                tElm = targetDoc.frames[this.editorId];
     3337
     3338                        this.targetElement = tElm;
     3339                        this.iframeElement = targetDoc.getElementById(this.editorId);
     3340
     3341                        if (tinyMCE.isOpera) {
     3342                                this.contentDocument = this.iframeElement.contentDocument;
     3343                                this.contentWindow = this.iframeElement.contentWindow;
     3344                                dynamicIFrame = true;
     3345                        } else {
     3346                                this.contentDocument = tElm.window.document;
     3347                                this.contentWindow = tElm.window;
     3348                        }
     3349
     3350                        this.getDoc().designMode = "on";
     3351                }
     3352
     3353                // Setup base HTML
     3354                var doc = this.contentDocument;
     3355                if (dynamicIFrame) {
     3356                        var html = tinyMCE.getParam('doctype') + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + tinyMCE.settings['base_href'] + '" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body class="mceContentBody"></body></html>';
     3357
     3358                        try {
     3359                                if (!this.isHidden())
     3360                                        this.getDoc().designMode = "on";
     3361
     3362                                doc.open();
     3363                                doc.write(html);
     3364                                doc.close();
     3365                        } catch (e) {
     3366                                // Failed Mozilla 1.3
     3367                                this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm";
     3368                        }
     3369                }
     3370
     3371                // This timeout is needed in MSIE 5.5 for some odd reason
     3372                // it seems that the document.frames isn't initialized yet?
     3373                if (tinyMCE.isMSIE)
     3374                        window.setTimeout("tinyMCE.addEventHandlers(tinyMCE.instances[\"" + this.editorId + "\"]);", 1);
     3375
     3376                tinyMCE.setupContent(this.editorId, true);
     3377
     3378                return true;
     3379        },
     3380
     3381        setBaseHREF : function(u) {
     3382                var h, b, d, nl;
     3383
     3384                d = this.getDoc();
     3385                nl = d.getElementsByTagName("base");
     3386                b = nl.length > 0 ? nl[0] : null;
     3387
     3388                if (!b) {
     3389                        nl = d.getElementsByTagName("head");
     3390                        h = nl.length > 0 ? nl[0] : null;
     3391
     3392                        b = d.createElement("base");
     3393                        b.setAttribute('href', u);
     3394                        h.appendChild(b);
     3395                } else {
     3396                        if (u == "" || u == null)
     3397                                b.parentNode.removeChild(b);
     3398                        else
     3399                                b.setAttribute('href', u);
     3400                }
     3401        },
     3402
     3403        getFocusElement : function() {
     3404                return this.selection.getFocusElement();
     3405        },
     3406
     3407        getSel : function() {
     3408                return this.selection.getSel();
     3409        },
     3410
     3411        getRng : function() {
     3412                return this.selection.getRng();
     3413        },
     3414
     3415        triggerSave : function(skip_cleanup, skip_callback) {
     3416                this.switchSettings();
     3417
     3418                tinyMCE.settings['preformatted'] = false;
     3419
     3420                // Default to false
     3421                if (typeof(skip_cleanup) == "undefined")
     3422                        skip_cleanup = false;
     3423
     3424                // Default to false
     3425                if (typeof(skip_callback) == "undefined")
     3426                        skip_callback = false;
     3427
     3428                tinyMCE._setHTML(this.getDoc(), this.getBody().innerHTML);
    3953429
    3963430                // Remove visual aids when cleanup is disabled
    397                 if (inst.settings['cleanup'] == false) {
    398                         tinyMCE.handleVisualAid(inst.getBody(), true, false, inst);
    399                         tinyMCE._setEventsEnabled(inst.getBody(), true);
    400                 }
    401 
    402                 tinyMCE._customCleanup(inst, "submit_content_dom", inst.contentWindow.document.body);
    403                 var htm = skip_cleanup ? inst.getBody().innerHTML : tinyMCE._cleanupHTML(inst, inst.getDoc(), this.settings, inst.getBody(), this.visualAid, true);
    404                 htm = tinyMCE._customCleanup(inst, "submit_content", htm);
    405 
    406                 if (tinyMCE.settings["encoding"] == "xml" || tinyMCE.settings["encoding"] == "html")
    407                         htm = tinyMCE.convertStringToXML(htm);
     3431                if (this.settings['cleanup'] == false) {
     3432                        tinyMCE.handleVisualAid(this.getBody(), true, false, this);
     3433                        tinyMCE._setEventsEnabled(this.getBody(), true);
     3434                }
     3435
     3436                tinyMCE._customCleanup(this, "submit_content_dom", this.contentWindow.document.body);
     3437                var htm = skip_cleanup ? this.getBody().innerHTML : tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true);
     3438                htm = tinyMCE._customCleanup(this, "submit_content", htm);
    4083439
    4093440                if (!skip_callback && tinyMCE.settings['save_callback'] != "")
    410                         var content = eval(tinyMCE.settings['save_callback'] + "(inst.formTargetElementId,htm,inst.getBody());");
     3441                        var content = eval(tinyMCE.settings['save_callback'] + "(this.formTargetElementId,htm,this.getBody());");
    4113442
    4123443                // Use callback content if available
    … …  
    4213452                htm = tinyMCE.regexpReplace(htm, "&#94;", "^", "gi");
    4223453
    423                 if (inst.formElement)
    424                         inst.formElement.value = htm;
     3454                if (this.formElement)
     3455                        this.formElement.value = htm;
     3456
     3457                if (tinyMCE.isSafari && this.formElement)
     3458                        this.formElement.innerText = htm;
    4253459        }
    4263460};
    4273461
    428 TinyMCE.prototype._setEventsEnabled = function(node, state) {
    429         var events = new Array('onfocus','onblur','onclick','ondblclick',
    430                                 'onmousedown','onmouseup','onmouseover','onmousemove',
    431                                 'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup');
    432 
    433         var evs = tinyMCE.settings['event_elements'].split(',');
    434     for (var y=0; y<evs.length; y++){
    435                 var elms = node.getElementsByTagName(evs[y]);
    436                 for (var i=0; i<elms.length; i++) {
    437                         var event = "";
    438 
    439                         for (var x=0; x<events.length; x++) {
    440                                 if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {
    441                                         event = tinyMCE.cleanupEventStr("" + event);
    442 
    443                                         if (!state)
    444                                                 event = "return true;" + event;
    445                                         else
    446                                                 event = event.replace(/^return true;/gi, '');
    447 
    448                                         elms[i].removeAttribute(events[x]);
    449                                         elms[i].setAttribute(events[x], event);
    450                                 }
    451                         }
    452                 }
    453         }
    454 };
    455 
    456 TinyMCE.prototype.resetForm = function(form_index) {
    457         var formObj = document.forms[form_index];
    458 
    459         for (var n in tinyMCE.instances) {
    460                 var inst = tinyMCE.instances[n];
    461                 if (!tinyMCE.isInstance(inst))
    462                         continue;
    463 
    464                 inst.switchSettings();
    465 
    466                 for (var i=0; i<formObj.elements.length; i++) {
    467                         if (inst.formTargetElementId == formObj.elements[i].name)
    468                                 inst.getBody().innerHTML = inst.startContent;
    469                 }
    470         }
    471 };
    472 
    473 TinyMCE.prototype.execInstanceCommand = function(editor_id, command, user_interface, value, focus) {
    474         var inst = tinyMCE.getInstanceById(editor_id);
    475         if (inst) {
    476                 if (typeof(focus) == "undefined")
    477                         focus = true;
    478 
    479                 if (focus)
    480                         inst.contentWindow.focus();
    481 
    482                 // Reset design mode if lost
    483                 inst.autoResetDesignMode();
    484 
    485                 this.selectedElement = inst.getFocusElement();
    486                 this.selectedInstance = inst;
    487                 tinyMCE.execCommand(command, user_interface, value);
    488 
    489                 // Cancel event so it doesn't call onbeforeonunlaod
    490                 if (tinyMCE.isMSIE && window.event != null)
    491                         tinyMCE.cancelEvent(window.event);
    492         }
    493 };
    494 
    495 TinyMCE.prototype.execCommand = function(command, user_interface, value) {
    496         // Default input
    497         user_interface = user_interface ? user_interface : false;
    498         value = value ? value : null;
    499 
    500         if (tinyMCE.selectedInstance)
    501                 tinyMCE.selectedInstance.switchSettings();
    502 
    503         switch (command) {
    504                 case 'mceHelp':
    505                         var template = new Array();
    506 
    507                         template['file']   = 'about.htm';
    508                         template['width']  = 480;
    509                         template['height'] = 380;
    510 
    511                         tinyMCE.openWindow(template, {
    512                                 tinymce_version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion,
    513                                 tinymce_releasedate : tinyMCE.releaseDate,
    514                                 inline : "yes"
    515                         });
    516                 return;
    517 
    518                 case 'mceFocus':
    519                         var inst = tinyMCE.getInstanceById(value);
    520                         if (inst)
    521                                 inst.contentWindow.focus();
    522                 return;
    523 
    524                 case "mceAddControl":
    525                 case "mceAddEditor":
    526                         tinyMCE.addMCEControl(tinyMCE._getElementById(value), value);
    527                         return;
    528 
    529                 case "mceAddFrameControl":
    530                         tinyMCE.addMCEControl(tinyMCE._getElementById(value), value['element'], value['document']);
    531                         return;
    532 
    533                 case "mceRemoveControl":
    534                 case "mceRemoveEditor":
    535                         tinyMCE.removeMCEControl(value);
    536                         return;
    537 
    538                 case "mceResetDesignMode":
    539                         // Resets the designmode state of the editors in Gecko
    540                         if (!tinyMCE.isMSIE) {
    541                                 for (var n in tinyMCE.instances) {
    542                                         if (!tinyMCE.isInstance(tinyMCE.instances[n]))
    543                                                 continue;
    544 
    545                                         try {
    546                                                 tinyMCE.instances[n].getDoc().designMode = "on";
    547                                         } catch (e) {
    548                                                 // Ignore any errors
    549                                         }
    550                                 }
    551                         }
    552 
    553                         return;
    554         }
    555 
    556         if (this.selectedInstance) {
    557                 this.selectedInstance.execCommand(command, user_interface, value);
    558         } else if (tinyMCE.settings['focus_alert'])
    559                 alert(tinyMCELang['lang_focus_alert']);
    560 };
    561 
    562 TinyMCE.prototype.eventPatch = function(editor_id) {
    563         // Remove odd, error
    564         if (typeof(tinyMCE) == "undefined")
    565                 return true;
    566 
    567         for (var i=0; i<document.frames.length; i++) {
    568                 try {
    569                         if (document.frames[i].event) {
    570                                 var event = document.frames[i].event;
    571 
    572                                 if (!event.target)
    573                                         event.target = event.srcElement;
    574 
    575                                 TinyMCE.prototype.handleEvent(event);
    576                                 return;
    577                         }
    578                 } catch (ex) {
    579                         // Ignore error if iframe is pointing to external URL
    580                 }
    581         }
    582 };
    583 
    584 TinyMCE.prototype.unloadHandler = function() {
    585         tinyMCE.triggerSave(true, true);
    586 };
    587 
    588 TinyMCE.prototype.addEventHandlers = function(editor_id) {
    589         if (tinyMCE.isMSIE) {
    590                 var doc = document.frames[editor_id].document;
    591 
    592                 // Event patch
    593                 tinyMCE.addEvent(doc, "keypress", TinyMCE.prototype.eventPatch);
    594                 tinyMCE.addEvent(doc, "keyup", TinyMCE.prototype.eventPatch);
    595                 tinyMCE.addEvent(doc, "keydown", TinyMCE.prototype.eventPatch);
    596                 tinyMCE.addEvent(doc, "mouseup", TinyMCE.prototype.eventPatch);
    597                 tinyMCE.addEvent(doc, "click", TinyMCE.prototype.eventPatch);
    598         } else {
    599                 var inst = tinyMCE.instances[editor_id];
    600                 var doc = inst.getDoc();
    601 
    602                 inst.switchSettings();
    603 
    604                 tinyMCE.addEvent(doc, "keypress", tinyMCE.handleEvent);
    605                 tinyMCE.addEvent(doc, "keydown", tinyMCE.handleEvent);
    606                 tinyMCE.addEvent(doc, "keyup", tinyMCE.handleEvent);
    607                 tinyMCE.addEvent(doc, "click", tinyMCE.handleEvent);
    608                 tinyMCE.addEvent(doc, "mouseup", tinyMCE.handleEvent);
    609                 tinyMCE.addEvent(doc, "mousedown", tinyMCE.handleEvent);
    610                 tinyMCE.addEvent(doc, "focus", tinyMCE.handleEvent);
    611                 tinyMCE.addEvent(doc, "blur", tinyMCE.handleEvent);
    612 
    613                 eval('try { doc.designMode = "On"; } catch(e) {}');
    614         }
    615 };
    616 
    617 TinyMCE.prototype._createIFrame = function(replace_element) {
    618         var iframe = document.createElement("iframe");
    619         var id = replace_element.getAttribute("id");
    620         var aw, ah;
    621 
    622         aw = "" + tinyMCE.settings['area_width'];
    623         ah = "" + tinyMCE.settings['area_height'];
    624 
    625         if (aw.indexOf('%') == -1) {
    626                 aw = parseInt(aw);
    627                 aw = aw < 0 ? 300 : aw;
    628                 aw = aw + "px";
    629         }
    630 
    631         if (ah.indexOf('%') == -1) {
    632                 ah = parseInt(ah);
    633                 ah = ah < 0 ? 240 : ah;
    634                 ah = ah + "px";
    635         }
    636 
    637         iframe.setAttribute("id", id);
    638         //iframe.setAttribute("className", "mceEditorArea");
    639         iframe.setAttribute("border", "0");
    640         iframe.setAttribute("frameBorder", "0");
    641         iframe.setAttribute("marginWidth", "0");
    642         iframe.setAttribute("marginHeight", "0");
    643         iframe.setAttribute("leftMargin", "0");
    644         iframe.setAttribute("topMargin", "0");
    645         iframe.setAttribute("width", aw);
    646         iframe.setAttribute("height", ah);
    647         iframe.setAttribute("allowtransparency", "true");
    648 
    649         if (tinyMCE.settings["auto_resize"])
    650                 iframe.setAttribute("scrolling", "no");
    651 
    652         // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs
    653         if (tinyMCE.isMSIE && !tinyMCE.isOpera)
    654                 iframe.setAttribute("src", this.settings['default_document']);
    655 
    656         iframe.style.width = aw;
    657         iframe.style.height = ah;
    658 
    659         // MSIE 5.0 issue
    660         if (tinyMCE.isMSIE && !tinyMCE.isOpera)
    661                 replace_element.outerHTML = iframe.outerHTML;
    662         else
    663                 replace_element.parentNode.replaceChild(iframe, replace_element);
    664 
    665         if (tinyMCE.isMSIE)
    666                 return window.frames[id];
    667         else
    668                 return iframe;
    669 };
    670 
    671 TinyMCE.prototype.setupContent = function(editor_id) {
    672         var inst = tinyMCE.instances[editor_id];
    673         var doc = inst.getDoc();
    674         var head = doc.getElementsByTagName('head').item(0);
    675         var content = inst.startContent;
    676 
    677         tinyMCE.operaOpacityCounter = 100 * tinyMCE.idCounter;
    678 
    679         inst.switchSettings();
    680 
    681         // Not loaded correctly hit it again, Mozilla bug #997860
    682         if (!tinyMCE.isMSIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") {
    683                 // This part will remove the designMode status
    684                 // Failes first time in Firefox 1.5b2 on Mac
    685                 try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {}
    686                 window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000);
    687                 return;
    688         }
    689 
    690         if (!head) {
    691                 window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10);
    692                 return;
    693         }
    694 
    695         // Import theme specific content CSS the user specific
    696         tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css");
    697         tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']);
    698         tinyMCE.executeCallback('init_instance_callback', '_initInstance', 0, inst);
    699 
    700         // Setup span styles
    701         if (tinyMCE.getParam("convert_fonts_to_spans"))
    702                 inst.getDoc().body.setAttribute('id', 'mceSpanFonts');
    703 
    704         if (tinyMCE.settings['nowrap'])
    705                 doc.body.style.whiteSpace = "nowrap";
    706 
    707         doc.body.dir = this.settings['directionality'];
    708         doc.editorId = editor_id;
    709 
    710         // Add on document element in Mozilla
    711         if (!tinyMCE.isMSIE)
    712                 doc.documentElement.editorId = editor_id;
    713 
    714         // Setup base element
    715         var base = doc.createElement("base");
    716         base.setAttribute('href', tinyMCE.settings['base_href']);
    717         head.appendChild(base);
    718 
    719         // Replace new line characters to BRs
    720         if (tinyMCE.settings['convert_newlines_to_brs']) {
    721                 content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi");
    722                 content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi");
    723                 content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi");
    724         }
    725 
    726         // Open closed anchors
    727 //      content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
    728 
    729         // Call custom cleanup code
    730         content = tinyMCE.storeAwayURLs(content);
    731         content = tinyMCE._customCleanup(inst, "insert_to_editor", content);
    732 
    733         if (tinyMCE.isMSIE) {
    734                 // Ugly!!!
    735                 window.setInterval('try{tinyMCE.getCSSClasses(document.frames["' + editor_id + '"].document, "' + editor_id + '");}catch(e){}', 500);
    736 
    737                 if (tinyMCE.settings["force_br_newlines"])
    738                         document.frames[editor_id].document.styleSheets[0].addRule("p", "margin: 0px;");
    739 
    740                 var body = document.frames[editor_id].document.body;
    741 
    742                 tinyMCE.addEvent(body, "beforepaste", TinyMCE.prototype.eventPatch);
    743                 tinyMCE.addEvent(body, "beforecut", TinyMCE.prototype.eventPatch);
    744 
    745                 body.editorId = editor_id;
    746         }
    747 
    748         content = tinyMCE.cleanupHTMLCode(content);
    749 
    750         // Fix for bug #958637
    751         if (!tinyMCE.isMSIE) {
    752                 var contentElement = inst.getDoc().createElement("body");
    753                 var doc = inst.getDoc();
    754 
    755                 contentElement.innerHTML = content;
    756 
    757                 // Remove weridness!
    758                 if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt'])
    759                         content = content.replace(new RegExp('&lt;&gt;', 'g'), "");
    760 
    761                 if (tinyMCE.settings['cleanup_on_startup'])
    762                         tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement));
    763                 else {
    764                         // Convert all strong/em to b/i
    765                         content = tinyMCE.regexpReplace(content, "<strong", "<b", "gi");
    766                         content = tinyMCE.regexpReplace(content, "<em(/?)>", "<i$1>", "gi");
    767                         content = tinyMCE.regexpReplace(content, "<em ", "<i ", "gi");
    768                         content = tinyMCE.regexpReplace(content, "</strong>", "</b>", "gi");
    769                         content = tinyMCE.regexpReplace(content, "</em>", "</i>", "gi");
    770                         tinyMCE.setInnerHTML(inst.getBody(), content);
    771                 }
    772 
    773                 inst.convertAllRelativeURLs();
    774         } else {
    775                 if (tinyMCE.settings['cleanup_on_startup']) {
    776                         tinyMCE._setHTML(inst.getDoc(), content);
    777 
    778                         // Produces permission denied error in MSIE 5.5
    779                         eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}');
    780                 } else
    781                         tinyMCE._setHTML(inst.getDoc(), content);
    782         }
    783 
    784         // Fix for bug #957681
    785         //inst.getDoc().designMode = inst.getDoc().designMode;
    786 
    787         // Setup element references
    788         var parentElm = document.getElementById(inst.editorId + '_parent');
    789         if (parentElm.lastChild.nodeName == "INPUT")
    790                 inst.formElement = tinyMCE.isGecko ? parentElm.firstChild : parentElm.lastChild;
    791         else
    792                 inst.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling;
    793 
    794         tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst);
    795         tinyMCE.executeCallback('setupcontent_callback', '_setupContent', 0, editor_id, inst.getBody(), inst.getDoc());
    796 
    797         // Re-add design mode on mozilla
    798         if (!tinyMCE.isMSIE)
    799                 TinyMCE.prototype.addEventHandlers(editor_id);
    800 
    801         // Add blur handler
    802         if (tinyMCE.isMSIE)
    803                 tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE.prototype.eventPatch);
    804 
    805         // Trigger node change, this call locks buttons for tables and so forth
    806         tinyMCE.selectedInstance = inst;
    807         tinyMCE.selectedElement = inst.contentWindow.document.body;
    808 
    809         if (!inst.isHidden())
    810                 tinyMCE.triggerNodeChange(false, true);
    811 
    812         // Call custom DOM cleanup
    813         tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody());
    814         tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody());
    815         tinyMCE._setEventsEnabled(inst.getBody(), false);
    816         tinyMCE.cleanupAnchors(inst.getDoc());
    817 
    818         if (tinyMCE.getParam("convert_fonts_to_spans"))
    819                 tinyMCE.convertSpansToFonts(inst.getDoc());
    820 
    821         inst.startContent = tinyMCE.trim(inst.getBody().innerHTML);
    822         inst.undoLevels[inst.undoLevels.length] = inst.startContent;
    823 
    824         tinyMCE.operaOpacityCounter = -1;
    825 };
    826 
    827 TinyMCE.prototype.cleanupHTMLCode = function(s) {
     3462/* file:jscripts/tiny_mce/classes/TinyMCE_Cleanup.class.js */
     3463
     3464TinyMCE_Engine.prototype.cleanupHTMLCode = function(s) {
    8283465        s = s.replace(/<p \/>/gi, '<p>&nbsp;</p>');
    8293466        s = s.replace(/<p>\s*<\/p>/gi, '<p>&nbsp;</p>');
    … …  
    8313468        // Open closed tags like <b/> to <b></b>
    8323469//      tinyMCE.debug("f:" + s);
    833         s = s.replace(/<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\|>]*?)\/>/gi, '<$1$2$3></$1$2>');
     3470        s = s.replace(/<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|font|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\|>]*?)\/>/gi, '<$1$2$3></$1$2>');
    8343471//      tinyMCE.debug("e:" + s);
    8353472
    … …  
    8453482
    8463483        // Convert relative anchors to absolute URLs ex: #something to file.htm#something
    847         s = s.replace(new RegExp('(href=\"?)(\\s*?#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#");
     3484        if (tinyMCE.getParam('convert_urls'))
     3485                s = s.replace(new RegExp('(href=\"?)(\\s*?#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#");
    8483486
    8493487        return s;
    8503488};
    8513489
    852 TinyMCE.prototype.storeAwayURLs = function(s) {
    853         // Remove all mce_src, mce_href and replace them with new ones
    854         s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
    855         s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
    856         s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"');
    857         s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"');
    858 
    859         return s;
    860 };
    861 
    862 TinyMCE.prototype.cancelEvent = function(e) {
    863         if (tinyMCE.isMSIE) {
    864                 e.returnValue = false;
    865                 e.cancelBubble = true;
    866         } else
    867                 e.preventDefault();
    868 };
    869 
    870 TinyMCE.prototype.removeTinyMCEFormElements = function(form_obj) {
    871         // Check if form is valid
    872         if (typeof(form_obj) == "undefined" || form_obj == null)
    873                 return;
    874 
    875         // If not a form, find the form
    876         if (form_obj.nodeName != "FORM") {
    877                 if (form_obj.form)
    878                         form_obj = form_obj.form;
    879                 else
    880                         form_obj = tinyMCE.getParentElement(form_obj, "form");
    881         }
    882 
    883         // Still nothing
    884         if (form_obj == null)
    885                 return;
    886 
    887         // Disable all UI form elements that TinyMCE created
    888         for (var i=0; i<form_obj.elements.length; i++) {
    889                 var elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id;
    890 
    891                 if (elementId.indexOf('mce_editor_') == 0)
    892                         form_obj.elements[i].disabled = true;
    893         }
    894 };
    895 
    896 TinyMCE.prototype.accessibleEventHandler = function(e) {
    897         var win = this._win;
    898         e = tinyMCE.isMSIE ? win.event : e;
    899         var elm = tinyMCE.isMSIE ? e.srcElement : e.target;
    900 
    901         // Piggyback onchange
    902         if (elm.nodeName == "SELECT" && !elm.oldonchange) {
    903                 elm.oldonchange = elm.onchange;
    904                 elm.onchange = null;
    905         }
    906 
    907         // Execute onchange and remove piggyback
    908         if (e.keyCode == 13 || e.keyCode == 32) {
    909                 elm.onchange = elm.oldonchange;
    910                 elm.onchange();
    911                 elm.oldonchange = null;
    912                 tinyMCE.cancelEvent(e);
    913         }
    914 };
    915 
    916 TinyMCE.prototype.addSelectAccessibility = function(e, select, win) {
    917         // Add event handlers
    918         if (!select._isAccessible) {
    919                 select.onkeydown = tinyMCE.accessibleEventHandler;
    920                 select._isAccessible = true;
    921                 select._win = win;
    922         }
    923 };
    924 
    925 TinyMCE.prototype.handleEvent = function(e) {
    926         // Remove odd, error
    927         if (typeof(tinyMCE) == "undefined")
    928                 return true;
    929 
    930         //tinyMCE.debug(e.type + " " + e.target.nodeName + " " + (e.relatedTarget ? e.relatedTarget.nodeName : ""));
    931 
    932         switch (e.type) {
    933                 case "blur":
    934                         if (tinyMCE.selectedInstance)
    935                                 tinyMCE.selectedInstance.execCommand('mceEndTyping');
    936 
    937                         return;
    938 
    939                 case "submit":
    940                         tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target);
    941                         tinyMCE.triggerSave();
    942                         tinyMCE.isNotDirty = true;
    943                         return;
    944 
    945                 case "reset":
    946                         var formObj = tinyMCE.isMSIE ? window.event.srcElement : e.target;
    947 
    948                         for (var i=0; i<document.forms.length; i++) {
    949                                 if (document.forms[i] == formObj)
    950                                         window.setTimeout('tinyMCE.resetForm(' + i + ');', 10);
    951                         }
    952 
    953                         return;
    954 
    955                 case "keypress":
    956                         if (e.target.editorId) {
    957                                 tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
    958                         } else {
    959                                 if (e.target.ownerDocument.editorId)
    960                                         tinyMCE.selectedInstance = tinyMCE.instances[e.target.ownerDocument.editorId];
    961                         }
    962 
    963                         if (tinyMCE.selectedInstance)
    964                                 tinyMCE.selectedInstance.switchSettings();
    965 
    966                         // Insert space instead of &nbsp;
    967 /*                      if (tinyMCE.isGecko && e.charCode == 32) {
    968                                 if (tinyMCE.selectedInstance._insertSpace()) {
    969                                         // Cancel event
    970                                         e.preventDefault();
    971                                         return false;
    972                                 }
    973                         }*/
    974 
    975                         // Insert P element
    976                         if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && e.keyCode == 13 && !e.shiftKey) {
    977                                 // Insert P element instead of BR
    978                                 if (tinyMCE.selectedInstance._insertPara(e)) {
    979                                         // Cancel event
    980                                         tinyMCE.execCommand("mceAddUndoLevel");
    981                                         tinyMCE.cancelEvent(e);
    982                                         return false;
    983                                 }
    984                         }
    985 
    986                         // Handle backspace
    987                         if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
    988                                 // Insert P element instead of BR
    989                                 if (tinyMCE.selectedInstance._handleBackSpace(e.type)) {
    990                                         // Cancel event
    991                                         tinyMCE.execCommand("mceAddUndoLevel");
    992                                         tinyMCE.cancelEvent(e);
    993                                         return false;
    994                                 }
    995                         }
    996 
    997                         // Mozilla custom key handling
    998                         if (tinyMCE.isGecko && (e.ctrlKey && !e.altKey) && tinyMCE.settings['custom_undo_redo']) {
    999                                 if (tinyMCE.settings['custom_undo_redo_keyboard_shortcuts']) {
    1000                                         if (e.charCode == 122) { // Ctrl+Z
    1001                                                 tinyMCE.selectedInstance.execCommand("Undo");
    1002                                                 tinyMCE.cancelEvent(e);
    1003                                                 return false;
    1004                                         }
    1005 
    1006                                         if (e.charCode == 121) { // Ctrl+Y
    1007                                                 tinyMCE.selectedInstance.execCommand("Redo");
    1008                                                 tinyMCE.cancelEvent(e);
    1009                                                 return false;
    1010                                         }
    1011                                 }
    1012 
    1013                                 if (e.charCode == 98) { // Ctrl+B
    1014                                         tinyMCE.selectedInstance.execCommand("Bold");
    1015                                         tinyMCE.cancelEvent(e);
    1016                                         return false;
    1017                                 }
    1018 
    1019                                 if (e.charCode == 105) { // Ctrl+I
    1020                                         tinyMCE.selectedInstance.execCommand("Italic");
    1021                                         tinyMCE.cancelEvent(e);
    1022                                         return false;
    1023                                 }
    1024 
    1025                                 if (e.charCode == 117) { // Ctrl+U
    1026                                         tinyMCE.selectedInstance.execCommand("Underline");
    1027                                         tinyMCE.cancelEvent(e);
    1028                                         return false;
    1029                                 }
    1030 
    1031                                 if (e.charCode == 118) { // Ctrl+V
    1032                                         tinyMCE.selectedInstance.execCommand("mceInsertContent", false, '<geckopastefix/>');
    1033                                 }
    1034                         }
    1035 
    1036                         // Return key pressed
    1037                         if (tinyMCE.isMSIE && tinyMCE.settings['force_br_newlines'] && e.keyCode == 13) {
    1038                                 if (e.target.editorId)
    1039                                         tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
    1040 
    1041                                 if (tinyMCE.selectedInstance) {
    1042                                         var sel = tinyMCE.selectedInstance.getDoc().selection;
    1043                                         var rng = sel.createRange();
    1044 
    1045                                         if (tinyMCE.getParentElement(rng.parentElement(), "li") != null)
    1046                                                 return false;
    1047 
    1048                                         // Cancel event
    1049                                         e.returnValue = false;
    1050                                         e.cancelBubble = true;
    1051 
    1052                                         // Insert BR element
    1053                                         rng.pasteHTML("<br />");
    1054                                         rng.collapse(false);
    1055                                         rng.select();
    1056 
    1057                                         tinyMCE.execCommand("mceAddUndoLevel");
    1058                                         tinyMCE.triggerNodeChange(false);
    1059                                         return false;
    1060                                 }
    1061                         }
    1062 
    1063                         // Backspace or delete
    1064                         if (e.keyCode == 8 || e.keyCode == 46) {
    1065                                 tinyMCE.selectedElement = e.target;
    1066                                 tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a");
    1067                                 tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img");
    1068                                 tinyMCE.triggerNodeChange(false);
    1069                         }
    1070 
    1071                         return false;
    1072                 break;
    1073 
    1074                 case "keyup":
    1075                 case "keydown":
    1076                         if (e.target.editorId)
    1077                                 tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
    1078                         else
    1079                                 return;
    1080 
    1081                         if (tinyMCE.selectedInstance)
    1082                                 tinyMCE.selectedInstance.switchSettings();
    1083 
    1084                         var inst = tinyMCE.selectedInstance;
    1085 
    1086                         // Handle backspace
    1087                         if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
    1088                                 // Insert P element instead of BR
    1089                                 if (tinyMCE.selectedInstance._handleBackSpace(e.type)) {
    1090                                         // Cancel event
    1091                                         tinyMCE.execCommand("mceAddUndoLevel");
    1092                                         e.preventDefault();
    1093                                         return false;
    1094                                 }
    1095                         }
    1096 
    1097                         tinyMCE.selectedElement = null;
    1098                         tinyMCE.selectedNode = null;
    1099                         var elm = tinyMCE.selectedInstance.getFocusElement();
    1100                         tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a");
    1101                         tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img");
    1102                         tinyMCE.selectedElement = elm;
    1103 
    1104                         // Update visualaids on tabs
    1105                         if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9)
    1106                                 tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance);
    1107 
    1108                         // Fix empty elements on return/enter, check where enter occured
    1109                         if (tinyMCE.isMSIE && e.type == "keydown" && e.keyCode == 13)
    1110                                 tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement();
    1111 
    1112                         // Fix empty elements on return/enter
    1113                         if (tinyMCE.isMSIE && e.type == "keyup" && e.keyCode == 13) {
    1114                                 var elm = tinyMCE.enterKeyElement;
    1115                                 if (elm) {
    1116                                         var re = new RegExp('^HR|IMG|BR$','g'); // Skip these
    1117                                         var dre = new RegExp('^H[1-6]$','g'); // Add double on these
    1118 
    1119                                         if (!elm.hasChildNodes() && !re.test(elm.nodeName)) {
    1120                                                 if (dre.test(elm.nodeName))
    1121                                                         elm.innerHTML = "&nbsp;&nbsp;";
    1122                                                 else
    1123                                                         elm.innerHTML = "&nbsp;";
    1124                                         }
    1125                                 }
    1126                         }
    1127 
    1128                         // Check if it's a position key
    1129                         var keys = tinyMCE.posKeyCodes;
    1130                         var posKey = false;
    1131                         for (var i=0; i<keys.length; i++) {
    1132                                 if (keys[i] == e.keyCode) {
    1133                                         posKey = true;
    1134                                         break;
    1135                                 }
    1136                         }
    1137 
    1138                         // MSIE custom key handling
    1139                         if (tinyMCE.isMSIE && tinyMCE.settings['custom_undo_redo']) {
    1140                                 var keys = new Array(8,46); // Backspace,Delete
    1141                                 for (var i=0; i<keys.length; i++) {
    1142                                         if (keys[i] == e.keyCode) {
    1143                                                 if (e.type == "keyup")
    1144                                                         tinyMCE.triggerNodeChange(false);
    1145                                         }
    1146                                 }
    1147 
    1148                                 if (tinyMCE.settings['custom_undo_redo_keyboard_shortcuts']) {
    1149                                         if (e.keyCode == 90 && (e.ctrlKey && !e.altKey) && e.type == "keydown") { // Ctrl+Z
    1150                                                 tinyMCE.selectedInstance.execCommand("Undo");
    1151                                                 tinyMCE.triggerNodeChange(false);
    1152                                         }
    1153 
    1154                                         if (e.keyCode == 89 && (e.ctrlKey && !e.altKey) && e.type == "keydown") { // Ctrl+Y
    1155                                                 tinyMCE.selectedInstance.execCommand("Redo");
    1156                                                 tinyMCE.triggerNodeChange(false);
    1157                                         }
    1158 
    1159                                         if ((e.keyCode == 90 || e.keyCode == 89) && (e.ctrlKey && !e.altKey)) {
    1160                                                 // Cancel event
    1161                                                 e.returnValue = false;
    1162                                                 e.cancelBubble = true;
    1163                                                 return false;
    1164                                         }
    1165                                 }
    1166                         }
    1167 
    1168                         // If undo/redo key
    1169                         if ((e.keyCode == 90 || e.keyCode == 89) && (e.ctrlKey && !e.altKey))
    1170                                 return true;
    1171 
    1172                         // If Ctrl key
    1173                         if (e.keyCode == 17)
    1174                                 return true;
    1175 
    1176                         // Handle Undo/Redo when typing content
    1177 
    1178                         // Start typing (non position key)
    1179                         if (!posKey && e.type == "keyup")
    1180                                 tinyMCE.execCommand("mceStartTyping");
    1181 
    1182                         // End typing (position key) or some Ctrl event
    1183                         if (e.type == "keyup" && (posKey || e.ctrlKey))
    1184                                 tinyMCE.execCommand("mceEndTyping");
    1185 
    1186                         if (posKey && e.type == "keyup")
    1187                                 tinyMCE.triggerNodeChange(false);
    1188 
    1189                         if (tinyMCE.isMSIE && e.ctrlKey)
    1190                                 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
    1191                 break;
    1192 
    1193                 case "mousedown":
    1194                 case "mouseup":
    1195                 case "click":
    1196                 case "focus":
    1197                         if (tinyMCE.selectedInstance)
    1198                                 tinyMCE.selectedInstance.switchSettings();
    1199 
    1200                         // Check instance event trigged on
    1201                         var targetBody = tinyMCE.getParentElement(e.target, "body");
    1202                         for (var instanceName in tinyMCE.instances) {
    1203                                 if (!tinyMCE.isInstance(tinyMCE.instances[instanceName]))
    1204                                         continue;
    1205 
    1206                                 var inst = tinyMCE.instances[instanceName];
    1207 
    1208                                 // Reset design mode if lost (on everything just in case)
    1209                                 inst.autoResetDesignMode();
    1210 
    1211                                 if (inst.getBody() == targetBody) {
    1212                                         tinyMCE.selectedInstance = inst;
    1213                                         tinyMCE.selectedElement = e.target;
    1214                                         tinyMCE.linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
    1215                                         tinyMCE.imgElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "img");
    1216                                         break;
    1217                                 }
    1218                         }
    1219 
    1220                         if (tinyMCE.isSafari) {
    1221                                 tinyMCE.selectedInstance.lastSafariSelection = tinyMCE.selectedInstance.getBookmark();
    1222                                 tinyMCE.selectedInstance.lastSafariSelectedElement = tinyMCE.selectedElement;
    1223 
    1224                                 var lnk = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
    1225 
    1226                                 // Patch the darned link
    1227                                 if (lnk && e.type == "mousedown") {
    1228                                         lnk.setAttribute("mce_real_href", lnk.getAttribute("href"));
    1229                                         lnk.setAttribute("href", "javascript:void(0);");
    1230                                 }
    1231 
    1232                                 // Patch back
    1233                                 if (lnk && e.type == "click") {
    1234                                         window.setTimeout(function() {
    1235                                                 lnk.setAttribute("href", lnk.getAttribute("mce_real_href"));
    1236                                                 lnk.removeAttribute("mce_real_href");
    1237                                         }, 10);
    1238                                 }
    1239                         }
    1240 
    1241                         // Reset selected node
    1242                         if (e.type != "focus")
    1243                                 tinyMCE.selectedNode = null;
    1244 
    1245                         tinyMCE.triggerNodeChange(false);
    1246                         tinyMCE.execCommand("mceEndTyping");
    1247 
    1248                         if (e.type == "mouseup")
    1249                                 tinyMCE.execCommand("mceAddUndoLevel");
    1250 
    1251                         // Just in case
    1252                         if (!tinyMCE.selectedInstance && e.target.editorId)
    1253                                 tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
    1254 
    1255                         return false;
    1256                 break;
    1257     } // end switch
    1258 }; // end function
    1259 
    1260 TinyMCE.prototype.switchClass = function(element, class_name, lock_state) {
    1261         var lockChanged = false;
    1262 
    1263         if (typeof(lock_state) != "undefined" && element != null) {
    1264                 element.classLock = lock_state;
    1265                 lockChanged = true;
    1266         }
    1267 
    1268         if (element != null && (lockChanged || !element.classLock)) {
    1269                 element.oldClassName = element.className;
    1270                 element.className = class_name;
    1271         }
    1272 };
    1273 
    1274 TinyMCE.prototype.restoreAndSwitchClass = function(element, class_name) {
    1275         if (element != null && !element.classLock) {
    1276                 this.restoreClass(element);
    1277                 this.switchClass(element, class_name);
    1278         }
    1279 };
    1280 
    1281 TinyMCE.prototype.switchClassSticky = function(element_name, class_name, lock_state) {
    1282         var element, lockChanged = false;
    1283 
    1284         // Performance issue
    1285         if (!this.stickyClassesLookup[element_name])
    1286                 this.stickyClassesLookup[element_name] = document.getElementById(element_name);
    1287 
    1288 //      element = document.getElementById(element_name);
    1289         element = this.stickyClassesLookup[element_name];
    1290 
    1291         if (typeof(lock_state) != "undefined" && element != null) {
    1292                 element.classLock = lock_state;
    1293                 lockChanged = true;
    1294         }
    1295 
    1296         if (element != null && (lockChanged || !element.classLock)) {
    1297                 element.className = class_name;
    1298                 element.oldClassName = class_name;
    1299 
    1300                 // Fix opacity in Opera
    1301                 if (tinyMCE.isOpera) {
    1302                         if (class_name == "mceButtonDisabled") {
    1303                                 var suffix = "";
    1304 
    1305                                 if (!element.mceOldSrc)
    1306                                         element.mceOldSrc = element.src;
    1307 
    1308                                 if (this.operaOpacityCounter > -1)
    1309                                         suffix = '?rnd=' + this.operaOpacityCounter++;
    1310 
    1311                                 element.src = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/images/opacity.png" + suffix;
    1312                                 element.style.backgroundImage = "url('" + element.mceOldSrc + "')";
    1313                         } else {
    1314                                 if (element.mceOldSrc) {
    1315                                         element.src = element.mceOldSrc;
    1316                                         element.parentNode.style.backgroundImage = "";
    1317                                         element.mceOldSrc = null;
    1318                                 }
    1319                         }
    1320                 }
    1321         }
    1322 };
    1323 
    1324 TinyMCE.prototype.restoreClass = function(element) {
    1325         if (element != null && element.oldClassName && !element.classLock) {
    1326                 element.className = element.oldClassName;
    1327                 element.oldClassName = null;
    1328         }
    1329 };
    1330 
    1331 TinyMCE.prototype.setClassLock = function(element, lock_state) {
    1332         if (element != null)
    1333                 element.classLock = lock_state;
    1334 };
    1335 
    1336 TinyMCE.prototype.addEvent = function(obj, name, handler) {
    1337         if (tinyMCE.isMSIE) {
    1338                 obj.attachEvent("on" + name, handler);
    1339         } else
    1340                 obj.addEventListener(name, handler, false);
    1341 };
    1342 
    1343 TinyMCE.prototype.submitPatch = function() {
    1344         tinyMCE.removeTinyMCEFormElements(this);
    1345         tinyMCE.triggerSave();
    1346         this.mceOldSubmit();
    1347         tinyMCE.isNotDirty = true;
    1348 };
    1349 
    1350 TinyMCE.prototype.onLoad = function() {
    1351         for (var c=0; c<tinyMCE.configs.length; c++) {
    1352                 tinyMCE.settings = tinyMCE.configs[c];
    1353 
    1354                 var selector = tinyMCE.getParam("editor_selector");
    1355                 var deselector = tinyMCE.getParam("editor_deselector");
    1356                 var elementRefAr = new Array();
    1357 
    1358                 // Add submit triggers
    1359                 if (document.forms && tinyMCE.settings['add_form_submit_trigger'] && !tinyMCE.submitTriggers) {
    1360                         for (var i=0; i<document.forms.length; i++) {
    1361                                 var form = document.forms[i];
    1362 
    1363                                 tinyMCE.addEvent(form, "submit", TinyMCE.prototype.handleEvent);
    1364                                 tinyMCE.addEvent(form, "reset", TinyMCE.prototype.handleEvent);
    1365                                 tinyMCE.submitTriggers = true; // Do it only once
    1366 
    1367                                 // Patch the form.submit function
    1368                                 if (tinyMCE.settings['submit_patch']) {
    1369                                         try {
    1370                                                 form.mceOldSubmit = form.submit;
    1371                                                 form.submit = TinyMCE.prototype.submitPatch;
    1372                                         } catch (e) {
    1373                                                 // Do nothing
    1374                                         }
    1375                                 }
    1376                         }
    1377                 }
    1378 
    1379                 // Add editor instances based on mode
    1380                 var mode = tinyMCE.settings['mode'];
    1381                 switch (mode) {
    1382                         case "exact":
    1383                                 var elements = tinyMCE.getParam('elements', '', true, ',');
    1384 
    1385                                 for (var i=0; i<elements.length; i++) {
    1386                                         var element = tinyMCE._getElementById(elements[i]);
    1387                                         var trigger = element ? element.getAttribute(tinyMCE.settings['textarea_trigger']) : "";
    1388 
    1389                                         if (tinyMCE.getAttrib(element, "class").indexOf(deselector) != -1)
    1390                                                 continue;
    1391 
    1392                                         if (trigger == "false")
    1393                                                 continue;
    1394 
    1395                                         if (tinyMCE.settings['ask'] && element) {
    1396                                                 elementRefAr[elementRefAr.length] = element;
    1397                                                 continue;
    1398                                         }
    1399 
    1400                                         if (element)
    1401                                                 tinyMCE.addMCEControl(element, elements[i]);
    1402                                         else if (tinyMCE.settings['debug'])
    1403                                                 alert("Error: Could not find element by id or name: " + elements[i]);
    1404                                 }
    1405                         break;
    1406 
    1407                         case "specific_textareas":
    1408                         case "textareas":
    1409                                 var nodeList = document.getElementsByTagName("textarea");
    1410 
    1411                                 for (var i=0; i<nodeList.length; i++) {
    1412                                         var elm = nodeList.item(i);
    1413                                         var trigger = elm.getAttribute(tinyMCE.settings['textarea_trigger']);
    1414 
    1415                                         if (selector != '' && tinyMCE.getAttrib(elm, "class").indexOf(selector) == -1)
    1416                                                 continue;
    1417 
    1418                                         if (selector != '')
    1419                                                 trigger = selector != "" ? "true" : "";
    1420 
    1421                                         if (tinyMCE.getAttrib(elm, "class").indexOf(deselector) != -1)
    1422                                                 continue;
    1423 
    1424                                         if ((mode == "specific_textareas" && trigger == "true") || (mode == "textareas" && trigger != "false"))
    1425                                                 elementRefAr[elementRefAr.length] = elm;
    1426                                 }
    1427                         break;
    1428                 }
    1429 
    1430                 for (var i=0; i<elementRefAr.length; i++) {
    1431                         var element = elementRefAr[i];
    1432                         var elementId = element.name ? element.name : element.id;
    1433 
    1434                         if (tinyMCE.settings['ask']) {
    1435                                 // Focus breaks in Mozilla
    1436                                 if (tinyMCE.isGecko) {
    1437                                         var settings = tinyMCE.settings;
    1438 
    1439                                         tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE.prototype.confirmAdd(e, settings);}, 10);});
    1440                                 } else {
    1441                                         var settings = tinyMCE.settings;
    1442 
    1443                                         tinyMCE.addEvent(element, "focus", function () { TinyMCE.prototype.confirmAdd(null, settings); });
    1444                                 }
    1445                         } else
    1446                                 tinyMCE.addMCEControl(element, elementId);
    1447                 }
    1448 
    1449                 // Handle auto focus
    1450                 if (tinyMCE.settings['auto_focus']) {
    1451                         window.setTimeout(function () {
    1452                                 var inst = tinyMCE.getInstanceById(tinyMCE.settings['auto_focus']);
    1453                                 inst.selectNode(inst.getBody(), true, true);
    1454                                 inst.contentWindow.focus();
    1455                         }, 10);
    1456                 }
    1457 
    1458                 tinyMCE.executeCallback('oninit', '_oninit', 0);
    1459         }
    1460 };
    1461 
    1462 TinyMCE.prototype.removeMCEControl = function(editor_id) {
    1463         var inst = tinyMCE.getInstanceById(editor_id);
    1464 
    1465         if (inst) {
    1466                 inst.switchSettings();
    1467 
    1468                 editor_id = inst.editorId;
    1469                 var html = tinyMCE.getContent(editor_id);
    1470 
    1471                 // Remove editor instance from instances array
    1472                 var tmpInstances = new Array();
    1473                 for (var instanceName in tinyMCE.instances) {
    1474                         var instance = tinyMCE.instances[instanceName];
    1475                         if (!tinyMCE.isInstance(instance))
    1476                                 continue;
    1477 
    1478                         if (instanceName != editor_id)
    1479                                         tmpInstances[instanceName] = instance;
    1480                 }
    1481                 tinyMCE.instances = tmpInstances;
    1482 
    1483                 tinyMCE.selectedElement = null;
    1484                 tinyMCE.selectedInstance = null;
    1485 
    1486                 // Remove element
    1487                 var replaceElement = document.getElementById(editor_id + "_parent");
    1488                 var oldTargetElement = inst.oldTargetElement;
    1489                 var targetName = oldTargetElement.nodeName.toLowerCase();
    1490 
    1491                 if (targetName == "textarea" || targetName == "input") {
    1492                         // Just show the old text area
    1493                         replaceElement.parentNode.removeChild(replaceElement);
    1494                         oldTargetElement.style.display = "inline";
    1495                         oldTargetElement.value = html;
    1496                 } else {
    1497                         oldTargetElement.innerHTML = html;
    1498 
    1499                         replaceElement.parentNode.insertBefore(oldTargetElement, replaceElement);
    1500                         replaceElement.parentNode.removeChild(replaceElement);
    1501                 }
    1502         }
    1503 };
    1504 
    1505 TinyMCE.prototype._cleanupElementName = function(element_name, element) {
    1506         var name = "";
    1507 
    1508         element_name = element_name.toLowerCase();
    1509 
    1510         // Never include body
    1511         if (element_name == "body")
    1512                 return null;
    1513 
    1514         // If verification mode
    1515         if (tinyMCE.cleanup_verify_html) {
    1516                 // Check if invalid element
    1517                 for (var i=0; i<tinyMCE.cleanup_invalidElements.length; i++) {
    1518                         if (tinyMCE.cleanup_invalidElements[i] == element_name)
    1519                                 return null;
    1520                 }
    1521 
    1522                 // Check if valid element
    1523                 var validElement = false;
    1524                 var elementAttribs = null;
    1525                 for (var i=0; i<tinyMCE.cleanup_validElements.length && !elementAttribs; i++) {
    1526                         for (var x=0, n=tinyMCE.cleanup_validElements[i][0].length; x<n; x++) {
    1527                                 var elmMatch = tinyMCE.cleanup_validElements[i][0][x];
    1528 
    1529                                 if (elmMatch.charAt(0) == '+' || elmMatch.charAt(0) == '-')
    1530                                         elmMatch = elmMatch.substring(1);
    1531 
    1532                                 // Handle wildcard/regexp
    1533                                 if (elmMatch.match(new RegExp('\\*|\\?|\\+', 'g')) != null) {
    1534                                         elmMatch = elmMatch.replace(new RegExp('\\?', 'g'), '(\\S?)');
    1535                                         elmMatch = elmMatch.replace(new RegExp('\\+', 'g'), '(\\S+)');
    1536                                         elmMatch = elmMatch.replace(new RegExp('\\*', 'g'), '(\\S*)');
    1537                                         elmMatch = "^" + elmMatch + "$";
    1538                                         if (element_name.match(new RegExp(elmMatch, 'g'))) {
    1539                                                 elementAttribs = tinyMCE.cleanup_validElements[i];
    1540                                                 validElement = true;
    1541                                                 break;
    1542                                         }
    1543                                 }
    1544 
    1545                                 // Handle non regexp
    1546                                 if (element_name == elmMatch) {
    1547                                         elementAttribs = tinyMCE.cleanup_validElements[i];
    1548                                         validElement = true;
    1549                                         element_name = elementAttribs[0][0];
    1550                                         break;
    1551                                 }
    1552                         }
    1553                 }
    1554 
    1555                 if (!validElement)
    1556                         return null;
    1557         }
    1558 
    1559         if (element_name.charAt(0) == '+' || element_name.charAt(0) == '-')
    1560                 name = element_name.substring(1);
    1561 
    1562         // Special Mozilla stuff
    1563         if (!tinyMCE.isMSIE) {
    1564                 // Fix for bug #958498
    1565                 if (name == "strong" && !tinyMCE.cleanup_on_save)
    1566                         element_name = "b";
    1567                 else if (name == "em" && !tinyMCE.cleanup_on_save)
    1568                         element_name = "i";
    1569         }
    1570 
    1571         var elmData = new Object();
    1572 
    1573         elmData.element_name = element_name;
    1574         elmData.valid_attribs = elementAttribs;
    1575 
    1576         return elmData;
    1577 };
    1578 
    1579 /**
    1580  * This function moves CSS styles to/from attributes.
    1581  */
    1582 TinyMCE.prototype._moveStyle = function(elm, style, attrib) {
    1583         if (tinyMCE.cleanup_inline_styles) {
    1584                 var val = tinyMCE.getAttrib(elm, attrib);
    1585 
    1586                 if (val != '') {
    1587                         val = '' + val;
    1588 
    1589                         switch (attrib) {
    1590                                 case "background":
    1591                                         val = "url('" + val + "')";
    1592                                         break;
    1593 
    1594                                 case "bordercolor":
    1595                                         if (elm.style.borderStyle == '' || elm.style.borderStyle == 'none')
    1596                                                 elm.style.borderStyle = 'solid';
    1597                                         break;
    1598 
    1599                                 case "border":
    1600                                 case "width":
    1601                                 case "height":
    1602                                         if (attrib == "border" && elm.style.borderWidth > 0)
    1603                                                 return;
    1604 
    1605                                         if (val.indexOf('%') == -1)
    1606                                                 val += 'px';
    1607                                         break;
    1608 
    1609                                 case "vspace":
    1610                                 case "hspace":
    1611                                         elm.style.marginTop = val + "px";
    1612                                         elm.style.marginBottom = val + "px";
    1613                                         elm.removeAttribute(attrib);
    1614                                         return;
    1615 
    1616                                 case "align":
    1617                                         if (elm.nodeName == "IMG") {
    1618                                                 if (tinyMCE.isMSIE)
    1619                                                         elm.style.styleFloat = val;
    1620                                                 else
    1621                                                         elm.style.cssFloat = val;
    1622                                         } else
    1623                                                 elm.style.textAlign = val;
    1624 
    1625                                         elm.removeAttribute(attrib);
    1626                                         return;
    1627                         }
    1628 
    1629                         if (val != '') {
    1630                                 eval('elm.style.' + style + ' = val;');
    1631                                 elm.removeAttribute(attrib);
    1632                         }
    1633                 }
    1634         } else {
    1635                 if (style == '')
    1636                         return;
    1637 
    1638                 var val = eval('elm.style.' + style) == '' ? tinyMCE.getAttrib(elm, attrib) : eval('elm.style.' + style);
    1639                 val = val == null ? '' : '' + val;
    1640 
    1641                 switch (attrib) {
    1642                         // Always move background to style
    1643                         case "background":
    1644                                 if (val.indexOf('url') == -1 && val != '')
    1645                                         val = "url('" + val + "');";
    1646 
    1647                                 if (val != '') {
    1648                                         elm.style.backgroundImage = val;
    1649                                         elm.removeAttribute(attrib);
    1650                                 }
    1651                                 return;
    1652 
    1653                         case "border":
    1654                         case "width":
    1655                         case "height":
    1656                                 val = val.replace('px', '');
    1657                                 break;
    1658 
    1659                         case "align":
    1660                                 if (tinyMCE.getAttrib(elm, 'align') == '') {
    1661                                         if (elm.nodeName == "IMG") {
    1662                                                 if (tinyMCE.isMSIE && elm.style.styleFloat != '') {
    1663                                                         val = elm.style.styleFloat;
    1664                                                         style = 'styleFloat';
    1665                                                 } else if (tinyMCE.isGecko && elm.style.cssFloat != '') {
    1666                                                         val = elm.style.cssFloat;
    1667                                                         style = 'cssFloat';
    1668                                                 }
    1669                                         }
    1670                                 }
    1671                                 break;
    1672                 }
    1673 
    1674                 if (val != '') {
    1675                         elm.removeAttribute(attrib);
    1676                         elm.setAttribute(attrib, val);
    1677                         eval('elm.style.' + style + ' = "";');
    1678                 }
    1679         }
    1680 };
    1681 
    1682 TinyMCE.prototype._cleanupAttribute = function(valid_attributes, element_name, attribute_node, element_node) {
    1683         var attribName = attribute_node.nodeName.toLowerCase();
    1684         var attribValue = attribute_node.nodeValue;
    1685         var attribMustBeValue = null;
    1686         var verified = false;
    1687 
    1688         // Mozilla attibute, remove them
    1689         if (attribName.indexOf('moz_') != -1)
    1690                 return null;
    1691 
    1692         if (!tinyMCE.cleanup_on_save && (attribName == "mce_href" || attribName == "mce_src"))
    1693                 return {name : attribName, value : attribValue};
    1694 
    1695         // Verify attrib
    1696         if (tinyMCE.cleanup_verify_html && !verified) {
    1697                 for (var i=1; i<valid_attributes.length; i++) {
    1698                         var attribMatch = valid_attributes[i][0];
    1699                         var re = null;
    1700 
    1701                         // Build regexp from wildcard
    1702                         if (attribMatch.match(new RegExp('\\*|\\?|\\+', 'g')) != null) {
    1703                                 attribMatch = attribMatch.replace(new RegExp('\\?', 'g'), '(\\S?)');
    1704                                 attribMatch = attribMatch.replace(new RegExp('\\+', 'g'), '(\\S+)');
    1705                                 attribMatch = attribMatch.replace(new RegExp('\\*', 'g'), '(\\S*)');
    1706                                 attribMatch = "^" + attribMatch + "$";
    1707                                 re = new RegExp(attribMatch, 'g');
    1708                         }
    1709 
    1710                         if ((re && attribName.match(re) != null) || attribName == attribMatch) {
    1711                                 verified = true;
    1712                                 attribMustBeValue = valid_attributes[i][3];
    1713                                 break;
    1714                         }
    1715                 }
    1716 
    1717                 if (!verified)
    1718                         return false;
    1719         } else
    1720                 verified = true;
    1721 
    1722         // Treat some attribs diffrent
    1723         switch (attribName) {
    1724                 case "size":
    1725                         if (tinyMCE.isMSIE5 && element_name == "font")
    1726                                 attribValue = element_node.size;
    1727                         break;
    1728 
    1729                 case "width":
    1730                 case "height":
    1731                 case "border":
    1732                         // Old MSIE needs this
    1733                         if (tinyMCE.isMSIE5)
    1734                                 attribValue = eval("element_node." + attribName);
    1735                         break;
    1736 
    1737                 case "shape":
    1738                         attribValue = attribValue.toLowerCase();
    1739                         break;
    1740 
    1741                 case "cellspacing":
    1742                         if (tinyMCE.isMSIE5)
    1743                                 attribValue = element_node.cellSpacing;
    1744                         break;
    1745 
    1746                 case "cellpadding":
    1747                         if (tinyMCE.isMSIE5)
    1748                                 attribValue = element_node.cellPadding;
    1749                         break;
    1750 
    1751                 case "color":
    1752                         if (tinyMCE.isMSIE5 && element_name == "font")
    1753                                 attribValue = element_node.color;
    1754                         break;
    1755 
    1756                 case "class":
    1757                         // Remove mceItem classes from anchors
    1758                         if (tinyMCE.cleanup_on_save && attribValue.indexOf('mceItemAnchor') != -1)
    1759                                 attribValue = attribValue.replace(/mceItem[a-z0-9]+/gi, '');
    1760 
    1761                         if (element_name == "table" || element_name == "td" || element_name == "th") {
    1762                                 // Handle visual aid
    1763                                 if (tinyMCE.cleanup_visual_table_class != "")
    1764                                         attribValue = tinyMCE.getVisualAidClass(attribValue, !tinyMCE.cleanup_on_save);
    1765                         }
    1766 
    1767                         if (!tinyMCE._verifyClass(element_node) || attribValue == "")
    1768                                 return null;
    1769 
    1770                         break;
    1771 
    1772                 case "onfocus":
    1773                 case "onblur":
    1774                 case "onclick":
    1775                 case "ondblclick":
    1776                 case "onmousedown":
    1777                 case "onmouseup":
    1778                 case "onmouseover":
    1779                 case "onmousemove":
    1780                 case "onmouseout":
    1781                 case "onkeypress":
    1782                 case "onkeydown":
    1783                 case "onkeydown":
    1784                 case "onkeyup":
    1785                         attribValue = tinyMCE.cleanupEventStr("" + attribValue);
    1786 
    1787                         if (attribValue.indexOf('return false;') == 0)
    1788                                 attribValue = attribValue.substring(14);
    1789 
    1790                         break;
    1791 
    1792                 case "style":
    1793                         attribValue = tinyMCE.serializeStyle(tinyMCE.parseStyle(tinyMCE.getAttrib(element_node, "style")));
    1794                         break;
    1795 
    1796                 // Convert the URLs of these
    1797                 case "href":
    1798                 case "src":
    1799                 case "longdesc":
    1800                         attribValue = tinyMCE.getAttrib(element_node, attribName);
    1801 
    1802                         // Use mce_href instead
    1803                         var href = tinyMCE.getAttrib(element_node, "mce_href");
    1804                         if (attribName == "href" && href != "")
    1805                                 attribValue = href;
    1806 
    1807                         // Use mce_src instead
    1808                         var src = tinyMCE.getAttrib(element_node, "mce_src");
    1809                         if (attribName == "src" && src != "")
    1810                                 attribValue = src;
    1811 
    1812                         // Always use absolute URLs within TinyMCE
    1813                         if (!tinyMCE.cleanup_on_save)
    1814                                 attribValue = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], attribValue);
    1815                         else if (tinyMCE.getParam('convert_urls'))
    1816                                 attribValue = eval(tinyMCE.cleanup_urlconverter_callback + "(attribValue, element_node, tinyMCE.cleanup_on_save);");
    1817 
    1818                         break;
    1819 
    1820                 case "colspan":
    1821                 case "rowspan":
    1822                         // Not needed
    1823                         if (attribValue == "1")
    1824                                 return null;
    1825                         break;
    1826 
    1827                 // Skip these
    1828                 case "_moz-userdefined":
    1829                 case "editorid":
    1830                 case "mce_href":
    1831                 case "mce_src":
    1832                         return null;
    1833         }
    1834 
    1835         // Not the must be value
    1836         if (attribMustBeValue != null) {
    1837                 var isCorrect = false;
    1838                 for (var i=0; i<attribMustBeValue.length; i++) {
    1839                         if (attribValue == attribMustBeValue[i]) {
    1840                                 isCorrect = true;
    1841                                 break;
    1842                         }
    1843                 }
    1844 
    1845                 if (!isCorrect)
    1846                         return null;
    1847         }
    1848 
    1849         var attrib = new Object();
    1850 
    1851         attrib.name = attribName;
    1852         attrib.value = attribValue;
    1853 
    1854         return attrib;
    1855 };
    1856 
    1857 TinyMCE.prototype.clearArray = function(ar) {
    1858         // Since stupid people tend to extend core objects like
    1859         // Array with their own crap I needed to make functions that clean away
    1860         // this junk so the arrays get clean and nice as they should be
    1861         for (var key in ar)
    1862                 ar[key] = null;
    1863 };
    1864 
    1865 TinyMCE.prototype.isInstance = function(inst) {
    1866         return inst != null && typeof(inst) == "object" && inst.isTinyMCEControl;
    1867 };
    1868 
    1869 TinyMCE.prototype.parseStyle = function(str) {
     3490TinyMCE_Engine.prototype.parseStyle = function(str) {
    18703491        var ar = new Array();
    18713492
    … …  
    18913512};
    18923513
    1893 TinyMCE.prototype.compressStyle = function(ar, pr, sf, res) {
     3514TinyMCE_Engine.prototype.compressStyle = function(ar, pr, sf, res) {
    18943515        var box = new Array();
    18953516
    … …  
    19173538};
    19183539
    1919 TinyMCE.prototype.serializeStyle = function(ar) {
     3540TinyMCE_Engine.prototype.serializeStyle = function(ar) {
    19203541        var str = "";
    19213542
    … …  
    19273548        for (var key in ar) {
    19283549                var val = ar[key];
     3550
    19293551                if (typeof(val) == 'function')
     3552                        continue;
     3553
     3554                if (key.indexOf('mso-') == 0)
    19303555                        continue;
    19313556
    … …  
    19593584};
    19603585
    1961 TinyMCE.prototype.convertRGBToHex = function(s, k) {
     3586TinyMCE_Engine.prototype.convertRGBToHex = function(s, k) {
    19623587        if (s.toLowerCase().indexOf('rgb') != -1) {
    19633588                var re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
    … …  
    19823607};
    19833608
    1984 TinyMCE.prototype.convertHexToRGB = function(s) {
     3609TinyMCE_Engine.prototype.convertHexToRGB = function(s) {
    19853610        if (s.indexOf('#') != -1) {
    19863611                s = s.replace(new RegExp('[^0-9A-F]', 'gi'), '');
    … …  
    19913616};
    19923617
    1993 TinyMCE.prototype._verifyClass = function(node) {
    1994         // Sometimes the class gets set to null, weird Gecko bug?
    1995         if (tinyMCE.isGecko) {
    1996                 var className = node.getAttribute('class');
    1997                 if (!className)
    1998                         return false;
    1999         }
    2000 
    2001         // Trim CSS class
    2002         if (tinyMCE.isMSIE)
    2003                 var className = node.getAttribute('className');
    2004 
    2005         if (tinyMCE.cleanup_verify_css_classes && tinyMCE.cleanup_on_save) {
    2006                 var csses = tinyMCE.getCSSClasses();
    2007                 nonDefinedCSS = true;
    2008                 for (var c=0; c<csses.length; c++) {
    2009                         if (csses[c] == className) {
    2010                                 nonDefinedCSS = false;
     3618TinyMCE_Engine.prototype.convertSpansToFonts = function(doc) {
     3619        var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
     3620
     3621        var h = doc.body.innerHTML;
     3622        h = h.replace(/<span/gi, '<font');
     3623        h = h.replace(/<\/span/gi, '</font');
     3624        doc.body.innerHTML = h;
     3625
     3626        var s = doc.getElementsByTagName("font");
     3627        for (var i=0; i<s.length; i++) {
     3628                var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();
     3629                var fSize = 0;
     3630
     3631                for (var x=0; x<sizes.length; x++) {
     3632                        if (sizes[x] == size) {
     3633                                fSize = x + 1;
    20113634                                break;
    20123635                        }
    20133636                }
    20143637
    2015                 if (nonDefinedCSS && className.indexOf('mce_') != 0) {
    2016                         node.removeAttribute('className');
    2017                         node.removeAttribute('class');
    2018                         return false;
    2019                 }
    2020         }
    2021 
    2022         return true;
    2023 };
    2024 
    2025 TinyMCE.prototype.cleanupNode = function(node) {
    2026         var output = "";
    2027 
    2028         switch (node.nodeType) {
    2029                 case 1: // Element
    2030                         var elementData = tinyMCE._cleanupElementName(node.nodeName, node);
    2031                         var elementName = elementData ? elementData.element_name : null;
    2032                         var elementValidAttribs = elementData ? elementData.valid_attribs : null;
    2033                         var elementAttribs = "";
    2034                         var openTag = false, nonEmptyTag = false;
    2035 
    2036                         if (elementName != null && elementName.charAt(0) == '+') {
    2037                                 elementName = elementName.substring(1);
    2038                                 openTag = true;
    2039                         }
    2040 
    2041                         if (elementName != null && elementName.charAt(0) == '-') {
    2042                                 elementName = elementName.substring(1);
    2043                                 nonEmptyTag = true;
    2044                         }
    2045 
    2046                         // Checking DOM tree for MSIE weirdness!!
    2047                         if (tinyMCE.isMSIE && tinyMCE.settings['fix_content_duplication']) {
    2048                                 var lookup = tinyMCE.cleanup_elementLookupTable;
    2049 
    2050                                 for (var i=0; i<lookup.length; i++) {
    2051                                         // Found element reference else were, hmm?
    2052                                         if (lookup[i] == node)
    2053                                                 return output;
    2054                                 }
    2055 
    2056                                 // Add element to lookup table
    2057                                 lookup[lookup.length] = node;
    2058                         }
    2059 
    2060                         // Element not valid (only render children)
    2061                         if (!elementName) {
    2062                                 if (node.hasChildNodes()) {
    2063                                         for (var i=0; i<node.childNodes.length; i++)
    2064                                                 output += this.cleanupNode(node.childNodes[i]);
    2065                                 }
    2066 
    2067                                 return output;
    2068                         }
    2069 
    2070                         if (tinyMCE.cleanup_on_save) {
    2071                                 if (node.nodeName == "A" && node.className == "mceItemAnchor") {
    2072                                         if (node.hasChildNodes()) {
    2073                                                 for (var i=0; i<node.childNodes.length; i++)
    2074                                                         output += this.cleanupNode(node.childNodes[i]);
    2075                                         }
    2076 
    2077                                         return '<a name="' + this.convertStringToXML(node.getAttribute("name")) + '"></a>' + output;
    2078                                 }
    2079                         }
    2080 
    2081                         // Remove deprecated attributes
    2082                         var re = new RegExp("^(TABLE|TD|TR)$");
    2083                         if (re.test(node.nodeName)) {
    2084                                 // Move attrib to style
    2085                                 if ((node.nodeName != "TABLE" || tinyMCE.cleanup_inline_styles) && (width = tinyMCE.getAttrib(node, "width")) != '') {
    2086                                         node.style.width = width.indexOf('%') != -1 ? width : width.replace(/[^0-9]/gi, '') + "px";
    2087                                         node.removeAttribute("width");
    2088                                 }
    2089 
    2090                                 // Is table and not inline
    2091                                 if ((node.nodeName == "TABLE" && !tinyMCE.cleanup_inline_styles) && node.style.width != '') {
    2092                                         tinyMCE.setAttrib(node, "width", node.style.width.replace('px',''));
    2093                                         node.style.width = '';
    2094                                 }
    2095 
    2096                                 // Move attrib to style
    2097                                 if ((height = tinyMCE.getAttrib(node, "height")) != '') {
    2098                                         height = "" + height; // Force string
    2099                                         node.style.height = height.indexOf('%') != -1 ? height : height.replace(/[^0-9]/gi, '') + "px";
    2100                                         node.removeAttribute("height");
    2101                                 }
    2102                         }
    2103 
    2104                         // Handle inline/outline styles
    2105                         if (tinyMCE.cleanup_inline_styles) {
    2106                                 var re = new RegExp("^(TABLE|TD|TR|IMG|HR)$");
    2107                                 if (re.test(node.nodeName) && tinyMCE.getAttrib(node, "class").indexOf('mceItem') == -1) {
    2108                                         tinyMCE._moveStyle(node, 'width', 'width');
    2109                                         tinyMCE._moveStyle(node, 'height', 'height');
    2110                                         tinyMCE._moveStyle(node, 'borderWidth', 'border');
    2111                                         tinyMCE._moveStyle(node, '', 'vspace');
    2112                                         tinyMCE._moveStyle(node, '', 'hspace');
    2113                                         tinyMCE._moveStyle(node, 'textAlign', 'align');
    2114                                         tinyMCE._moveStyle(node, 'backgroundColor', 'bgColor');
    2115                                         tinyMCE._moveStyle(node, 'borderColor', 'borderColor');
    2116                                         tinyMCE._moveStyle(node, 'backgroundImage', 'background');
    2117 
    2118                                         // Refresh element in old MSIE
    2119                                         if (tinyMCE.isMSIE5)
    2120                                                 node.outerHTML = node.outerHTML;
    2121                                 } else if (tinyMCE.isBlockElement(node))
    2122                                         tinyMCE._moveStyle(node, 'textAlign', 'align');
    2123 
    2124                                 if (node.nodeName == "FONT")
    2125                                         tinyMCE._moveStyle(node, 'color', 'color');
    2126                         }
    2127 
    2128                         // Set attrib data
    2129                         if (elementValidAttribs) {
    2130                                 for (var a=1; a<elementValidAttribs.length; a++) {
    2131                                         var attribName, attribDefaultValue, attribForceValue, attribValue;
    2132 
    2133                                         attribName = elementValidAttribs[a][0];
    2134                                         attribDefaultValue = elementValidAttribs[a][1];
    2135                                         attribForceValue = elementValidAttribs[a][2];
    2136 
    2137                                         if (attribDefaultValue != null || attribForceValue != null) {
    2138                                                 var attribValue = node.getAttribute(attribName);
    2139 
    2140                                                 if (node.getAttribute(attribName) == null || node.getAttribute(attribName) == "")
    2141                                                         attribValue = attribDefaultValue;
    2142 
    2143                                                 attribValue = attribForceValue ? attribForceValue : attribValue;
    2144 
    2145                                                 // Is to generate id
    2146                                                 if (attribValue == "{$uid}")
    2147                                                         attribValue = "uid_" + (tinyMCE.cleanup_idCount++);
    2148 
    2149                                                 // Add visual aid class
    2150                                                 if (attribName == "class")
    2151                                                         attribValue = tinyMCE.getVisualAidClass(attribValue, tinyMCE.cleanup_on_save);
    2152 
    2153                                                 node.setAttribute(attribName, attribValue);
    2154                                                 //alert(attribName + "=" + attribValue);
    2155                                         }
    2156                                 }
    2157                         }
    2158 
    2159                         if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && elementName == "style")
    2160                                 return "<style>" + node.innerHTML + "</style>";
    2161 
    2162                         // Remove empty tables
    2163                         if (elementName == "table" && !node.hasChildNodes())
    2164                                 return "";
    2165 
    2166                         // Handle element attributes
    2167                         if (node.attributes.length > 0) {
    2168                                 var lastAttrib = "";
    2169 
    2170                                 for (var i=0; i<node.attributes.length; i++) {
    2171                                         if (node.attributes[i].specified) {
    2172                                                 // Is the attrib already processed (removed duplicate attributes in opera TD[align=left])
    2173                                                 if (tinyMCE.isOpera) {
    2174                                                         if (node.attributes[i].nodeName == lastAttrib)
    2175                                                                 continue;
    2176 
    2177                                                         lastAttrib = node.attributes[i].nodeName;
    2178                                                 }
    2179 
    2180                                                 // tinyMCE.debug(node.nodeName, node.attributes[i].nodeName, node.attributes[i].nodeValue, node.innerHTML);
    2181                                                 var attrib = tinyMCE._cleanupAttribute(elementValidAttribs, elementName, node.attributes[i], node);
    2182                                                 if (attrib && attrib.value != "")
    2183                                                         elementAttribs += " " + attrib.name + "=" + '"' + this.convertStringToXML("" + attrib.value) + '"';
    2184                                         }
    2185                                 }
    2186                         }
    2187 
    2188                         // MSIE table summary fix (MSIE 5.5)
    2189                         if (tinyMCE.isMSIE && elementName == "table" && node.getAttribute("summary") != null && elementAttribs.indexOf('summary') == -1) {
    2190                                 var summary = tinyMCE.getAttrib(node, 'summary');
    2191                                 if (summary != '')
    2192                                         elementAttribs += " summary=" + '"' + this.convertStringToXML(summary) + '"';
    2193                         }
    2194 
    2195                         // Handle missing attributes in MSIE 5.5
    2196                         if (tinyMCE.isMSIE5 && /^(td|img|a)$/.test(elementName)) {
    2197                                 var ma = new Array("scope", "longdesc", "hreflang", "charset", "type");
    2198 
    2199                                 for (var u=0; u<ma.length; u++) {
    2200                                         if (node.getAttribute(ma[u]) != null) {
    2201                                                 var s = tinyMCE.getAttrib(node, ma[u]);
    2202 
    2203                                                 if (s != '')
    2204                                                         elementAttribs += " " + ma[u] + "=" + '"' + this.convertStringToXML(s) + '"';
    2205                                         }
    2206                                 }
    2207                         }
    2208 
    2209                         // MSIE form element issue
    2210                         if (tinyMCE.isMSIE && elementName == "input") {
    2211                                 if (node.type) {
    2212                                         if (!elementAttribs.match(/ type=/g))
    2213                                                 elementAttribs += " type=" + '"' + node.type + '"';
    2214                                 }
    2215 
    2216                                 if (node.value) {
    2217                                         if (!elementAttribs.match(/ value=/g))
    2218                                                 elementAttribs += " value=" + '"' + node.value + '"';
    2219                                 }
    2220                         }
    2221 
    2222                         // Add nbsp to some elements
    2223                         if ((elementName == "p" || elementName == "td") && (node.innerHTML == "" || node.innerHTML == "&nbsp;"))
    2224                                 return "<" + elementName + elementAttribs + ">" + this.convertStringToXML(String.fromCharCode(160)) + "</" + elementName + ">";
    2225 
    2226                         // Is MSIE script element
    2227                         if (tinyMCE.isMSIE && elementName == "script")
    2228                                 return "<" + elementName + elementAttribs + ">" + node.text + "</" + elementName + ">";
    2229 
    2230                         // Clean up children
    2231                         if (node.hasChildNodes()) {
    2232                                 // If not empty span
    2233                                 if (!(elementName == "span" && elementAttribs == "" && tinyMCE.getParam("trim_span_elements"))) {
    2234                                         // Force BR
    2235                                         if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)
    2236                                                 output += "<div" + elementAttribs + ">";
    2237                                         else
    2238                                                 output += "<" + elementName + elementAttribs + ">";
    2239                                 }
    2240 
    2241                                 for (var i=0; i<node.childNodes.length; i++)
    2242                                         output += this.cleanupNode(node.childNodes[i]);
    2243 
    2244                                 // If not empty span
    2245                                 if (!(elementName == "span" && elementAttribs == "" && tinyMCE.getParam("trim_span_elements"))) {
    2246                                         // Force BR
    2247                                         if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)
    2248                                                 output += "</div><br />";
    2249                                         else
    2250                                                 output += "</" + elementName + ">";
    2251                                 }
    2252                         } else {
    2253                                 if (!nonEmptyTag) {
    2254                                         if (openTag)
    2255                                                 output += "<" + elementName + elementAttribs + "></" + elementName + ">";
    2256                                         else
    2257                                                 output += "<" + elementName + elementAttribs + " />";
    2258                                 }
    2259                         }
    2260 
    2261                         return output;
    2262 
    2263                 case 3: // Text
    2264                         // Do not convert script elements
    2265                         if (node.parentNode.nodeName == "SCRIPT" || node.parentNode.nodeName == "NOSCRIPT" || node.parentNode.nodeName == "STYLE")
    2266                                 return node.nodeValue;
    2267 
    2268                         return this.convertStringToXML(node.nodeValue);
    2269 
    2270                 case 8: // Comment
    2271                         return "<!--" + node.nodeValue + "-->";
    2272 
    2273                 default: // Unknown
    2274                         return "[UNKNOWN NODETYPE " + node.nodeType + "]";
     3638                if (fSize > 0) {
     3639                        tinyMCE.setAttrib(s[i], 'size', fSize);
     3640                        s[i].style.fontSize = '';
     3641                }
     3642
     3643                var fFace = s[i].style.fontFamily;
     3644                if (fFace != null && fFace != "") {
     3645                        tinyMCE.setAttrib(s[i], 'face', fFace);
     3646                        s[i].style.fontFamily = '';
     3647                }
     3648
     3649                var fColor = s[i].style.color;
     3650                if (fColor != null && fColor != "") {
     3651                        tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));
     3652                        s[i].style.color = '';
     3653                }
    22753654        }
    22763655};
    22773656
    2278 TinyMCE.prototype.convertStringToXML = function(html_data) {
    2279     var output = "";
    2280 
    2281         for (var i=0; i<html_data.length; i++) {
    2282                 var chr = html_data.charCodeAt(i);
    2283 
    2284                 // Numeric entities
    2285                 if (tinyMCE.settings['entity_encoding'] == "numeric") {
    2286                         if (chr > 127)
    2287                                 output += '&#' + chr + ";";
    2288                         else
    2289                                 output += String.fromCharCode(chr);
    2290 
    2291                         continue;
    2292                 }
    2293 
    2294                 // Raw entities
    2295                 if (tinyMCE.settings['entity_encoding'] == "raw") {
    2296                         output += String.fromCharCode(chr);
    2297                         continue;
    2298                 }
    2299 
    2300                 // Named entities
    2301                 if (typeof(tinyMCE.settings['cleanup_entities']["c" + chr]) != 'undefined' && tinyMCE.settings['cleanup_entities']["c" + chr] != '')
    2302                         output += '&' + tinyMCE.settings['cleanup_entities']["c" + chr] + ';';
    2303                 else
    2304                         output += '' + String.fromCharCode(chr);
    2305     }
    2306 
    2307     return output;
     3657TinyMCE_Engine.prototype.convertFontsToSpans = function(doc) {
     3658        var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
     3659
     3660        var h = doc.body.innerHTML;
     3661        h = h.replace(/<font/gi, '<span');
     3662        h = h.replace(/<\/font/gi, '</span');
     3663        doc.body.innerHTML = h;
     3664
     3665        var fsClasses = tinyMCE.getParam('font_size_classes');
     3666        if (fsClasses != '')
     3667                fsClasses = fsClasses.replace(/\s+/, '').split(',');
     3668        else
     3669                fsClasses = null;
     3670
     3671        var s = doc.getElementsByTagName("span");
     3672        for (var i=0; i<s.length; i++) {
     3673                var fSize, fFace, fColor;
     3674
     3675                fSize = tinyMCE.getAttrib(s[i], 'size');
     3676                fFace = tinyMCE.getAttrib(s[i], 'face');
     3677                fColor = tinyMCE.getAttrib(s[i], 'color');
     3678
     3679                if (fSize != "") {
     3680                        fSize = parseInt(fSize);
     3681
     3682                        if (fSize > 0 && fSize < 8) {
     3683                                if (fsClasses != null)
     3684                                        tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);
     3685                                else
     3686                                        s[i].style.fontSize = sizes[fSize-1];
     3687                        }
     3688
     3689                        s[i].removeAttribute('size');
     3690                }
     3691
     3692                if (fFace != "") {
     3693                        s[i].style.fontFamily = fFace;
     3694                        s[i].removeAttribute('face');
     3695                }
     3696
     3697                if (fColor != "") {
     3698                        s[i].style.color = fColor;
     3699                        s[i].removeAttribute('color');
     3700                }
     3701        }
    23083702};
    23093703
    2310 TinyMCE.prototype._getCleanupElementName = function(chunk) {
    2311         var pos;
    2312 
    2313         if (chunk.charAt(0) == '+')
    2314                 chunk = chunk.substring(1);
    2315 
    2316         if (chunk.charAt(0) == '-')
    2317                 chunk = chunk.substring(1);
    2318 
    2319         if ((pos = chunk.indexOf('/')) != -1)
    2320                 chunk = chunk.substring(0, pos);
    2321 
    2322         if ((pos = chunk.indexOf('[')) != -1)
    2323                 chunk = chunk.substring(0, pos);
    2324 
    2325         return chunk;
     3704TinyMCE_Engine.prototype.cleanupAnchors = function(doc) {
     3705        var i, cn, x, an = doc.getElementsByTagName("a");
     3706
     3707        for (i=0; i<an.length; i++) {
     3708                if (tinyMCE.getAttrib(an[i], "name") != "" && tinyMCE.getAttrib(an[i], "href") == "") {
     3709                        cn = an[i].childNodes;
     3710
     3711                        for (x=cn.length-1; x>=0; x--)
     3712                                tinyMCE.insertAfter(cn[x], an[i]);
     3713                }
     3714        }
    23263715};
    23273716
    2328 TinyMCE.prototype._initCleanup = function() {
    2329         // Parse valid elements and attributes
    2330         var validElements = tinyMCE.settings["valid_elements"];
    2331         validElements = validElements.split(',');
    2332 
    2333         // Handle extended valid elements
    2334         var extendedValidElements = tinyMCE.settings["extended_valid_elements"];
    2335         extendedValidElements = extendedValidElements.split(',');
    2336         for (var i=0; i<extendedValidElements.length; i++) {
    2337                 var elementName = this._getCleanupElementName(extendedValidElements[i]);
    2338                 var skipAdd = false;
    2339 
    2340                 // Check if it's defined before, if so override that one
    2341                 for (var x=0; x<validElements.length; x++) {
    2342                         if (this._getCleanupElementName(validElements[x]) == elementName) {
    2343                                 validElements[x] = extendedValidElements[i];
    2344                                 skipAdd = true;
    2345                                 break;
    2346                         }
    2347                 }
    2348 
    2349                 if (!skipAdd)
    2350                         validElements[validElements.length] = extendedValidElements[i];
     3717TinyMCE_Engine.prototype.getContent = function(editor_id) {
     3718        var h;
     3719
     3720        if (typeof(editor_id) != "undefined")
     3721                tinyMCE.selectedInstance = tinyMCE.getInstanceById(editor_id);
     3722
     3723        if (tinyMCE.selectedInstance) {
     3724                h = tinyMCE._cleanupHTML(this.selectedInstance, this.selectedInstance.getDoc(), tinyMCE.settings, this.selectedInstance.getBody(), false, true);
     3725
     3726                // When editing always use fonts internaly
     3727                if (tinyMCE.getParam("convert_fonts_to_spans"))
     3728                        tinyMCE.convertSpansToFonts(this.selectedInstance.getDoc());
     3729
     3730                return h;
    23513731        }
    23523732
    2353         for (var i=0; i<validElements.length; i++) {
    2354                 var item = validElements[i];
    2355 
    2356                 item = item.replace('[','|');
    2357                 item = item.replace(']','');
    2358 
    2359                 // Split and convert
    2360                 var attribs = item.split('|');
    2361                 for (var x=0; x<attribs.length; x++)
    2362                         attribs[x] = attribs[x].toLowerCase();
    2363 
    2364                 // Handle change elements
    2365                 attribs[0] = attribs[0].split('/');
    2366 
    2367                 // Handle default attribute values
    2368                 for (var x=1; x<attribs.length; x++) {
    2369                         var attribName = attribs[x];
    2370                         var attribDefault = null;
    2371                         var attribForce = null;
    2372                         var attribMustBe = null;
    2373 
    2374                         // Default value
    2375                         if ((pos = attribName.indexOf('=')) != -1) {
    2376                                 attribDefault = attribName.substring(pos+1);
    2377                                 attribName = attribName.substring(0, pos);
    2378                         }
    2379 
    2380                         // Force check
    2381                         if ((pos = attribName.indexOf(':')) != -1) {
    2382                                 attribForce = attribName.substring(pos+1);
    2383                                 attribName = attribName.substring(0, pos);
    2384                         }
    2385 
    2386                         // Force check
    2387                         if ((pos = attribName.indexOf('<')) != -1) {
    2388                                 attribMustBe = attribName.substring(pos+1).split('?');
    2389                                 attribName = attribName.substring(0, pos);
    2390                         }
    2391 
    2392                         attribs[x] = new Array(attribName, attribDefault, attribForce, attribMustBe);
    2393                 }
    2394 
    2395                 validElements[i] = attribs;
     3733        return null;
     3734};
     3735
     3736TinyMCE_Engine.prototype._fixListElements = function(d) {
     3737        var nl, x, a = ['ol', 'ul'], i, n, p, r = new RegExp('^(OL|UL)$'), np;
     3738
     3739        for (x=0; x<a.length; x++) {
     3740                nl = d.getElementsByTagName(a[x]);
     3741
     3742                for (i=0; i<nl.length; i++) {
     3743                        n = nl[i];
     3744                        p = n.parentNode;
     3745
     3746                        if (r.test(p.nodeName)) {
     3747                                np = tinyMCE.prevNode(n, 'LI');
     3748
     3749                                if (!np) {
     3750                                        np = d.createElement('li');
     3751                                        np.innerHTML = '&nbsp;';
     3752                                        np.appendChild(n);
     3753                                        p.insertBefore(np, p.firstChild);
     3754                                } else
     3755                                        np.appendChild(n);
     3756                        }
     3757                }
    23963758        }
    2397 
    2398         var invalidElements = tinyMCE.settings['invalid_elements'].split(',');
    2399         for (var i=0; i<invalidElements.length; i++)
    2400                 invalidElements[i] = invalidElements[i].toLowerCase();
    2401 
    2402         // Set these for performance
    2403         tinyMCE.settings['cleanup_validElements'] = validElements;
    2404         tinyMCE.settings['cleanup_invalidElements'] = invalidElements;
    24053759};
    24063760
    2407 TinyMCE.prototype._cleanupHTML = function(inst, doc, config, element, visual, on_save) {
    2408         if (!tinyMCE.settings['cleanup']) {
    2409                 tinyMCE.handleVisualAid(inst.getBody(), true, false, inst);
    2410 
    2411                 var html = element.innerHTML;
    2412 
    2413                 // Remove mce_href/mce_src
    2414                 html = html.replace(new RegExp('(mce_href|mce_src)=".*?"', 'gi'), '');
    2415                 html = html.replace(/\s+>/gi, '>');
    2416 
    2417                 return html;
     3761TinyMCE_Engine.prototype._fixTables = function(d) {
     3762        var nl, i, n, p, np, x, t;
     3763
     3764        nl = d.getElementsByTagName('table');
     3765        for (i=0; i<nl.length; i++) {
     3766                n = nl[i];
     3767
     3768                if ((p = tinyMCE.getParentElement(n, 'p,div,h1,h2,h3,h4,h5,h6')) != null) {
     3769                        np = p.cloneNode(false);
     3770                        np.removeAttribute('id');
     3771
     3772                        t = n;
     3773
     3774                        while ((n = n.nextSibling))
     3775                                np.appendChild(n);
     3776
     3777                        tinyMCE.insertAfter(np, p);
     3778                        tinyMCE.insertAfter(t, p);
     3779                }
    24183780        }
    2419 
    2420         if (on_save && tinyMCE.getParam("convert_fonts_to_spans"))
     3781};
     3782
     3783TinyMCE_Engine.prototype._cleanupHTML = function(inst, doc, config, elm, visual, on_save, on_submit) {
     3784        var h, d, t1, t2, t3, t4, t5, c, s;
     3785
     3786        if (!tinyMCE.getParam('cleanup'))
     3787                return elm.innerHTML;
     3788
     3789        on_save = typeof(on_save) == 'undefined' ? false : on_save;
     3790
     3791        c = inst.cleanup;
     3792        s = inst.settings;
     3793        d = c.settings.debug;
     3794
     3795        if (d)
     3796                t1 = new Date().getTime();
     3797
     3798        if (tinyMCE.getParam("convert_fonts_to_spans"))
    24213799                tinyMCE.convertFontsToSpans(doc);
     3800
     3801        if (tinyMCE.getParam("fix_list_elements"))
     3802                tinyMCE._fixListElements(doc);
     3803
     3804        if (tinyMCE.getParam("fix_table_elements"))
     3805                tinyMCE._fixTables(doc);
    24223806
    24233807        // Call custom cleanup code
    24243808        tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body);
    24253809
    2426         // Move bgcolor to style
    2427         var n = doc.getElementsByTagName("font");
    2428         for (var i=0; i<n.length; i++) {
    2429                 var c = "";
    2430                 if ((c = tinyMCE.getAttrib(n[i], "bgcolor")) != "") {
    2431                         n[i].style.backgroundColor = c;
    2432                         tinyMCE.setAttrib(n[i], "bgcolor", "");
    2433                 }
     3810        if (d)
     3811                t2 = new Date().getTime();
     3812
     3813        c.settings.on_save = on_save;
     3814        //for (var i=0; i<100; i++)
     3815
     3816        c.idCount = 0;
     3817        c.serializationId++;
     3818        c.serializedNodes = new Array();
     3819        c.sourceIndex = -1;
     3820
     3821        if (s.cleanup_serializer == "xml")
     3822                h = c.serializeNodeAsXML(elm);
     3823        else
     3824                h = c.serializeNodeAsHTML(elm);
     3825
     3826        if (d)
     3827                t3 = new Date().getTime();
     3828
     3829        // Post processing
     3830        h = h.replace(/<\/?(body|head|html)[^>]*>/gi, '');
     3831        h = h.replace(new RegExp(' (rowspan="1"|colspan="1")', 'g'), '');
     3832        h = h.replace(/<p><hr \/><\/p>/g, '<hr />');
     3833        h = h.replace(/<p>(&nbsp;|&#160;)<\/p><hr \/><p>(&nbsp;|&#160;)<\/p>/g, '<hr />');
     3834        h = h.replace(/<td>\s*<br \/>\s*<\/td>/g, '<td>&nbsp;</td>');
     3835        h = h.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>&nbsp;</p>');
     3836        h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*(&nbsp;|&#160;)\s*<\/p>/g, '<p>&nbsp;</p>');
     3837        h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*<\/p>/g, '<p>&nbsp;</p>');
     3838        h = h.replace(/<p>\s*<br \/>\s*&nbsp;\s*<\/p>/g, '<p>&nbsp;</p>');
     3839        h = h.replace(/<a>(.*?)<\/a>/g, '$1');
     3840        h = h.replace(/<p([^>]*)>\s*<\/p>/g, '<p$1>&nbsp;</p>');
     3841
     3842        // Clean body
     3843        if (/^\s*(<br \/>|<p>&nbsp;<\/p>|<p>&#160;<\/p>|<p><\/p>)\s*$/.test(h))
     3844                h = '';
     3845
     3846        // If preformatted
     3847        if (s.preformatted) {
     3848                h = h.replace(/^<pre>/, '');
     3849                h = h.replace(/<\/pre>$/, '');
     3850                h = '<pre>' + h + '</pre>';
    24343851        }
    24353852
    2436         // Set these for performance
    2437         tinyMCE.cleanup_validElements = tinyMCE.settings['cleanup_validElements'];
    2438         tinyMCE.cleanup_invalidElements = tinyMCE.settings['cleanup_invalidElements'];
    2439         tinyMCE.cleanup_verify_html = tinyMCE.settings['verify_html'];
    2440         tinyMCE.cleanup_force_br_newlines = tinyMCE.settings['force_br_newlines'];
    2441         tinyMCE.cleanup_urlconverter_callback = tinyMCE.settings['urlconverter_callback'];
    2442         tinyMCE.cleanup_verify_css_classes = tinyMCE.settings['verify_css_classes'];
    2443         tinyMCE.cleanup_visual_table_class = tinyMCE.settings['visual_table_class'];
    2444         tinyMCE.cleanup_apply_source_formatting = tinyMCE.settings['apply_source_formatting'];
    2445         tinyMCE.cleanup_inline_styles = tinyMCE.settings['inline_styles'];
    2446         tinyMCE.cleanup_visual_aid = visual;
    2447         tinyMCE.cleanup_on_save = on_save;
    2448         tinyMCE.cleanup_idCount = 0;
    2449         tinyMCE.cleanup_elementLookupTable = new Array();
    2450 
    2451         var startTime = new Date().getTime();
    2452 
    2453         // Cleanup madness that breaks the editor in MSIE
     3853        // Gecko specific processing
     3854        if (tinyMCE.isGecko) {
     3855                h = h.replace(/<o:p _moz-userdefined="" \/>/g, '');
     3856                h = h.replace(/<td([^>]*)>\s*<br \/>\s*<\/td>/g, '<td$1>&nbsp;</td>');
     3857        }
     3858
     3859        if (s.force_br_newlines)
     3860                h = h.replace(/<p>(&nbsp;|&#160;)<\/p>/g, '<br />');
     3861
     3862        // Call custom cleanup code
     3863        h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h);
     3864
     3865        // Remove internal classes
     3866        if (on_save) {
     3867                h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), '');
     3868                h = h.replace(new RegExp(' ?class=""', 'g'), '');
     3869        }
     3870
     3871        if (s.remove_linebreaks && !c.settings.indent)
     3872                h = h.replace(/\n|\r/g, ' ');
     3873
     3874        if (d)
     3875                t4 = new Date().getTime();
     3876
     3877        if (on_save && c.settings.indent)
     3878                h = c.formatHTML(h);
     3879
     3880        // If encoding (not recommended option)
     3881        if (on_submit && (s.encoding == "xml" || s.encoding == "html"))
     3882                h = c.xmlEncode(h);
     3883
     3884        if (d)
     3885                t5 = new Date().getTime();
     3886
     3887        if (c.settings.debug)
     3888                tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + ".");
     3889
     3890        return h;
     3891};
     3892
     3893function TinyMCE_Cleanup() {
     3894        this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
     3895        this.rules = tinyMCE.clearArray(new Array());
     3896
     3897        // Default config
     3898        this.settings = {
     3899                indent_elements : 'head,table,tbody,thead,tfoot,form,tr,ul,ol,blockquote,object',
     3900                newline_before_elements : 'h1,h2,h3,h4,h5,h6,pre,address,div,ul,ol,li,meta,option,area,title,link,base,script,td',
     3901                newline_after_elements : 'br,hr,p,pre,address,div,ul,ol,meta,option,area,link,base,script',
     3902                newline_before_after_elements : 'html,head,body,table,thead,tbody,tfoot,tr,form,ul,ol,blockquote,p,object,param,hr,div',
     3903                indent_char : '\t',
     3904                indent_levels : 1,
     3905                entity_encoding : 'raw',
     3906                valid_elements : '*[*]',
     3907                entities : '',
     3908                url_converter : '',
     3909                invalid_elements : '',
     3910                verify_html : false
     3911        };
     3912
     3913        this.vElements = tinyMCE.clearArray(new Array());
     3914        this.vElementsRe = '';
     3915        this.closeElementsRe = /^(IMG|BR|HR|LINK|META|BASE|INPUT|BUTTON)$/;
     3916        this.codeElementsRe = /^(SCRIPT|STYLE)$/;
     3917        this.serializationId = 0;
     3918        this.mceAttribs = {
     3919                href : 'mce_href',
     3920                src : 'mce_src',
     3921                type : 'mce_type'
     3922        };
     3923}
     3924
     3925TinyMCE_Cleanup.prototype = {
     3926        init : function(s) {
     3927                var n, a, i, ir, or, st;
     3928
     3929                for (n in s)
     3930                        this.settings[n] = s[n];
     3931
     3932                // Setup code formating
     3933                s = this.settings;
     3934
     3935                // Setup regexps
     3936                this.inRe = this._arrayToRe(s.indent_elements.split(','), '', '^<(', ')[^>]*');
     3937                this.ouRe = this._arrayToRe(s.indent_elements.split(','), '', '^<\\/(', ')[^>]*');
     3938                this.nlBeforeRe = this._arrayToRe(s.newline_before_elements.split(','), 'gi', '<(',  ')([^>]*)>');
     3939                this.nlAfterRe = this._arrayToRe(s.newline_after_elements.split(','), 'gi', '<(',  ')([^>]*)>');
     3940                this.nlBeforeAfterRe = this._arrayToRe(s.newline_before_after_elements.split(','), 'gi', '<(\\/?)(', ')([^>]*)>');
     3941
     3942                if (s.invalid_elements != '')
     3943                        this.iveRe = this._arrayToRe(s.invalid_elements.toUpperCase().split(','), 'g', '^(', ')$');
     3944                else
     3945                        this.iveRe = null;
     3946
     3947                // Setup separator
     3948                st = '';
     3949                for (i=0; i<s.indent_levels; i++)
     3950                        st += s.indent_char;
     3951
     3952                this.inStr = st;
     3953
     3954                // If verify_html if false force *[*]
     3955                if (!s.verify_html) {
     3956                        s.valid_elements = '*[*]';
     3957                        s.extended_valid_elements = '';
     3958                }
     3959
     3960                this.fillStr = s.entity_encoding == "named" ? "&nbsp;" : "&#160;";
     3961                this.idCount = 0;
     3962        },
     3963
     3964        addRuleStr : function(s) {
     3965                var r = this.parseRuleStr(s);
     3966                var n;
     3967
     3968                for (n in r) {
     3969                        if (r[n])
     3970                                this.rules[n] = r[n];
     3971                }
     3972
     3973                this.vElements = tinyMCE.clearArray(new Array());
     3974
     3975                for (n in this.rules) {
     3976                        if (this.rules[n])
     3977                                this.vElements[this.vElements.length] = this.rules[n].tag;
     3978                }
     3979
     3980                this.vElementsRe = this._arrayToRe(this.vElements, '');
     3981        },
     3982
     3983        parseRuleStr : function(s) {
     3984                var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray(new Array()), dv;
     3985
     3986                if (s == null || s.length == 0)
     3987                        return or;
     3988
     3989                ta = s.split(',');
     3990                for (x=0; x<ta.length; x++) {
     3991                        s = ta[x];
     3992                        if (s.length == 0)
     3993                                continue;
     3994
     3995                        // Split tag/attrs
     3996                        p = this.split(/\[|\]/, s);
     3997                        if (p == null || p.length < 1)
     3998                                t = s.toUpperCase();
     3999                        else
     4000                                t = p[0].toUpperCase();
     4001
     4002                        // Handle all tag names
     4003                        tn = this.split('/', t);
     4004                        for (y=0; y<tn.length; y++) {
     4005                                r = {};
     4006
     4007                                r.tag = tn[y];
     4008                                r.forceAttribs = null;
     4009                                r.defaultAttribs = null;
     4010                                r.validAttribValues = null;
     4011
     4012                                // Handle prefixes
     4013                                px = r.tag.charAt(0);
     4014                                r.forceOpen = px == '+';
     4015                                r.removeEmpty = px == '-';
     4016                                r.fill = px == '#';
     4017                                r.tag = r.tag.replace(/\+|-|#/g, '');
     4018                                r.oTagName = tn[0].replace(/\+|-|#/g, '').toLowerCase();
     4019                                r.isWild = new RegExp('\\*|\\?|\\+', 'g').test(r.tag);
     4020                                r.validRe = new RegExp(this._wildcardToRe('^' + r.tag + '$'));
     4021
     4022                                // Setup valid attributes
     4023                                if (p.length > 1) {
     4024                                        r.vAttribsRe = '^(';
     4025                                        a = this.split(/\|/, p[1]);
     4026
     4027                                        for (i=0; i<a.length; i++) {
     4028                                                t = a[i];
     4029
     4030                                                av = /(=|:|<)(.*?)$/.exec(t);
     4031                                                t = t.replace(/(=|:|<).*?$/, '');
     4032                                                if (av && av.length > 0) {
     4033                                                        if (av[0].charAt(0) == ':') {
     4034                                                                if (!r.forceAttribs)
     4035                                                                        r.forceAttribs = tinyMCE.clearArray(new Array());
     4036
     4037                                                                r.forceAttribs[t.toLowerCase()] = av[0].substring(1);
     4038                                                        } else if (av[0].charAt(0) == '=') {
     4039                                                                if (!r.defaultAttribs)
     4040                                                                        r.defaultAttribs = tinyMCE.clearArray(new Array());
     4041
     4042                                                                dv = av[0].substring(1);
     4043
     4044                                                                r.defaultAttribs[t.toLowerCase()] = dv == "" ? "mce_empty" : dv;
     4045                                                        } else if (av[0].charAt(0) == '<') {
     4046                                                                if (!r.validAttribValues)
     4047                                                                        r.validAttribValues = tinyMCE.clearArray(new Array());
     4048
     4049                                                                r.validAttribValues[t.toLowerCase()] = this._arrayToRe(this.split('?', av[0].substring(1)), '');
     4050                                                        }
     4051                                                }
     4052
     4053                                                r.vAttribsRe += '' + t.toLowerCase() + (i != a.length - 1 ? '|' : '');
     4054
     4055                                                a[i] = t.toLowerCase();
     4056                                        }
     4057
     4058                                        r.vAttribsRe += ')$';
     4059                                        r.vAttribsRe = this._wildcardToRe(r.vAttribsRe);
     4060                                        r.vAttribsReIsWild = new RegExp('\\*|\\?|\\+', 'g').test(r.vAttribsRe);
     4061                                        r.vAttribsRe = new RegExp(r.vAttribsRe);
     4062                                        r.vAttribs = a.reverse();
     4063
     4064                                        //tinyMCE.debug(r.tag, r.oTagName, r.vAttribsRe, r.vAttribsReWC);
     4065                                } else {
     4066                                        r.vAttribsRe = '';
     4067                                        r.vAttribs = tinyMCE.clearArray(new Array());
     4068                                        r.vAttribsReIsWild = false;
     4069                                }
     4070
     4071                                or[r.tag] = r;
     4072                        }
     4073                }
     4074
     4075                return or;
     4076        },
     4077
     4078        serializeNodeAsXML : function(n) {
     4079                var s, b;
     4080
     4081                if (!this.xmlDoc) {
     4082                        if (this.isMSIE) {
     4083                                try {this.xmlDoc = new ActiveXObject('MSXML2.DOMDocument');} catch (e) {}
     4084
     4085                                if (!this.xmlDoc)
     4086                                        try {this.xmlDoc = new ActiveXObject('Microsoft.XmlDom');} catch (e) {}
     4087                        } else
     4088                                this.xmlDoc = document.implementation.createDocument('', '', null);
     4089
     4090                        if (!this.xmlDoc)
     4091                                alert("Error XML Parser could not be found.");
     4092                }
     4093
     4094                if (this.xmlDoc.firstChild)
     4095                        this.xmlDoc.removeChild(this.xmlDoc.firstChild);
     4096
     4097                b = this.xmlDoc.createElement("html");
     4098                b = this.xmlDoc.appendChild(b);
     4099
     4100                this._convertToXML(n, b);
     4101
     4102                if (this.isMSIE)
     4103                        return this.xmlDoc.xml;
     4104                else
     4105                        return new XMLSerializer().serializeToString(this.xmlDoc);
     4106        },
     4107
     4108        _convertToXML : function(n, xn) {
     4109                var xd, el, i, l, cn, at, no, hc = false;
     4110
     4111                if (this._isDuplicate(n))
     4112                        return;
     4113
     4114                xd = this.xmlDoc;
     4115
     4116                switch (n.nodeType) {
     4117                        case 1: // Element
     4118                                hc = n.hasChildNodes();
     4119
     4120                                el = xd.createElement(n.nodeName.toLowerCase());
     4121
     4122                                at = n.attributes;
     4123                                for (i=at.length-1; i>-1; i--) {
     4124                                        no = at[i];
     4125
     4126                                        if (no.specified && no.nodeValue)
     4127                                                el.setAttribute(no.nodeName.toLowerCase(), no.nodeValue);
     4128                                }
     4129
     4130                                if (!hc && !this.closeElementsRe.test(n.nodeName))
     4131                                        el.appendChild(xd.createTextNode(""));
     4132
     4133                                xn = xn.appendChild(el);
     4134                                break;
     4135
     4136                        case 3: // Text
     4137                                xn.appendChild(xd.createTextNode(n.nodeValue));
     4138                                return;
     4139
     4140                        case 8: // Comment
     4141                                xn.appendChild(xd.createComment(n.nodeValue));
     4142                                return;
     4143                }
     4144
     4145                if (hc) {
     4146                        cn = n.childNodes;
     4147
     4148                        for (i=0, l=cn.length; i<l; i++)
     4149                                this._convertToXML(cn[i], xn);
     4150                }
     4151        },
     4152
     4153        serializeNodeAsHTML : function(n) {
     4154                var en, no, h = '', i, l, r, cn, va = false, f = false, at, hc;
     4155
     4156                this._setupRules(); // Will initialize cleanup rules
     4157
     4158                if (this._isDuplicate(n))
     4159                        return '';
     4160
     4161                switch (n.nodeType) {
     4162                        case 1: // Element
     4163                                hc = n.hasChildNodes();
     4164
     4165                                // MSIE sometimes produces <//tag>
     4166                                if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && n.nodeName.indexOf('/') != -1)
     4167                                        break;
     4168
     4169                                if (this.vElementsRe.test(n.nodeName) && (!this.iveRe || !this.iveRe.test(n.nodeName))) {
     4170                                        va = true;
     4171
     4172                                        r = this.rules[n.nodeName];
     4173                                        if (!r) {
     4174                                                at = this.rules;
     4175                                                for (no in at) {
     4176                                                        if (at[no] && at[no].validRe.test(n.nodeName)) {
     4177                                                                r = at[no];
     4178                                                                break;
     4179                                                        }
     4180                                                }
     4181                                        }
     4182
     4183                                        en = r.isWild ? n.nodeName.toLowerCase() : r.oTagName;
     4184                                        f = r.fill;
     4185
     4186                                        if (r.removeEmpty && !hc)
     4187                                                return "";
     4188
     4189                                        h += '<' + en;
     4190
     4191                                        if (r.vAttribsReIsWild) {
     4192                                                // Serialize wildcard attributes
     4193                                                at = n.attributes;
     4194                                                for (i=at.length-1; i>-1; i--) {
     4195                                                        no = at[i];
     4196                                                        if (no.specified && r.vAttribsRe.test(no.nodeName))
     4197                                                                h += this._serializeAttribute(n, r, no.nodeName);
     4198                                                }
     4199                                        } else {
     4200                                                // Serialize specific attributes
     4201                                                for (i=r.vAttribs.length-1; i>-1; i--)
     4202                                                        h += this._serializeAttribute(n, r, r.vAttribs[i]);
     4203                                        }
     4204
     4205                                        // Serialize mce_ atts
     4206                                        if (!this.settings.on_save) {
     4207                                                at = this.mceAttribs;
     4208
     4209                                                for (no in at) {
     4210                                                        if (at[no])
     4211                                                                h += this._serializeAttribute(n, r, at[no]);
     4212                                                }
     4213                                        }
     4214
     4215                                        // Close these
     4216                                        if (this.closeElementsRe.test(n.nodeName))
     4217                                                return h + ' />';
     4218
     4219                                        h += '>';
     4220
     4221                                        if (this.isMSIE && this.codeElementsRe.test(n.nodeName))
     4222                                                h += n.innerHTML;
     4223                                }
     4224                        break;
     4225
     4226                        case 3: // Text
     4227                                if (n.parentNode && this.codeElementsRe.test(n.parentNode.nodeName))
     4228                                        return this.isMSIE ? '' : n.nodeValue;
     4229
     4230                                return this.xmlEncode(n.nodeValue);
     4231
     4232                        case 8: // Comment
     4233                                return "<!--" + this._trimComment(n.nodeValue) + "-->";
     4234                }
     4235
     4236                if (hc) {
     4237                        cn = n.childNodes;
     4238
     4239                        for (i=0, l=cn.length; i<l; i++)
     4240                                h += this.serializeNodeAsHTML(cn[i]);
     4241                }
     4242
     4243                // Fill empty nodes
     4244                if (f && !hc)
     4245                        h += this.fillStr;
     4246
     4247                // End element
     4248                if (va)
     4249                        h += '</' + en + '>';
     4250
     4251                return h;
     4252        },
     4253
     4254        _serializeAttribute : function(n, r, an) {
     4255                var av = '', t, os = this.settings.on_save;
     4256
     4257                if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0))
     4258                        return '';
     4259
     4260                if (os && this.mceAttribs[an])
     4261                        av = this._getAttrib(n, this.mceAttribs[an]);
     4262
     4263                if (av.length == 0)
     4264                        av = this._getAttrib(n, an);
     4265
     4266                if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) {
     4267                        av = t;
     4268
     4269                        if (av == "mce_empty")
     4270                                return " " + an + '=""';
     4271                }
     4272
     4273                if (r.forceAttribs && (t = r.forceAttribs[an]))
     4274                        av = t;
     4275
     4276                if (os && av.length != 0 && this.settings.url_converter.length != 0 && /^(src|href|longdesc)$/.test(an))
     4277                        av = eval(this.settings.url_converter + '(this, n, av)');
     4278
     4279                if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av))
     4280                        return "";
     4281
     4282                if (av.length != 0 && av == "{$uid}")
     4283                        av = "uid_" + (this.idCount++);
     4284
     4285                if (av.length != 0)
     4286                        return " " + an + "=" + '"' + this.xmlEncode(av) + '"';
     4287
     4288                return "";
     4289        },
     4290
     4291        formatHTML : function(h) {
     4292                var s = this.settings, p = '', i = 0, li = 0, o = '', l;
     4293
     4294                h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :)
     4295                h = '\n' + h;
     4296                h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting
     4297                h = h.replace(this.nlBeforeRe, '\n<$1$2>');
     4298                h = h.replace(this.nlAfterRe, '<$1$2>\n');
     4299                h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n');
     4300                h += '\n';
     4301
     4302                //tinyMCE.debug(h);
     4303
     4304                while ((i = h.indexOf('\n', i + 1)) != -1) {
     4305                        if ((l = h.substring(li + 1, i)).length != 0) {
     4306                                if (this.ouRe.test(l) && p.length >= s.indent_levels)
     4307                                        p = p.substring(s.indent_levels);
     4308
     4309                                o += p + l + '\n';
     4310       
     4311                                if (this.inRe.test(l))
     4312                                        p += this.inStr;
     4313                        }
     4314
     4315                        li = i;
     4316                }
     4317
     4318                //tinyMCE.debug(h);
     4319
     4320                return o;
     4321        },
     4322
     4323        xmlEncode : function(s) {
     4324                var i, l, e, o = '', c;
     4325
     4326                this._setupEntities(); // Will intialize lookup table
     4327
     4328                switch (this.settings.entity_encoding) {
     4329                        case "raw":
     4330                                return tinyMCE.xmlEncode(s);
     4331
     4332                        case "named":
     4333                                for (i=0, l=s.length; i<l; i++) {
     4334                                        c = s.charCodeAt(i);
     4335                                        e = this.entities[c];
     4336
     4337                                        // &apos; is not working in MSIE
     4338                                        // More info: http://www.w3.org/TR/xhtml1/#C_16
     4339                                        if (c == 39) {
     4340                                                o += "&#39;";
     4341                                                continue;
     4342                                        }
     4343
     4344                                        if (e && e != '')
     4345                                                o += '&' + e + ';';
     4346                                        else
     4347                                                o += String.fromCharCode(c);
     4348                                }
     4349
     4350                                return o;
     4351
     4352                        case "numeric":
     4353                                for (i=0, l=s.length; i<l; i++) {
     4354                                        c = s.charCodeAt(i);
     4355
     4356                                        if (c > 127 || c == 60 || c == 62 || c == 38 || c == 39 || c == 34)
     4357                                                o += '&#' + c + ";";
     4358                                        else
     4359                                                o += String.fromCharCode(c);
     4360                                }
     4361
     4362                                return o;
     4363                }
     4364
     4365                return s;
     4366        },
     4367
     4368        split : function(re, s) {
     4369                var c = s.split(re);
     4370                var i, l, o = new Array();
     4371
     4372                for (i=0, l=c.length; i<l; i++) {
     4373                        if (c[i] != '')
     4374                                o[i] = c[i];
     4375                }
     4376
     4377                return o;
     4378        },
     4379
     4380        _trimComment : function(s) {
     4381                // Make xsrc, xhref as src and href again
     4382                if (tinyMCE.isGecko) {
     4383                        s = s.replace(/\sxsrc=/gi, " src=");
     4384                        s = s.replace(/\sxhref=/gi, " href=");
     4385                }
     4386
     4387                // Remove mce_src, mce_href
     4388                s = s.replace(new RegExp('\\smce_src=\"[^\"]*\"', 'gi'), "");
     4389                s = s.replace(new RegExp('\\smce_href=\"[^\"]*\"', 'gi'), "");
     4390
     4391                return s;
     4392        },
     4393
     4394        _getAttrib : function(e, n, d) {
     4395                if (typeof(d) == "undefined")
     4396                        d = "";
     4397
     4398                if (!e || e.nodeType != 1)
     4399                        return d;
     4400
     4401                var v = e.getAttribute(n, 0);
     4402
     4403                if (n == "class" && !v)
     4404                        v = e.className;
     4405
     4406                if (this.isMSIE && n == "http-equiv")
     4407                        v = e.httpEquiv;
     4408
     4409                if (n == "style" && !tinyMCE.isOpera)
     4410                        v = e.style.cssText;
     4411
     4412                if (n == 'style')
     4413                        v = tinyMCE.serializeStyle(tinyMCE.parseStyle(v));
     4414
     4415                if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v != "")
     4416                        v = tinyMCE.cleanupEventStr(v);
     4417
     4418                return (v && v != "") ? '' + v : d;
     4419        },
     4420
     4421        _urlConverter : function(c, n, v) {
     4422                if (!c.settings.on_save)
     4423                        return tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, v);
     4424                else if (tinyMCE.getParam('convert_urls'))
     4425                        return eval(tinyMCE.settings.urlconverter_callback + "(v, n, true);");
     4426
     4427                return v;
     4428        },
     4429
     4430        _arrayToRe : function(a, op, be, af) {
     4431                var i, r;
     4432
     4433                op = typeof(op) == "undefined" ? "gi" : op;
     4434                be = typeof(be) == "undefined" ? "^(" : be;
     4435                af = typeof(af) == "undefined" ? ")$" : af;
     4436
     4437                r = be;
     4438
     4439                for (i=0; i<a.length; i++)
     4440                        r += this._wildcardToRe(a[i]) + (i != a.length-1 ? "|" : "");
     4441
     4442                r += af;
     4443
     4444                return new RegExp(r, op);
     4445        },
     4446
     4447        _wildcardToRe : function(s) {
     4448                s = s.replace(/\?/g, '(\\S?)');
     4449                s = s.replace(/\+/g, '(\\S+)');
     4450                s = s.replace(/\*/g, '(\\S*)');
     4451
     4452                return s;
     4453        },
     4454
     4455        _setupEntities : function() {
     4456                var n, a, i, s = this.settings;
     4457
     4458                // Setup entities
     4459                if (!this.entitiesDone) {
     4460                        if (s.entity_encoding == "named") {
     4461                                n = tinyMCE.clearArray(new Array());
     4462                                a = this.split(',', s.entities);
     4463                                for (i=0; i<a.length; i+=2)
     4464                                        n[a[i]] = a[i+1];
     4465
     4466                                this.entities = n;
     4467                        }
     4468
     4469                        this.entitiesDone = true;
     4470                }
     4471        },
     4472
     4473        _setupRules : function() {
     4474                var s = this.settings;
     4475
     4476                // Setup default rule
     4477                if (!this.rulesDone) {
     4478                        this.addRuleStr(s.valid_elements);
     4479                        this.addRuleStr(s.extended_valid_elements);
     4480
     4481                        this.rulesDone = true;
     4482                }
     4483        },
     4484
     4485        _isDuplicate : function(n) {
     4486                var i;
     4487
     4488                if (!this.settings.fix_content_duplication)
     4489                        return false;
     4490
     4491                if (tinyMCE.isMSIE && !tinyMCE.isOpera && n.nodeType == 1) {
     4492                        // Mark elements
     4493                        if (n.mce_serialized == this.serializationId)
     4494                                return true;
     4495
     4496                        n.setAttribute('mce_serialized', this.serializationId);
     4497                } else {
     4498                        // Search lookup table for text nodes  and comments
     4499                        for (i=0; i<this.serializedNodes.length; i++) {
     4500                                if (this.serializedNodes[i] == n)
     4501                                        return true;
     4502                        }
     4503
     4504                        this.serializedNodes[this.serializedNodes.length] = n;
     4505                }
     4506
     4507                return false;
     4508        }
     4509};
     4510
     4511/* file:jscripts/tiny_mce/classes/TinyMCE_DOMUtils.class.js */
     4512
     4513TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) {
     4514        return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
     4515};
     4516
     4517TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) {
     4518        var i, nl = n.getElementsByTagName(e), o = new Array();
     4519
     4520        for (i=0; i<nl.length; i++) {
     4521                if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1)
     4522                        o[o.length] = nl[i];
     4523        }
     4524
     4525        return o;
     4526};
     4527
     4528TinyMCE_Engine.prototype.isBlockElement = function(n) {
     4529        return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName);
     4530};
     4531
     4532TinyMCE_Engine.prototype.getParentBlockElement = function(n) {
     4533        while (n) {
     4534                if (this.isBlockElement(n))
     4535                        return n;
     4536
     4537                n = n.parentNode;
     4538        }
     4539
     4540        return null;
     4541};
     4542
     4543TinyMCE_Engine.prototype.insertAfter = function(n, r){
     4544        if (r.nextSibling)
     4545                r.parentNode.insertBefore(n, r.nextSibling);
     4546        else
     4547                r.parentNode.appendChild(n);
     4548};
     4549
     4550TinyMCE_Engine.prototype.setInnerHTML = function(e, h) {
     4551        var i, nl, n;
     4552
     4553        if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
     4554                // Since MSIE handles invalid HTML better that valid XHTML we
     4555                // need to make some things invalid. <hr /> gets converted to <hr>.
     4556                h = h.replace(/\s\/>/g, '>');
     4557
     4558                // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
     4559                h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
     4560                h = h.replace(/<p([^>]*)>&nbsp;<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
     4561
     4562                // Remove first comment
     4563                e.innerHTML = tinyMCE.uniqueTag + h;
     4564                e.firstChild.removeNode(true);
     4565
     4566                // Remove weird auto generated empty paragraphs unless it's supposed to be there
     4567                nl = e.getElementsByTagName("p");
     4568                for (i=nl.length-1; i>=0; i--) {
     4569                        n = nl[i];
     4570
     4571                        if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
     4572                                n.parentNode.removeChild(n);
     4573                }
     4574        } else {
     4575                h = this.fixGeckoBaseHREFBug(1, e, h);
     4576                e.innerHTML = h;
     4577                this.fixGeckoBaseHREFBug(2, e, h);
     4578        }
     4579};
     4580
     4581TinyMCE_Engine.prototype.getOuterHTML = function(e) {
     4582        if (tinyMCE.isMSIE)
     4583                return e.outerHTML;
     4584
     4585        var d = e.ownerDocument.createElement("body");
     4586        d.appendChild(e);
     4587        return d.innerHTML;
     4588};
     4589
     4590TinyMCE_Engine.prototype.setOuterHTML = function(e, h) {
    24544591        if (tinyMCE.isMSIE) {
    2455                 // Remove null ids from HR elements, results in runtime error
    2456                 var nodes = element.getElementsByTagName("hr");
    2457                 for (var i=0; i<nodes.length; i++) {
    2458                         if (nodes[i].id == "null")
    2459                                 nodes[i].removeAttribute("id");
    2460                 }
    2461 
    2462                 tinyMCE.setInnerHTML(element, tinyMCE.regexpReplace(element.innerHTML, '<p>[ \n\r]*<hr.*>[ \n\r]*</p>', '<hr />', 'gi'));
    2463                 tinyMCE.setInnerHTML(element, tinyMCE.regexpReplace(element.innerHTML, '<!([^-(DOCTYPE)]* )|<!/[^-]*>', '', 'gi'));
    2464         }
    2465 
    2466         var html = this.cleanupNode(element);
    2467 
    2468         if (tinyMCE.settings['debug'])
    2469                 tinyMCE.debug("Cleanup process executed in: " + (new Date().getTime()-startTime) + " ms.");
    2470 
    2471         // Remove pesky HR paragraphs and other crap
    2472         html = tinyMCE.regexpReplace(html, '<p><hr /></p>', '<hr />');
    2473         html = tinyMCE.regexpReplace(html, '<p>&nbsp;</p><hr /><p>&nbsp;</p>', '<hr />');
    2474         html = tinyMCE.regexpReplace(html, '<td>\\s*<br />\\s*</td>', '<td>&nbsp;</td>');
    2475         html = tinyMCE.regexpReplace(html, '<p>\\s*<br />\\s*</p>', '<p>&nbsp;</p>');
    2476         html = tinyMCE.regexpReplace(html, '<p>\\s*&nbsp;\\s*<br />\\s*&nbsp;\\s*</p>', '<p>&nbsp;</p>');
    2477         html = tinyMCE.regexpReplace(html, '<p>\\s*&nbsp;\\s*<br />\\s*</p>', '<p>&nbsp;</p>');
    2478         html = tinyMCE.regexpReplace(html, '<p>\\s*<br />\\s*&nbsp;\\s*</p>', '<p>&nbsp;</p>');
    2479 
    2480         // Remove empty anchors
    2481         html = html.replace(new RegExp('<a>(.*?)</a>', 'gi'), '$1');
    2482 
    2483         // Remove some mozilla crap
    2484         if (!tinyMCE.isMSIE)
    2485                 html = html.replace(new RegExp('<o:p _moz-userdefined="" />', 'g'), "");
    2486 
    2487         if (tinyMCE.settings['remove_linebreaks'])
    2488                 html = html.replace(new RegExp('\r|\n', 'g'), ' ');
    2489 
    2490         if (tinyMCE.getParam('apply_source_formatting')) {
    2491                 html = html.replace(new RegExp('<(p|div)([^>]*)>', 'g'), "\n<$1$2>\n");
    2492                 html = html.replace(new RegExp('<\/(p|div)([^>]*)>', 'g'), "\n</$1$2>\n");
    2493                 html = html.replace(new RegExp('<br />', 'g'), "<br />\n");
    2494         }
    2495 
    2496         if (tinyMCE.settings['force_br_newlines']) {
    2497                 var re = new RegExp('<p>&nbsp;</p>', 'g');
    2498                 html = html.replace(re, "<br />");
    2499         }
    2500 
    2501         if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt']) {
    2502                 // Remove weridness!
    2503                 var re = new RegExp('&lt;&gt;', 'g');
    2504                 html = html.replace(re, "");
    2505         }
    2506 
    2507         // Call custom cleanup code
    2508         html = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", html);
    2509 
    2510         // Emtpy node, return empty
    2511         var chk = tinyMCE.regexpReplace(html, "[ \t\r\n]", "").toLowerCase();
    2512         if (chk == "<br/>" || chk == "<br>" || chk == "<p>&nbsp;</p>" || chk == "<p>&#160;</p>" || chk == "<p></p>")
    2513                 html = "";
    2514 
    2515         if (tinyMCE.settings["preformatted"])
    2516                 return "<pre>" + html + "</pre>";
    2517 
    2518         return html;
    2519 };
    2520 
    2521 TinyMCE.prototype.insertLink = function(href, target, title, onclick, style_class) {
    2522         tinyMCE.execCommand('mceBeginUndoLevel');
    2523 
    2524         if (this.selectedInstance && this.selectedElement && this.selectedElement.nodeName.toLowerCase() == "img") {
    2525                 var doc = this.selectedInstance.getDoc();
    2526                 var linkElement = tinyMCE.getParentElement(this.selectedElement, "a");
    2527                 var newLink = false;
    2528 
    2529                 if (!linkElement) {
    2530                         linkElement = doc.createElement("a");
    2531                         newLink = true;
    2532                 }
    2533 
    2534                 var mhref = href;
    2535                 var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);");
    2536                 mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
    2537 
    2538                 tinyMCE.setAttrib(linkElement, 'href', thref);
    2539                 tinyMCE.setAttrib(linkElement, 'mce_href', mhref);
    2540                 tinyMCE.setAttrib(linkElement, 'target', target);
    2541                 tinyMCE.setAttrib(linkElement, 'title', title);
    2542         tinyMCE.setAttrib(linkElement, 'onclick', onclick);
    2543                 tinyMCE.setAttrib(linkElement, 'class', style_class);
    2544 
    2545                 if (newLink) {
    2546                         linkElement.appendChild(this.selectedElement.cloneNode(true));
    2547                         this.selectedElement.parentNode.replaceChild(linkElement, this.selectedElement);
    2548                 }
    2549 
     4592                e.outerHTML = h;
    25504593                return;
    25514594        }
    25524595
    2553         if (!this.linkElement && this.selectedInstance) {
    2554                 if (tinyMCE.isSafari) {
    2555                         tinyMCE.execCommand("mceInsertContent", false, '<a href="' + tinyMCE.uniqueURL + '">' + this.selectedInstance.getSelectedHTML() + '</a>');
    2556                 } else
    2557                         this.selectedInstance.contentDocument.execCommand("createlink", false, tinyMCE.uniqueURL);
    2558 
    2559                 tinyMCE.linkElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
    2560 
    2561                 var elementArray = this.getElementsByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
    2562 
    2563                 for (var i=0; i<elementArray.length; i++) {
    2564                         var mhref = href;
    2565                         var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, elementArray[i]);");
    2566                         mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
    2567 
    2568                         tinyMCE.setAttrib(elementArray[i], 'href', thref);
    2569                         tinyMCE.setAttrib(elementArray[i], 'mce_href', mhref);
    2570                         tinyMCE.setAttrib(elementArray[i], 'target', target);
    2571                         tinyMCE.setAttrib(elementArray[i], 'title', title);
    2572             tinyMCE.setAttrib(elementArray[i], 'onclick', onclick);
    2573                         tinyMCE.setAttrib(elementArray[i], 'class', style_class);
    2574                 }
    2575 
    2576                 tinyMCE.linkElement = elementArray[0];
     4596        var d = e.ownerDocument.createElement("body");
     4597        d.innerHTML = h;
     4598        e.parentNode.replaceChild(d.firstChild, e);
     4599};
     4600
     4601TinyMCE_Engine.prototype._getElementById = function(id, d) {
     4602        var e, i, j, f;
     4603
     4604        if (typeof(d) == "undefined")
     4605                d = document;
     4606
     4607        e = d.getElementById(id);
     4608        if (!e) {
     4609                f = d.forms;
     4610
     4611                for (i=0; i<f.length; i++) {
     4612                        for (j=0; j<f[i].elements.length; j++) {
     4613                                if (f[i].elements[j].name == id) {
     4614                                        e = f[i].elements[j];
     4615                                        break;
     4616                                }
     4617                        }
     4618                }
    25774619        }
    25784620
    2579         if (this.linkElement) {
    2580                 var mhref = href;
    2581                 href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, this.linkElement);");
    2582                 mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
    2583 
    2584                 tinyMCE.setAttrib(this.linkElement, 'href', href);
    2585                 tinyMCE.setAttrib(this.linkElement, 'mce_href', mhref);
    2586                 tinyMCE.setAttrib(this.linkElement, 'target', target);
    2587                 tinyMCE.setAttrib(this.linkElement, 'title', title);
    2588         tinyMCE.setAttrib(this.linkElement, 'onclick', onclick);
    2589                 tinyMCE.setAttrib(this.linkElement, 'class', style_class);
     4621        return e;
     4622};
     4623
     4624TinyMCE_Engine.prototype.getNodeTree = function(n, na, t, nn) {
     4625        var i;
     4626
     4627        if (typeof(t) == "undefined" || n.nodeType == t && (typeof(nn) == "undefined" || n.nodeName == nn))
     4628                na[na.length] = n;
     4629
     4630        if (n.hasChildNodes()) {
     4631                for (i=0; i<n.childNodes.length; i++)
     4632                        tinyMCE.getNodeTree(n.childNodes[i], na, t, nn);
    25904633        }
    25914634
    2592         tinyMCE.execCommand('mceEndUndoLevel');
     4635        return na;
    25934636};
    25944637
    2595 TinyMCE.prototype.insertImage = function(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout) {
    2596         tinyMCE.execCommand('mceBeginUndoLevel');
    2597 
    2598         if (src == "")
    2599                 return;
    2600 
    2601         if (!this.imgElement && tinyMCE.isSafari) {
    2602                 var html = "";
    2603 
    2604                 html += '<img src="' + src + '" alt="' + alt + '"';
    2605                 html += ' border="' + border + '" hspace="' + hspace + '"';
    2606                 html += ' vspace="' + vspace + '" width="' + width + '"';
    2607                 html += ' height="' + height + '" align="' + align + '" title="' + title + '" onmouseover="' + onmouseover + '" onmouseout="' + onmouseout + '" />';
    2608 
    2609                 tinyMCE.execCommand("mceInsertContent", false, html);
    2610         } else {
    2611                 if (!this.imgElement && this.selectedInstance) {
    2612                         if (tinyMCE.isSafari)
    2613                                 tinyMCE.execCommand("mceInsertContent", false, '<img src="' + tinyMCE.uniqueURL + '" />');
    2614                         else
    2615                                 this.selectedInstance.contentDocument.execCommand("insertimage", false, tinyMCE.uniqueURL);
    2616 
    2617                         tinyMCE.imgElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "img", "src", tinyMCE.uniqueURL);
    2618                 }
    2619         }
    2620 
    2621         if (this.imgElement) {
    2622                 var needsRepaint = false;
    2623                 var msrc = src;
    2624 
    2625                 src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, tinyMCE.imgElement);");
    2626 
    2627                 if (tinyMCE.getParam('convert_urls'))
    2628                         msrc = src;
    2629 
    2630                 if (onmouseover && onmouseover != "")
    2631                         onmouseover = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, tinyMCE.imgElement);") + "';";
    2632 
    2633                 if (onmouseout && onmouseout != "")
    2634                         onmouseout = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, tinyMCE.imgElement);") + "';";
    2635 
    2636                 // Use alt as title if it's undefined
    2637                 if (typeof(title) == "undefined")
    2638                         title = alt;
    2639 
    2640                 if (width != this.imgElement.getAttribute("width") || height != this.imgElement.getAttribute("height") || align != this.imgElement.getAttribute("align"))
    2641                         needsRepaint = true;
    2642 
    2643                 tinyMCE.setAttrib(this.imgElement, 'src', src);
    2644                 tinyMCE.setAttrib(this.imgElement, 'mce_src', msrc);
    2645                 tinyMCE.setAttrib(this.imgElement, 'alt', alt);
    2646                 tinyMCE.setAttrib(this.imgElement, 'title', title);
    2647                 tinyMCE.setAttrib(this.imgElement, 'align', align);
    2648                 tinyMCE.setAttrib(this.imgElement, 'border', border, true);
    2649                 tinyMCE.setAttrib(this.imgElement, 'hspace', hspace, true);
    2650                 tinyMCE.setAttrib(this.imgElement, 'vspace', vspace, true);
    2651                 tinyMCE.setAttrib(this.imgElement, 'width', width, true);
    2652                 tinyMCE.setAttrib(this.imgElement, 'height', height, true);
    2653                 tinyMCE.setAttrib(this.imgElement, 'onmouseover', onmouseover);
    2654                 tinyMCE.setAttrib(this.imgElement, 'onmouseout', onmouseout);
    2655 
    2656                 // Fix for bug #989846 - Image resize bug
    2657                 if (width && width != "")
    2658                         this.imgElement.style.pixelWidth = width;
    2659 
    2660                 if (height && height != "")
    2661                         this.imgElement.style.pixelHeight = height;
    2662 
    2663                 if (needsRepaint)
    2664                         tinyMCE.selectedInstance.repaint();
    2665         }
    2666 
    2667         tinyMCE.execCommand('mceEndUndoLevel');
    2668 };
    2669 
    2670 TinyMCE.prototype.getElementByAttributeValue = function(node, element_name, attrib, value) {
    2671         var elements = this.getElementsByAttributeValue(node, element_name, attrib, value);
    2672         if (elements.length == 0)
    2673                 return null;
    2674 
    2675         return elements[0];
    2676 };
    2677 
    2678 TinyMCE.prototype.getElementsByAttributeValue = function(node, element_name, attrib, value) {
    2679         var elements = new Array();
    2680 
    2681         if (node && node.nodeName.toLowerCase() == element_name) {
    2682                 if (node.getAttribute(attrib) && node.getAttribute(attrib).indexOf(value) != -1)
    2683                         elements[elements.length] = node;
    2684         }
    2685 
    2686         if (node && node.hasChildNodes()) {
    2687                 for (var x=0, n=node.childNodes.length; x<n; x++) {
    2688                         var childElements = this.getElementsByAttributeValue(node.childNodes[x], element_name, attrib, value);
    2689                         for (var i=0, m=childElements.length; i<m; i++)
    2690                                 elements[elements.length] = childElements[i];
    2691                 }
    2692         }
    2693 
    2694         return elements;
    2695 };
    2696 
    2697 TinyMCE.prototype.isBlockElement = function(node) {
    2698         return node != null && node.nodeType == 1 && this.blockRegExp.test(node.nodeName);
    2699 };
    2700 
    2701 TinyMCE.prototype.getParentBlockElement = function(node) {
    2702         // Search up the tree for block element
    2703         while (node) {
    2704                 if (this.blockRegExp.test(node.nodeName))
    2705                         return node;
    2706 
    2707                 node = node.parentNode;
    2708         }
    2709 
    2710         return null;
    2711 };
    2712 
    2713 TinyMCE.prototype.getNodeTree = function(node, node_array, type, node_name) {
    2714         if (typeof(type) == "undefined" || node.nodeType == type && (typeof(node_name) == "undefined" || node.nodeName == node_name))
    2715                 node_array[node_array.length] = node;
    2716 
    2717         if (node.hasChildNodes()) {
    2718                 for (var i=0; i<node.childNodes.length; i++)
    2719                         tinyMCE.getNodeTree(node.childNodes[i], node_array, type, node_name);
    2720         }
    2721 
    2722         return node_array;
    2723 };
    2724 
    2725 TinyMCE.prototype.getParentElement = function(node, names, attrib_name, attrib_value) {
     4638TinyMCE_Engine.prototype.getParentElement = function(node, names, attrib_name, attrib_value) {
    27264639        if (typeof(names) == "undefined") {
    27274640                if (node.nodeType == 1)
    … …  
    27344647        }
    27354648
    2736         var namesAr = names.split(',');
    2737 
    27384649        if (node == null)
    27394650                return null;
    27404651
     4652        var namesAr = names.toUpperCase().split(',');
     4653
    27414654        do {
    27424655                for (var i=0; i<namesAr.length; i++) {
    2743                         if (node.nodeName.toLowerCase() == namesAr[i].toLowerCase() || names == "*") {
     4656                        if (node.nodeName == namesAr[i] || names == "*") {
    27444657                                if (typeof(attrib_name) == "undefined")
    27454658                                        return node;
    … …  
    27584671};
    27594672
    2760 TinyMCE.prototype.convertURL = function(url, node, on_save) {
    2761         var prot = document.location.protocol;
    2762         var host = document.location.hostname;
    2763         var port = document.location.port;
    2764 
    2765         // Pass through file protocol
    2766         if (prot == "file:")
    2767                 return url;
    2768 
    2769         // Something is wrong, remove weirdness
    2770         url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
    2771 
    2772         // Mailto link or anchor (Pass through)
    2773         if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#")
    2774                 return url;
    2775 
    2776         // Fix relative/Mozilla
    2777         if (!tinyMCE.isMSIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
    2778                 return tinyMCE.settings['base_href'] + url;
    2779 
    2780         // Handle relative URLs
    2781         if (on_save && tinyMCE.getParam('relative_urls')) {
    2782                 var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
    2783                 if (curl.charAt(0) == '/')
    2784                         curl = tinyMCE.settings['document_base_prefix'] + curl;
    2785 
    2786                 var urlParts = tinyMCE.parseURL(curl);
    2787                 var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);
    2788 
    2789                 // Force relative
    2790                 if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))
    2791                         return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);
     4673TinyMCE_Engine.prototype.getAttrib = function(elm, name, default_value) {
     4674        if (typeof(default_value) == "undefined")
     4675                default_value = "";
     4676
     4677        // Not a element
     4678        if (!elm || elm.nodeType != 1)
     4679                return default_value;
     4680
     4681        var v = elm.getAttribute(name);
     4682
     4683        // Try className for class attrib
     4684        if (name == "class" && !v)
     4685                v = elm.className;
     4686
     4687        // Workaround for a issue with Firefox 1.5rc2+
     4688        if (tinyMCE.isGecko && name == "src" && elm.src != null && elm.src != "")
     4689                v = elm.src;
     4690
     4691        // Workaround for a issue with Firefox 1.5rc2+
     4692        if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "")
     4693                v = elm.href;
     4694
     4695        if (name == "http-equiv" && tinyMCE.isMSIE)
     4696                v = elm.httpEquiv;
     4697
     4698        if (name == "style" && !tinyMCE.isOpera)
     4699                v = elm.style.cssText;
     4700
     4701        return (v && v != "") ? v : default_value;
     4702};
     4703
     4704TinyMCE_Engine.prototype.setAttrib = function(element, name, value, fix_value) {
     4705        if (typeof(value) == "number" && value != null)
     4706                value = "" + value;
     4707
     4708        if (fix_value) {
     4709                if (value == null)
     4710                        value = "";
     4711
     4712                var re = new RegExp('[^0-9%]', 'g');
     4713                value = value.replace(re, '');
    27924714        }
    27934715
    2794         // Handle absolute URLs
    2795         if (!tinyMCE.getParam('relative_urls')) {
    2796                 var urlParts = tinyMCE.parseURL(url);
    2797                 var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);
    2798 
    2799                 // Force absolute URLs from relative URLs
    2800                 url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
    2801 
    2802                 // If anchor and path is the same page
    2803                 if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])
    2804                         return "#" + urlParts['anchor'];
     4716        if (name == "style")
     4717                element.style.cssText = value;
     4718
     4719        if (name == "class")
     4720                element.className = value;
     4721
     4722        if (value != null && value != "" && value != -1)
     4723                element.setAttribute(name, value);
     4724        else
     4725                element.removeAttribute(name);
     4726};
     4727
     4728TinyMCE_Engine.prototype.setStyleAttrib = function(elm, name, value) {
     4729        eval('elm.style.' + name + '=value;');
     4730
     4731        // Style attrib deleted
     4732        if (tinyMCE.isMSIE && value == null || value == '') {
     4733                var str = tinyMCE.serializeStyle(tinyMCE.parseStyle(elm.style.cssText));
     4734                elm.style.cssText = str;
     4735                elm.setAttribute("style", str);
    28054736        }
    2806 
    2807         // Remove current domain
    2808         if (tinyMCE.getParam('remove_script_host')) {
    2809                 var start = "", portPart = "";
    2810 
    2811                 if (port != "")
    2812                         portPart = ":" + port;
    2813 
    2814                 start = prot + "//" + host + portPart + "/";
    2815 
    2816                 if (url.indexOf(start) == 0)
    2817                         url = url.substring(start.length-1);
     4737};
     4738
     4739TinyMCE_Engine.prototype.switchClass = function(ei, c) {
     4740        var e;
     4741
     4742        if (tinyMCE.switchClassCache[ei])
     4743                e = tinyMCE.switchClassCache[ei];
     4744        else
     4745                e = tinyMCE.switchClassCache[ei] = document.getElementById(ei);
     4746
     4747        if (e) {
     4748                // Keep tile mode
     4749                if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0)
     4750                        c = 'mceTiledButton ' + c;
     4751
     4752                e.className = c;
    28184753        }
    2819 
    2820         return url;
    28214754};
    28224755
    2823 /**
    2824  * Parses a URL in to its diffrent components.
    2825  */
    2826 TinyMCE.prototype.parseURL = function(url_str) {
     4756TinyMCE_Engine.prototype.getAbsPosition = function(n) {
     4757        var p = {absLeft : 0, absTop : 0};
     4758
     4759        while (n) {
     4760                p.absLeft += n.offsetLeft;
     4761                p.absTop += n.offsetTop;
     4762                n = n.offsetParent;
     4763        }
     4764
     4765        return p;
     4766};
     4767
     4768TinyMCE_Engine.prototype.prevNode = function(e, n) {
     4769        var a = n.split(','), i;
     4770
     4771        while ((e = e.previousSibling) != null) {
     4772                for (i=0; i<a.length; i++) {
     4773                        if (e.nodeName == a[i])
     4774                                return e;
     4775                }
     4776        }
     4777
     4778        return null;
     4779};
     4780
     4781TinyMCE_Engine.prototype.nextNode = function(e, n) {
     4782        var a = n.split(','), i;
     4783
     4784        while ((e = e.nextSibling) != null) {
     4785                for (i=0; i<a.length; i++) {
     4786                        if (e.nodeName == a[i])
     4787                                return e;
     4788                }
     4789        }
     4790
     4791        return null;
     4792};
     4793
     4794/* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */
     4795
     4796TinyMCE_Engine.prototype.parseURL = function(url_str) {
    28274797        var urlParts = new Array();
    28284798
    … …  
    28914861};
    28924862
    2893 TinyMCE.prototype.serializeURL = function(up) {
    2894         var url = "";
     4863TinyMCE_Engine.prototype.serializeURL = function(up) {
     4864        var o = "";
    28954865
    28964866        if (up['protocol'])
    2897                 url += up['protocol'] + "://";
     4867                o += up['protocol'] + "://";
    28984868
    28994869        if (up['host'])
    2900                 url += up['host'];
     4870                o += up['host'];
    29014871
    29024872        if (up['port'])
    2903                 url += ":" + up['port'];
     4873                o += ":" + up['port'];
    29044874
    29054875        if (up['path'])
    2906                 url += up['path'];
     4876                o += up['path'];
    29074877
    29084878        if (up['query'])
    2909                 url += "?" + up['query'];
     4879                o += "?" + up['query'];
    29104880
    29114881        if (up['anchor'])
    2912                 url += "#" + up['anchor'];
    2913 
    2914         return url;
     4882                o += "#" + up['anchor'];
     4883
     4884        return o;
    29154885};
    29164886
    2917 /**
    2918  * Converts an absolute path to relative path.
    2919  */
    2920 TinyMCE.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) {
     4887TinyMCE_Engine.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) {
    29214888        var baseURL = this.parseURL(base_url);
    29224889        var targetURL = this.parseURL(url_to_relative);
    … …  
    29844951                targetURL.path = "";
    29854952
     4953        // If empty and not local anchor force slash
     4954        if (targetURL.path == "" && !targetURL.anchor)
     4955                targetURL.path = "/";
     4956
    29864957        return this.serializeURL(targetURL);
    29874958};
    29884959
    2989 TinyMCE.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) {
    2990         var baseURL = TinyMCE.prototype.parseURL(base_url);
    2991         var relURL = TinyMCE.prototype.parseURL(relative_url);
     4960TinyMCE_Engine.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) {
     4961        var baseURL = this.parseURL(base_url);
     4962        var relURL = this.parseURL(relative_url);
    29924963
    29934964        if (relative_url == "" || relative_url.charAt(0) == '/' || relative_url.indexOf('://') != -1 || relative_url.indexOf('mailto:') != -1 || relative_url.indexOf('javascript:') != -1)
    … …  
    30465017        relURL.path = absPath;
    30475018
    3048         return TinyMCE.prototype.serializeURL(relURL);
     5019        return this.serializeURL(relURL);
    30495020};
    30505021
    3051 TinyMCE.prototype.getParam = function(name, default_value, strip_whitespace, split_chr) {
    3052         var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
    3053 
    3054         // Fix bool values
    3055         if (value == "true" || value == "false")
    3056                 return (value == "true");
    3057 
    3058         if (strip_whitespace)
    3059                 value = tinyMCE.regexpReplace(value, "[ \t\r\n]", "");
    3060 
    3061         if (typeof(split_chr) != "undefined" && split_chr != null) {
    3062                 value = value.split(split_chr);
    3063                 var outArray = new Array();
    3064 
    3065                 for (var i=0; i<value.length; i++) {
    3066                         if (value[i] && value[i] != "")
    3067                                 outArray[outArray.length] = value[i];
    3068                 }
    3069 
    3070                 value = outArray;
     5022TinyMCE_Engine.prototype.convertURL = function(url, node, on_save) {
     5023        var prot = document.location.protocol;
     5024        var host = document.location.hostname;
     5025        var port = document.location.port;
     5026
     5027        // Pass through file protocol
     5028        if (prot == "file:")
     5029                return url;
     5030
     5031        // Something is wrong, remove weirdness
     5032        url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
     5033
     5034        // Mailto link or anchor (Pass through)
     5035        if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#")
     5036                return url;
     5037
     5038        // Fix relative/Mozilla
     5039        if (!tinyMCE.isMSIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
     5040                return tinyMCE.settings['base_href'] + url;
     5041
     5042        // Handle relative URLs
     5043        if (on_save && tinyMCE.getParam('relative_urls')) {
     5044                var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
     5045                if (curl.charAt(0) == '/')
     5046                        curl = tinyMCE.settings['document_base_prefix'] + curl;
     5047
     5048                var urlParts = tinyMCE.parseURL(curl);
     5049                var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);
     5050
     5051                // Force relative
     5052                if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))
     5053                        return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);
    30715054        }
    30725055
    3073         return value;
     5056        // Handle absolute URLs
     5057        if (!tinyMCE.getParam('relative_urls')) {
     5058                var urlParts = tinyMCE.parseURL(url);
     5059                var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);
     5060
     5061                // Force absolute URLs from relative URLs
     5062                url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
     5063
     5064                // If anchor and path is the same page
     5065                if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])
     5066                        return "#" + urlParts['anchor'];
     5067        }
     5068
     5069        // Remove current domain
     5070        if (tinyMCE.getParam('remove_script_host')) {
     5071                var start = "", portPart = "";
     5072
     5073                if (port != "")
     5074                        portPart = ":" + port;
     5075
     5076                start = prot + "//" + host + portPart + "/";
     5077
     5078                if (url.indexOf(start) == 0)
     5079                        url = url.substring(start.length-1);
     5080        }
     5081
     5082        return url;
    30745083};
    30755084
    3076 TinyMCE.prototype.getLang = function(name, default_value, parse_entities) {
    3077         var value = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name];
    3078 
    3079         if (parse_entities)
    3080                 value = tinyMCE.entityDecode(value);
    3081 
    3082         return value;
    3083 };
    3084 
    3085 TinyMCE.prototype.entityDecode = function(s) {
    3086         var e = document.createElement("div");
    3087         e.innerHTML = s;
    3088         return e.innerHTML;
    3089 };
    3090 
    3091 TinyMCE.prototype.addToLang = function(prefix, ar) {
    3092         for (var key in ar) {
    3093                 if (typeof(ar[key]) == 'function')
    3094                         continue;
    3095 
    3096                 tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = ar[key];
     5085TinyMCE_Engine.prototype.convertAllRelativeURLs = function(body) {
     5086        // Convert all image URL:s to absolute URL
     5087        var elms = body.getElementsByTagName("img");
     5088        for (var i=0; i<elms.length; i++) {
     5089                var src = tinyMCE.getAttrib(elms[i], 'src');
     5090
     5091                var msrc = tinyMCE.getAttrib(elms[i], 'mce_src');
     5092                if (msrc != "")
     5093                        src = msrc;
     5094
     5095                if (src != "") {
     5096                        src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src);
     5097                        elms[i].setAttribute("src", src);
     5098                }
    30975099        }
    30985100
    3099 //      for (var key in ar)
    3100 //              tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = "|" + ar[key] + "|";
    3101 };
    3102 
    3103 TinyMCE.prototype.replaceVar = function(replace_haystack, replace_var, replace_str) {
    3104         var re = new RegExp('{\\\$' + replace_var + '}', 'g');
    3105         return replace_haystack.replace(re, replace_str);
    3106 };
    3107 
    3108 TinyMCE.prototype.replaceVars = function(replace_haystack, replace_vars) {
    3109         for (var key in replace_vars) {
    3110                 var value = replace_vars[key];
    3111                 if (typeof(value) == 'function')
    3112                         continue;
    3113 
    3114                 replace_haystack = tinyMCE.replaceVar(replace_haystack, key, value);
    3115         }
    3116 
    3117         return replace_haystack;
    3118 };
    3119 
    3120 TinyMCE.prototype.triggerNodeChange = function(focus, setup_content) {
    3121         if (tinyMCE.settings['handleNodeChangeCallback']) {
    3122                 if (tinyMCE.selectedInstance) {
    3123                         var inst = tinyMCE.selectedInstance;
    3124                         var editorId = inst.editorId;
    3125                         var elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement();
    3126                         var undoIndex = -1;
    3127                         var undoLevels = -1;
    3128                         var anySelection = false;
    3129                         var selectedText = inst.getSelectedText();
    3130 
    3131                         inst.switchSettings();
    3132 
    3133                         if (tinyMCE.settings["auto_resize"]) {
    3134                                 var doc = inst.getDoc();
    3135 
    3136                                 inst.iframeElement.style.width = doc.body.offsetWidth + "px";
    3137                                 inst.iframeElement.style.height = doc.body.offsetHeight + "px";
    3138                         }
    3139 
    3140                         if (tinyMCE.selectedElement)
    3141                                 anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (selectedText && selectedText.length > 0);
    3142 
    3143                         if (tinyMCE.settings['custom_undo_redo']) {
    3144                                 undoIndex = inst.undoIndex;
    3145                                 undoLevels = inst.undoLevels.length;
    3146                         }
    3147 
    3148                         tinyMCE.executeCallback('handleNodeChangeCallback', '_handleNodeChange', 0, editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content);
    3149                 }
    3150         }
    3151 
    3152         if (this.selectedInstance && (typeof(focus) == "undefined" || focus))
    3153                 this.selectedInstance.contentWindow.focus();
    3154 };
    3155 
    3156 TinyMCE.prototype._customCleanup = function(inst, type, content) {
    3157         // Call custom cleanup
    3158         var customCleanup = tinyMCE.settings['cleanup_callback'];
    3159         if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined")
    3160                 content = eval(customCleanup + "(type, content, inst);");
    3161 
    3162         // Trigger plugin cleanups
    3163         var plugins = tinyMCE.getParam('plugins', '', true, ',');
    3164         for (var i=0; i<plugins.length; i++) {
    3165                 if (eval("typeof(TinyMCE_" + plugins[i] +  "_cleanup)") != "undefined")
    3166                         content = eval("TinyMCE_" + plugins[i] +  "_cleanup(type, content, inst);");
    3167         }
    3168 
    3169         return content;
    3170 };
    3171 
    3172 TinyMCE.prototype.getContent = function(editor_id) {
    3173         if (typeof(editor_id) != "undefined")
    3174                 tinyMCE.selectedInstance = tinyMCE.getInstanceById(editor_id);
    3175 
    3176         if (tinyMCE.selectedInstance) {
    3177                 var old = this.selectedInstance.getBody().innerHTML;
    3178                 var html = tinyMCE._cleanupHTML(this.selectedInstance, this.selectedInstance.getDoc(), tinyMCE.settings, this.selectedInstance.getBody(), false, true);
    3179                 tinyMCE.setInnerHTML(this.selectedInstance.getBody(), old);
    3180                 return html;
    3181         }
    3182 
    3183         return null;
    3184 };
    3185 
    3186 TinyMCE.prototype.setContent = function(html_content) {
    3187         if (tinyMCE.selectedInstance) {
    3188                 tinyMCE.selectedInstance.execCommand('mceSetContent', false, html_content);
    3189                 tinyMCE.selectedInstance.repaint();
     5101        // Convert all link URL:s to absolute URL
     5102        var elms = body.getElementsByTagName("a");
     5103        for (var i=0; i<elms.length; i++) {
     5104                var href = tinyMCE.getAttrib(elms[i], 'href');
     5105
     5106                var mhref = tinyMCE.getAttrib(elms[i], 'mce_href');
     5107                if (mhref != "")
     5108                        href = mhref;
     5109
     5110                if (href && href != "") {
     5111                        href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], href);
     5112                        elms[i].setAttribute("href", href);
     5113                }
    31905114        }
    31915115};
    31925116
    3193 TinyMCE.prototype.importThemeLanguagePack = function(name) {
    3194         if (typeof(name) == "undefined")
    3195                 name = tinyMCE.settings['theme'];
    3196 
    3197         tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings['language'] + '.js');
     5117/* file:jscripts/tiny_mce/classes/TinyMCE_Array.class.js */
     5118
     5119TinyMCE_Engine.prototype.clearArray = function(a) {
     5120        for (var k in a)
     5121                a[k] = null;
     5122
     5123        return a;
    31985124};
    31995125
    3200 TinyMCE.prototype.importPluginLanguagePack = function(name, valid_languages) {
    3201         var lang = "en";
    3202 
    3203         valid_languages = valid_languages.split(',');
    3204         for (var i=0; i<valid_languages.length; i++) {
    3205                 if (tinyMCE.settings['language'] == valid_languages[i])
    3206                         lang = tinyMCE.settings['language'];
    3207         }
    3208 
    3209         tinyMCE.loadScript(tinyMCE.baseURL + '/plugins/' + name + '/langs/' + lang +  '.js');
    3210 };
    3211 
    3212 /**
    3213  * Adds themeurl, settings and lang to HTML code.
    3214  */
    3215 TinyMCE.prototype.applyTemplate = function(html, args) {
    3216         html = tinyMCE.replaceVar(html, "themeurl", tinyMCE.themeURL);
    3217 
    3218         if (typeof(args) != "undefined")
    3219                 html = tinyMCE.replaceVars(html, args);
    3220 
    3221         html = tinyMCE.replaceVars(html, tinyMCE.settings);
    3222         html = tinyMCE.replaceVars(html, tinyMCELang);
    3223 
    3224         return html;
    3225 };
    3226 
    3227 TinyMCE.prototype.openWindow = function(template, args) {
    3228         var html, width, height, x, y, resizable, scrollbars, url;
    3229 
    3230         args['mce_template_file'] = template['file'];
    3231         args['mce_width'] = template['width'];
    3232         args['mce_height'] = template['height'];
    3233         tinyMCE.windowArgs = args;
    3234 
    3235         html = template['html'];
    3236         if (!(width = parseInt(template['width'])))
    3237                 width = 320;
    3238 
    3239         if (!(height = parseInt(template['height'])))
    3240                 height = 200;
    3241 
    3242         // Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!!
    3243         if (tinyMCE.isMSIE)
    3244                 height += 40;
    3245         else
    3246                 height += 20;
    3247 
    3248         x = parseInt(screen.width / 2.0) - (width / 2.0);
    3249         y = parseInt(screen.height / 2.0) - (height / 2.0);
    3250 
    3251         resizable = (args && args['resizable']) ? args['resizable'] : "no";
    3252         scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
    3253 
    3254         if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
    3255                 url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
    3256         else
    3257                 url = template['file'];
    3258 
    3259         // Replace all args as variables in URL
    3260         for (var name in args) {
    3261                 if (typeof(args[name]) == 'function')
    3262                         continue;
    3263 
    3264                 url = tinyMCE.replaceVar(url, name, escape(args[name]));
    3265         }
    3266 
    3267         if (html) {
    3268                 html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']);
    3269                 html = tinyMCE.applyTemplate(html, args);
    3270 
    3271                 var win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable);
    3272                 if (win == null) {
    3273                         alert(tinyMCELang['lang_popup_blocked']);
    3274                         return;
    3275                 }
    3276 
    3277                 win.document.write(html);
    3278                 win.document.close();
    3279                 win.resizeTo(width, height);
    3280                 win.focus();
    3281         } else {
    3282                 if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {
    3283             var features = "resizable:" + resizable
    3284                 + ";scroll:"
    3285                 + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:"
    3286                 + width + "px;dialogHeight:" + height + "px;";
    3287 
    3288                         window.showModalDialog(url, window, features);
    3289                 } else {
    3290                         var modal = (resizable == "yes") ? "no" : "yes";
    3291 
    3292                         if (tinyMCE.isGecko && tinyMCE.isMac)
    3293                                 modal = "no";
    3294 
    3295                         if (template['close_previous'] != "no")
    3296                                 try {tinyMCE.lastWindow.close();} catch (ex) {}
    3297 
    3298                         var win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable);
    3299                         if (win == null) {
    3300                                 alert(tinyMCELang['lang_popup_blocked']);
    3301                                 return;
    3302                         }
    3303 
    3304                         if (template['close_previous'] != "no")
    3305                                 tinyMCE.lastWindow = win;
    3306 
    3307                         eval('try { win.resizeTo(width, height); } catch(e) { }');
    3308 
    3309                         // Make it bigger if statusbar is forced
    3310                         if (tinyMCE.isGecko) {
    3311                                 if (win.document.defaultView.statusbar.visible)
    3312                                         win.resizeBy(0, tinyMCE.isMac ? 10 : 24);
    3313                         }
    3314 
    3315                         win.focus();
     5126/* file:jscripts/tiny_mce/classes/TinyMCE_Event.class.js */
     5127
     5128TinyMCE_Engine.prototype._setEventsEnabled = function(node, state) {
     5129        var events = new Array('onfocus','onblur','onclick','ondblclick',
     5130                                'onmousedown','onmouseup','onmouseover','onmousemove',
     5131                                'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup');
     5132
     5133        var evs = tinyMCE.settings['event_elements'].split(',');
     5134        for (var y=0; y<evs.length; y++){
     5135                var elms = node.getElementsByTagName(evs[y]);
     5136                for (var i=0; i<elms.length; i++) {
     5137                        var event = "";
     5138
     5139                        for (var x=0; x<events.length; x++) {
     5140                                if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {
     5141                                        event = tinyMCE.cleanupEventStr("" + event);
     5142
     5143                                        if (!state)
     5144                                                event = "return true;" + event;
     5145                                        else
     5146                                                event = event.replace(/^return true;/gi, '');
     5147
     5148                                        elms[i].removeAttribute(events[x]);
     5149                                        elms[i].setAttribute(events[x], event);
     5150                                }
     5151                        }
    33165152                }
    33175153        }
    33185154};
    33195155
    3320 TinyMCE.prototype.closeWindow = function(win) {
    3321         win.close();
    3322 };
    3323 
    3324 TinyMCE.prototype.getVisualAidClass = function(class_name, state) {
    3325         var aidClass = tinyMCE.settings['visual_table_class'];
    3326 
    3327         if (typeof(state) == "undefined")
    3328                 state = tinyMCE.settings['visual'];
    3329 
    3330         // Split
    3331         var classNames = new Array();
    3332         var ar = class_name.split(' ');
    3333         for (var i=0; i<ar.length; i++) {
    3334                 if (ar[i] == aidClass)
    3335                         ar[i] = "";
    3336 
    3337                 if (ar[i] != "")
    3338                         classNames[classNames.length] = ar[i];
    3339         }
    3340 
    3341         if (state)
    3342                 classNames[classNames.length] = aidClass;
    3343 
    3344         // Glue
    3345         var className = "";
    3346         for (var i=0; i<classNames.length; i++) {
    3347                 if (i > 0)
    3348                         className += " ";
    3349 
    3350                 className += classNames[i];
    3351         }
    3352 
    3353         return className;
    3354 };
    3355 
    3356 TinyMCE.prototype.handleVisualAid = function(el, deep, state, inst) {
    3357         if (!el)
    3358                 return;
    3359 
    3360         var tableElement = null;
    3361 
    3362         switch (el.nodeName) {
    3363                 case "TABLE":
    3364                         var oldW = el.style.width;
    3365                         var oldH = el.style.height;
    3366                         var bo = tinyMCE.getAttrib(el, "border");
    3367 
    3368                         bo = bo == "" || bo == "0" ? true : false;
    3369 
    3370                         tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo));
    3371 
    3372                         el.style.width = oldW;
    3373                         el.style.height = oldH;
    3374 
    3375                         for (var y=0; y<el.rows.length; y++) {
    3376                                 for (var x=0; x<el.rows[y].cells.length; x++) {
    3377                                         var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);
    3378                                         tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn);
    3379                                 }
    3380                         }
    3381 
    3382                         break;
    3383 
    3384                 case "A":
    3385                         var anchorName = tinyMCE.getAttrib(el, "name");
    3386 
    3387                         if (anchorName != '' && state) {
    3388                                 el.title = anchorName;
    3389                                 el.className = 'mceItemAnchor';
    3390                         } else if (anchorName != '' && !state)
    3391                                 el.className = '';
    3392 
    3393                         break;
    3394         }
    3395 
    3396         if (deep && el.hasChildNodes()) {
    3397                 for (var i=0; i<el.childNodes.length; i++)
    3398                         tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst);
     5156TinyMCE_Engine.prototype._eventPatch = function(editor_id) {
     5157        var n, inst, win, e;
     5158
     5159        // Remove odd, error
     5160        if (typeof(tinyMCE) == "undefined")
     5161                return true;
     5162
     5163        try {
     5164                // Try selected instance first
     5165                if (tinyMCE.selectedInstance) {
     5166                        win = tinyMCE.selectedInstance.getWin();
     5167
     5168                        if (win && win.event) {
     5169                                e = win.event;
     5170
     5171                                if (!e.target)
     5172                                        e.target = e.srcElement;
     5173
     5174                                TinyMCE_Engine.prototype.handleEvent(e);
     5175                                return;
     5176                        }
     5177                }
     5178
     5179                // Search for it
     5180                for (n in tinyMCE.instances) {
     5181                        inst = tinyMCE.instances[n];
     5182
     5183                        if (!tinyMCE.isInstance(inst))
     5184                                continue;
     5185
     5186                        tinyMCE.selectedInstance = inst;
     5187                        win = inst.getWin();
     5188
     5189                        if (win && win.event) {
     5190                                e = win.event;
     5191
     5192                                if (!e.target)
     5193                                        e.target = e.srcElement;
     5194
     5195                                TinyMCE_Engine.prototype.handleEvent(e);
     5196                                return;
     5197                        }
     5198                }
     5199        } catch (ex) {
     5200                // Ignore error if iframe is pointing to external URL
    33995201        }
    34005202};
    34015203
    3402 TinyMCE.prototype.getAttrib = function(elm, name, default_value) {
    3403         if (typeof(default_value) == "undefined")
    3404                 default_value = "";
    3405 
    3406         // Not a element
    3407         if (!elm || elm.nodeType != 1)
    3408                 return default_value;
    3409 
    3410         var v = elm.getAttribute(name);
    3411 
    3412         // Try className for class attrib
    3413         if (name == "class" && !v)
    3414                 v = elm.className;
    3415 
    3416         // Workaround for a issue with Firefox 1.5rc2+
    3417         if (tinyMCE.isGecko && name == "src" && elm.src != null && elm.src != "")
    3418                 v = elm.src;
    3419 
    3420         // Workaround for a issue with Firefox 1.5rc2+
    3421         if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "")
    3422                 v = elm.href;
    3423 
    3424         if (name == "style" && !tinyMCE.isOpera)
    3425                 v = elm.style.cssText;
    3426 
    3427         return (v && v != "") ? v : default_value;
     5204TinyMCE_Engine.prototype.unloadHandler = function() {
     5205        tinyMCE.triggerSave(true, true);
    34285206};
    34295207
    3430 TinyMCE.prototype.setAttrib = function(element, name, value, fix_value) {
    3431         if (typeof(value) == "number" && value != null)
    3432                 value = "" + value;
    3433 
    3434         if (fix_value) {
    3435                 if (value == null)
    3436                         value = "";
    3437 
    3438                 var re = new RegExp('[^0-9%]', 'g');
    3439                 value = value.replace(re, '');
    3440         }
    3441 
    3442         if (name == "style")
    3443                 element.style.cssText = value;
    3444 
    3445         if (name == "class")
    3446                 element.className = value;
    3447 
    3448         if (value != null && value != "" && value != -1)
    3449                 element.setAttribute(name, value);
    3450         else
    3451                 element.removeAttribute(name);
    3452 };
    3453 
    3454 TinyMCE.prototype.setStyleAttrib = function(elm, name, value) {
    3455         eval('elm.style.' + name + '=value;');
    3456 
    3457         // Style attrib deleted
    3458         if (tinyMCE.isMSIE && value == null || value == '') {
    3459                 var str = tinyMCE.serializeStyle(tinyMCE.parseStyle(elm.style.cssText));
    3460                 elm.style.cssText = str;
    3461                 elm.setAttribute("style", str);
     5208TinyMCE_Engine.prototype.addEventHandlers = function(inst) {
     5209        var doc = inst.getDoc();
     5210
     5211        inst.switchSettings();
     5212
     5213        if (tinyMCE.isMSIE) {
     5214                tinyMCE.addEvent(doc, "keypress", TinyMCE_Engine.prototype._eventPatch);
     5215                tinyMCE.addEvent(doc, "keyup", TinyMCE_Engine.prototype._eventPatch);
     5216                tinyMCE.addEvent(doc, "keydown", TinyMCE_Engine.prototype._eventPatch);
     5217                tinyMCE.addEvent(doc, "mouseup", TinyMCE_Engine.prototype._eventPatch);
     5218                tinyMCE.addEvent(doc, "click", TinyMCE_Engine.prototype._eventPatch);
     5219        } else {
     5220                tinyMCE.addEvent(doc, "keypress", tinyMCE.handleEvent);
     5221                tinyMCE.addEvent(doc, "keydown", tinyMCE.handleEvent);
     5222                tinyMCE.addEvent(doc, "keyup", tinyMCE.handleEvent);
     5223                tinyMCE.addEvent(doc, "click", tinyMCE.handleEvent);
     5224                tinyMCE.addEvent(doc, "mouseup", tinyMCE.handleEvent);
     5225                tinyMCE.addEvent(doc, "mousedown", tinyMCE.handleEvent);
     5226                tinyMCE.addEvent(doc, "focus", tinyMCE.handleEvent);
     5227                tinyMCE.addEvent(doc, "blur", tinyMCE.handleEvent);
     5228
     5229                eval('try { doc.designMode = "On"; } catch(e) {}'); // Force designmode
    34625230        }
    34635231};
    34645232
    3465 TinyMCE.prototype.convertSpansToFonts = function(doc) {
    3466         var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
    3467 
    3468         var h = doc.body.innerHTML;
    3469         h = h.replace(/<span/gi, '<font');
    3470         h = h.replace(/<\/span/gi, '</font');
    3471         doc.body.innerHTML = h;
    3472 
    3473         var s = doc.getElementsByTagName("font");
    3474         for (var i=0; i<s.length; i++) {
    3475                 var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();
    3476                 var fSize = 0;
    3477 
    3478                 for (var x=0; x<sizes.length; x++) {
    3479                         if (sizes[x] == size) {
    3480                                 fSize = x + 1;
    3481                                 break;
    3482                         }
    3483                 }
    3484 
    3485                 if (fSize > 0) {
    3486                         tinyMCE.setAttrib(s[i], 'size', fSize);
    3487                         s[i].style.fontSize = '';
    3488                 }
    3489 
    3490                 var fFace = s[i].style.fontFamily;
    3491                 if (fFace != null && fFace != "") {
    3492                         tinyMCE.setAttrib(s[i], 'face', fFace);
    3493                         s[i].style.fontFamily = '';
    3494                 }
    3495 
    3496                 var fColor = s[i].style.color;
    3497                 if (fColor != null && fColor != "") {
    3498                         tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));
    3499                         s[i].style.color = '';
    3500                 }
     5233TinyMCE_Engine.prototype.onMouseMove = function() {
     5234        var inst;
     5235
     5236        if (!tinyMCE.hasMouseMoved) {
     5237                inst = tinyMCE.selectedInstance;
     5238
     5239                // Workaround for bug #1437457 (Odd MSIE bug)
     5240                if (inst.isFocused) {
     5241                        inst.undoBookmark = inst.selection.getBookmark();
     5242                        tinyMCE.hasMouseMoved = true;
     5243                }
     5244        }
     5245
     5246//      tinyMCE.cancelEvent(inst.getWin().event);
     5247//      return false;
     5248};
     5249
     5250TinyMCE_Engine.prototype.cancelEvent = function(e) {
     5251        if (tinyMCE.isMSIE) {
     5252                e.returnValue = false;
     5253                e.cancelBubble = true;
     5254        } else
     5255                e.preventDefault();
     5256};
     5257
     5258TinyMCE_Engine.prototype.addEvent = function(o, n, h) {
     5259        if (o.attachEvent)
     5260                o.attachEvent("on" + n, h);
     5261        else
     5262                o.addEventListener(n, h, false);
     5263};
     5264
     5265TinyMCE_Engine.prototype.addSelectAccessibility = function(e, s, w) {
     5266        // Add event handlers
     5267        if (!s._isAccessible) {
     5268                s.onkeydown = tinyMCE.accessibleEventHandler;
     5269                s.onblur = tinyMCE.accessibleEventHandler;
     5270                s._isAccessible = true;
     5271                s._win = w;
     5272        }
     5273
     5274        return false;
     5275};
     5276
     5277TinyMCE_Engine.prototype.accessibleEventHandler = function(e) {
     5278        var win = this._win;
     5279        e = tinyMCE.isMSIE ? win.event : e;
     5280        var elm = tinyMCE.isMSIE ? e.srcElement : e.target;
     5281
     5282        // Unpiggyback onchange on blur
     5283        if (e.type == "blur") {
     5284                if (elm.oldonchange) {
     5285                        elm.onchange = elm.oldonchange;
     5286                        elm.oldonchange = null;
     5287                }
     5288
     5289                return true;
     5290        }
     5291
     5292        // Piggyback onchange
     5293        if (elm.nodeName == "SELECT" && !elm.oldonchange) {
     5294                elm.oldonchange = elm.onchange;
     5295                elm.onchange = null;
     5296        }
     5297
     5298        // Execute onchange and remove piggyback
     5299        if (e.keyCode == 13 || e.keyCode == 32) {
     5300                elm.onchange = elm.oldonchange;
     5301                elm.onchange();
     5302                elm.oldonchange = null;
     5303
     5304                tinyMCE.cancelEvent(e);
     5305                return false;
     5306        }
     5307
     5308        return true;
     5309};
     5310
     5311/* file:jscripts/tiny_mce/classes/TinyMCE_Selection.class.js */
     5312
     5313function TinyMCE_Selection(inst) {
     5314        this.instance = inst;
     5315};
     5316
     5317TinyMCE_Selection.prototype = {
     5318        getSelectedHTML : function() {
     5319                var inst = this.instance;
     5320                var e, r = this.getRng(), h;
     5321
     5322                if (tinyMCE.isSafari) {
     5323                        // Not realy perfect!!
     5324                        return r.toString();
     5325                }
     5326
     5327                e = document.createElement("body");
     5328
     5329                if (tinyMCE.isGecko)
     5330                        e.appendChild(r.cloneContents());
     5331                else
     5332                        e.innerHTML = r.htmlText;
     5333
     5334                h = tinyMCE._cleanupHTML(inst, inst.contentDocument, inst.settings, e, e, false, true, false);
     5335
     5336                // When editing always use fonts internaly
     5337                if (tinyMCE.getParam("convert_fonts_to_spans"))
     5338                        tinyMCE.convertSpansToFonts(inst.getDoc());
     5339
     5340                return h;
     5341        },
     5342
     5343        getSelectedText : function() {
     5344                var inst = this.instance;
     5345                var d, r, s, t;
     5346
     5347                if (tinyMCE.isMSIE) {
     5348                        d = inst.getDoc();
     5349
     5350                        if (d.selection.type == "Text") {
     5351                                r = d.selection.createRange();
     5352                                t = r.text;
     5353                        } else
     5354                                t = '';
     5355                } else {
     5356                        s = this.getSel();
     5357
     5358                        if (s && s.toString)
     5359                                t = s.toString();
     5360                        else
     5361                                t = '';
     5362                }
     5363
     5364                return t;
     5365        },
     5366
     5367        getBookmark : function(simple) {
     5368                var rng = this.getRng();
     5369                var doc = this.instance.getDoc();
     5370                var sp, le, s, e, nl, i, si, ei;
     5371                var trng, sx, sy, xx = -999999999;
     5372
     5373                // Skip Opera for now
     5374                if (tinyMCE.isOpera)
     5375                        return null;
     5376
     5377                sx = doc.body.scrollLeft + doc.documentElement.scrollLeft;
     5378                sy = doc.body.scrollTop + doc.documentElement.scrollTop;
     5379
     5380                if (tinyMCE.isSafari || tinyMCE.isGecko)
     5381                        return {rng : rng, scrollX : sx, scrollY : sy};
     5382
     5383                if (tinyMCE.isMSIE) {
     5384                        if (simple)
     5385                                return {rng : rng};
     5386
     5387                        if (rng.item) {
     5388                                e = rng.item(0);
     5389
     5390                                nl = doc.getElementsByTagName(e.nodeName);
     5391                                for (i=0; i<nl.length; i++) {
     5392                                        if (e == nl[i]) {
     5393                                                sp = i;
     5394                                                break;
     5395                                        }
     5396                                }
     5397
     5398                                return {
     5399                                        tag : e.nodeName,
     5400                                        index : sp,
     5401                                        scrollX : sx,
     5402                                        scrollY : sy
     5403                                };
     5404                        } else {
     5405                                trng = rng.duplicate();
     5406                                trng.collapse(true);
     5407                                sp = Math.abs(trng.move('character', xx));
     5408
     5409                                trng = rng.duplicate();
     5410                                trng.collapse(false);
     5411                                le = Math.abs(trng.move('character', xx)) - sp;
     5412
     5413                                return {
     5414                                        start : sp,
     5415                                        length : le,
     5416                                        scrollX : sx,
     5417                                        scrollY : sy
     5418                                };
     5419                        }
     5420                }
     5421
     5422                if (tinyMCE.isGecko) {
     5423                        s = tinyMCE.getParentElement(rng.startContainer);
     5424                        for (si=0; si<s.childNodes.length && s.childNodes[si] != rng.startContainer; si++) ;
     5425
     5426                        nl = doc.getElementsByTagName(s.nodeName);
     5427                        for (i=0; i<nl.length; i++) {
     5428                                        if (s == nl[i]) {
     5429                                                sp = i;
     5430                                                break;
     5431                                        }
     5432                        }
     5433
     5434                        e = tinyMCE.getParentElement(rng.endContainer);
     5435                        for (ei=0; ei<e.childNodes.length && e.childNodes[ei] != rng.endContainer; ei++) ;
     5436
     5437                        nl = doc.getElementsByTagName(e.nodeName);
     5438                        for (i=0; i<nl.length; i++) {
     5439                                        if (e == nl[i]) {
     5440                                                le = i;
     5441                                                break;
     5442                                        }
     5443                        }
     5444
     5445                        //tinyMCE.debug(s.nodeName, sp, rng.startOffset, '-' , e.nodeName, le, rng.endOffset);
     5446                        //tinyMCE.debug(sx, sy);
     5447
     5448                        return {
     5449                                startTag : s.nodeName,
     5450                                start : sp,
     5451                                startIndex : si,
     5452                                endTag : e.nodeName,
     5453                                end : le,
     5454                                endIndex : ei,
     5455                                startOffset : rng.startOffset,
     5456                                endOffset : rng.endOffset,
     5457                                scrollX : sx,
     5458                                scrollY : sy
     5459                        };
     5460                }
     5461
     5462                return null;
     5463        },
     5464
     5465        moveToBookmark : function(bookmark) {
     5466                var rng, nl, i;
     5467                var inst = this.instance;
     5468                var doc = inst.getDoc();
     5469                var win = inst.getWin();
     5470                var sel = this.getSel();
     5471
     5472                if (!bookmark)
     5473                        return false;
     5474
     5475                if (tinyMCE.isSafari) {
     5476                        sel.setBaseAndExtent(bookmark.startContainer, bookmark.startOffset, bookmark.endContainer, bookmark.endOffset);
     5477                        return true;
     5478                }
     5479
     5480                if (tinyMCE.isMSIE) {
     5481                        if (bookmark.rng) {
     5482                                bookmark.rng.select();
     5483                                return true;
     5484                        }
     5485
     5486                        win.focus();
     5487
     5488                        if (bookmark.tag) {
     5489                                rng = inst.getBody().createControlRange();
     5490
     5491                                nl = doc.getElementsByTagName(bookmark.tag);
     5492
     5493                                if (nl.length > bookmark.index)
     5494                                        rng.addElement(nl[bookmark.index]);
     5495                        } else {
     5496                                rng = inst.getSel().createRange();
     5497                                rng.moveToElementText(inst.getBody());
     5498                                rng.collapse(true);
     5499                                rng.moveStart('character', bookmark.start);
     5500                                rng.moveEnd('character', bookmark.length);
     5501                        }
     5502
     5503                        rng.select();
     5504
     5505                        win.scrollTo(bookmark.scrollX, bookmark.scrollY);
     5506                        return true;
     5507                }
     5508
     5509                if (tinyMCE.isGecko && bookmark.rng) {
     5510                        sel.removeAllRanges();
     5511                        sel.addRange(bookmark.rng);
     5512                        win.scrollTo(bookmark.scrollX, bookmark.scrollY);
     5513                        return true;
     5514                }
     5515
     5516                if (tinyMCE.isGecko) {
     5517        //              try {
     5518                                rng = doc.createRange();
     5519
     5520                                nl = doc.getElementsByTagName(bookmark.startTag);
     5521                                if (nl.length > bookmark.start)
     5522                                        rng.setStart(nl[bookmark.start].childNodes[bookmark.startIndex], bookmark.startOffset);
     5523
     5524                                nl = doc.getElementsByTagName(bookmark.endTag);
     5525                                if (nl.length > bookmark.end)
     5526                                        rng.setEnd(nl[bookmark.end].childNodes[bookmark.endIndex], bookmark.endOffset);
     5527
     5528                                sel.removeAllRanges();
     5529                                sel.addRange(rng);
     5530        /*              } catch {
     5531                                // Ignore
     5532                        }*/
     5533
     5534                        win.scrollTo(bookmark.scrollX, bookmark.scrollY);
     5535                        return true;
     5536                }
     5537
     5538                return false;
     5539        },
     5540
     5541        selectNode : function(node, collapse, select_text_node, to_start) {
     5542                var inst = this.instance, sel, rng, nodes;
     5543
     5544                if (!node)
     5545                        return;
     5546
     5547                if (typeof(collapse) == "undefined")
     5548                        collapse = true;
     5549
     5550                if (typeof(select_text_node) == "undefined")
     5551                        select_text_node = false;
     5552
     5553                if (typeof(to_start) == "undefined")
     5554                        to_start = true;
     5555
     5556                if (tinyMCE.isMSIE) {
     5557                        rng = inst.getBody().createTextRange();
     5558
     5559                        try {
     5560                                rng.moveToElementText(node);
     5561
     5562                                if (collapse)
     5563                                        rng.collapse(to_start);
     5564
     5565                                rng.select();
     5566                        } catch (e) {
     5567                                // Throws illigal agrument in MSIE some times
     5568                        }
     5569                } else {
     5570                        sel = this.getSel();
     5571
     5572                        if (!sel)
     5573                                return;
     5574
     5575                        if (tinyMCE.isSafari) {
     5576                                sel.setBaseAndExtent(node, 0, node, node.innerText.length);
     5577
     5578                                if (collapse) {
     5579                                        if (to_start)
     5580                                                sel.collapseToStart();
     5581                                        else
     5582                                                sel.collapseToEnd();
     5583                                }
     5584
     5585                                this.scrollToNode(node);
     5586
     5587                                return;
     5588                        }
     5589
     5590                        rng = inst.getDoc().createRange();
     5591
     5592                        if (select_text_node) {
     5593                                // Find first textnode in tree
     5594                                nodes = tinyMCE.getNodeTree(node, new Array(), 3);
     5595                                if (nodes.length > 0)
     5596                                        rng.selectNodeContents(nodes[0]);
     5597                                else
     5598                                        rng.selectNodeContents(node);
     5599                        } else
     5600                                rng.selectNode(node);
     5601
     5602                        if (collapse) {
     5603                                // Special treatment of textnode collapse
     5604                                if (!to_start && node.nodeType == 3) {
     5605                                        rng.setStart(node, node.nodeValue.length);
     5606                                        rng.setEnd(node, node.nodeValue.length);
     5607                                } else
     5608                                        rng.collapse(to_start);
     5609                        }
     5610
     5611                        sel.removeAllRanges();
     5612                        sel.addRange(rng);
     5613                }
     5614
     5615                this.scrollToNode(node);
     5616
     5617                // Set selected element
     5618                tinyMCE.selectedElement = null;
     5619                if (node.nodeType == 1)
     5620                        tinyMCE.selectedElement = node;
     5621        },
     5622
     5623        scrollToNode : function(node) {
     5624                var inst = this.instance;
     5625                var pos, doc, scrollX, scrollY, height;
     5626
     5627                // Scroll to node position
     5628                pos = tinyMCE.getAbsPosition(node);
     5629                doc = inst.getDoc();
     5630                scrollX = doc.body.scrollLeft + doc.documentElement.scrollLeft;
     5631                scrollY = doc.body.scrollTop + doc.documentElement.scrollTop;
     5632                height = tinyMCE.isMSIE ? document.getElementById(inst.editorId).style.pixelHeight : inst.targetElement.clientHeight;
     5633
     5634                // Only scroll if out of visible area
     5635                if (!tinyMCE.settings['auto_resize'] && !(pos.absTop > scrollY && pos.absTop < (scrollY - 25 + height)))
     5636                        inst.contentWindow.scrollTo(pos.absLeft, pos.absTop - height + 25);
     5637        },
     5638
     5639        getSel : function() {
     5640                var inst = this.instance;
     5641
     5642                if (tinyMCE.isMSIE && !tinyMCE.isOpera)
     5643                        return inst.getDoc().selection;
     5644
     5645                return inst.contentWindow.getSelection();
     5646        },
     5647
     5648        getRng : function() {
     5649                var inst = this.instance;
     5650                var sel = this.getSel();
     5651
     5652                if (sel == null)
     5653                        return null;
     5654
     5655                if (tinyMCE.isMSIE && !tinyMCE.isOpera)
     5656                        return sel.createRange();
     5657
     5658                if (tinyMCE.isSafari && !sel.getRangeAt)
     5659                        return '' + window.getSelection();
     5660
     5661                return sel.getRangeAt(0);
     5662        },
     5663
     5664        getFocusElement : function() {
     5665                var inst = this.instance;
     5666
     5667                if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
     5668                        var doc = inst.getDoc();
     5669                        var rng = doc.selection.createRange();
     5670
     5671        //              if (rng.collapse)
     5672        //                      rng.collapse(true);
     5673
     5674                        var elm = rng.item ? rng.item(0) : rng.parentElement();
     5675                } else {
     5676                        if (inst.isHidden())
     5677                                return inst.getBody();
     5678
     5679                        var sel = this.getSel();
     5680                        var rng = this.getRng();
     5681
     5682                        if (!sel || !rng)
     5683                                return null;
     5684
     5685                        var elm = rng.commonAncestorContainer;
     5686                        //var elm = (sel && sel.anchorNode) ? sel.anchorNode : null;
     5687
     5688                        // Handle selection a image or other control like element such as anchors
     5689                        if (!rng.collapsed) {
     5690                                // Is selection small
     5691                                if (rng.startContainer == rng.endContainer) {
     5692                                        if (rng.startOffset - rng.endOffset < 2) {
     5693                                                if (rng.startContainer.hasChildNodes())
     5694                                                        elm = rng.startContainer.childNodes[rng.startOffset];
     5695                                        }
     5696                                }
     5697                        }
     5698
     5699                        // Get the element parent of the node
     5700                        elm = tinyMCE.getParentElement(elm);
     5701
     5702                        //if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img")
     5703                        //      elm = tinyMCE.selectedElement;
     5704                }
     5705
     5706                return elm;
    35015707        }
    35025708};
    35035709
    3504 TinyMCE.prototype.convertFontsToSpans = function(doc) {
    3505         var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
    3506 
    3507         var h = doc.body.innerHTML;
    3508         h = h.replace(/<font/gi, '<span');
    3509         h = h.replace(/<\/font/gi, '</span');
    3510         doc.body.innerHTML = h;
    3511 
    3512         var fsClasses = tinyMCE.getParam('font_size_classes');
    3513         if (fsClasses != '')
    3514                 fsClasses = fsClasses.replace(/\s+/, '').split(',');
    3515         else
    3516                 fsClasses = null;
    3517 
    3518         var s = doc.getElementsByTagName("span");
    3519         for (var i=0; i<s.length; i++) {
    3520                 var fSize, fFace, fColor;
    3521 
    3522                 fSize = tinyMCE.getAttrib(s[i], 'size');
    3523                 fFace = tinyMCE.getAttrib(s[i], 'face');
    3524                 fColor = tinyMCE.getAttrib(s[i], 'color');
    3525 
    3526                 if (fSize != "") {
    3527                         fSize = parseInt(fSize);
    3528 
    3529                         if (fSize > 0 && fSize < 8) {
    3530                                 if (fsClasses != null)
    3531                                         tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);
    3532                                 else
    3533                                         s[i].style.fontSize = sizes[fSize-1];
    3534                         }
    3535 
    3536                         s[i].removeAttribute('size');
    3537                 }
    3538 
    3539                 if (fFace != "") {
    3540                         s[i].style.fontFamily = fFace;
    3541                         s[i].removeAttribute('face');
    3542                 }
    3543 
    3544                 if (fColor != "") {
    3545                         s[i].style.color = fColor;
    3546                         s[i].removeAttribute('color');
    3547                 }
    3548         }
    3549 };
    3550 
    3551 /*
    3552 TinyMCE.prototype.applyClassesToFonts = function(doc, size) {
    3553         var f = doc.getElementsByTagName("font");
    3554         for (var i=0; i<f.length; i++) {
    3555                 var s = tinyMCE.getAttrib(f[i], "size");
    3556 
    3557                 if (s != "")
    3558                         tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s);
    3559         }
    3560 
    3561         if (typeof(size) != "undefined") {
    3562                 var css = "";
    3563 
    3564                 for (var x=0; x<doc.styleSheets.length; x++) {
    3565                         for (var i=0; i<doc.styleSheets[x].rules.length; i++) {
    3566                                 if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) {
    3567                                         css = doc.styleSheets[x].rules[i].style.cssText;
    3568                                         break;
    3569                                 }
    3570                         }
    3571 
    3572                         if (css != "")
    3573                                 break;
    3574                 }
    3575 
    3576                 if (doc.styleSheets[0].rules[0].selectorText == "FONT")
    3577                         doc.styleSheets[0].removeRule(0);
    3578 
    3579                 doc.styleSheets[0].addRule("FONT", css, 0);
    3580         }
    3581 };
    3582 */
    3583 
    3584 TinyMCE.prototype.setInnerHTML = function(e, h) {
    3585         if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
    3586                 e.innerHTML = tinyMCE.uniqueTag + h;
    3587                 e.firstChild.removeNode(true);
    3588         } else {
    3589                 h = this.fixGeckoBaseHREFBug(1, e, h);
    3590                 e.innerHTML = h;
    3591                 this.fixGeckoBaseHREFBug(2, e, h);
    3592         }
    3593 };
    3594 
    3595 TinyMCE.prototype.fixGeckoBaseHREFBug = function(m, e, h) {
    3596         if (tinyMCE.isGecko) {
    3597                 if (m == 1) {
    3598                         h = h.replace(/\ssrc=/gi, " xsrc=");
    3599                         h = h.replace(/\shref=/gi, " xhref=");
    3600 
    3601                         return h;
    3602                 } else {
    3603                         if (h.indexOf(' xsrc') != -1) {
    3604                                 var n = e.getElementsByTagName("img");
    3605                                 for (var i=0; i<n.length; i++) {
    3606                                         var xsrc = tinyMCE.getAttrib(n[i], "xsrc");
    3607 
    3608                                         if (xsrc != "") {
    3609                                                 n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
    3610                                                 n[i].removeAttribute("xsrc");
    3611                                         }
    3612                                 }
    3613 
    3614                                 // Select image form fields
    3615                                 var n = e.getElementsByTagName("select");
    3616                                 for (var i=0; i<n.length; i++) {
    3617                                         var xsrc = tinyMCE.getAttrib(n[i], "xsrc");
    3618 
    3619                                         if (xsrc != "") {
    3620                                                 n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
    3621                                                 n[i].removeAttribute("xsrc");
    3622                                         }
    3623                                 }
    3624 
    3625                                 // iframes
    3626                                 var n = e.getElementsByTagName("iframe");
    3627                                 for (var i=0; i<n.length; i++) {
    3628                                         var xsrc = tinyMCE.getAttrib(n[i], "xsrc");
    3629 
    3630                                         if (xsrc != "") {
    3631                                                 n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
    3632                                                 n[i].removeAttribute("xsrc");
    3633                                         }
    3634                                 }
    3635                         }
    3636 
    3637                         if (h.indexOf(' xhref') != -1) {
    3638                                 var n = e.getElementsByTagName("a");
    3639                                 for (var i=0; i<n.length; i++) {
    3640                                         var xhref = tinyMCE.getAttrib(n[i], "xhref");
    3641 
    3642                                         if (xhref != "") {
    3643                                                 n[i].href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref);
    3644                                                 n[i].removeAttribute("xhref");
    3645                                         }
    3646                                 }
    3647                         }
    3648                 }
    3649         }
    3650 
    3651         return h;
    3652 };
    3653 
    3654 TinyMCE.prototype.getOuterHTML = function(e) {
    3655         if (tinyMCE.isMSIE)
    3656                 return e.outerHTML;
    3657 
    3658         var d = e.ownerDocument.createElement("body");
    3659         d.appendChild(e);
    3660         return d.innerHTML;
    3661 };
    3662 
    3663 TinyMCE.prototype.setOuterHTML = function(doc, e, h) {
    3664         if (tinyMCE.isMSIE) {
    3665                 e.outerHTML = h;
    3666                 return;
    3667         }
    3668 
    3669         var d = e.ownerDocument.createElement("body");
    3670         d.innerHTML = h;
    3671         e.parentNode.replaceChild(d.firstChild, e);
    3672 };
    3673 
    3674 TinyMCE.prototype.insertAfter = function(nc, rc){
    3675         if (rc.nextSibling)
    3676                 rc.parentNode.insertBefore(nc, rc.nextSibling);
    3677         else
    3678                 rc.parentNode.appendChild(nc);
    3679 };
    3680 
    3681 TinyMCE.prototype.cleanupAnchors = function(doc) {
    3682         var an = doc.getElementsByTagName("a");
    3683 
    3684         for (var i=0; i<an.length; i++) {
    3685                 if (tinyMCE.getAttrib(an[i], "name") != "") {
    3686                         var cn = an[i].childNodes;
    3687                         for (var x=cn.length-1; x>=0; x--)
    3688                                 tinyMCE.insertAfter(cn[x], an[i]);
    3689                 }
    3690         }
    3691 };
    3692 
    3693 TinyMCE.prototype._setHTML = function(doc, html_content) {
    3694         // Force closed anchors open
    3695         //html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
    3696 
    3697         html_content = tinyMCE.cleanupHTMLCode(html_content);
    3698 
    3699         // Try innerHTML if it fails use pasteHTML in MSIE
    3700         try {
    3701                 tinyMCE.setInnerHTML(doc.body, html_content);
    3702         } catch (e) {
    3703                 if (this.isMSIE)
    3704                         doc.body.createTextRange().pasteHTML(html_content);
    3705         }
    3706 
    3707         // Content duplication bug fix
    3708         if (tinyMCE.isMSIE && tinyMCE.settings['fix_content_duplication']) {
    3709                 // Remove P elements in P elements
    3710                 var paras = doc.getElementsByTagName("P");
    3711                 for (var i=0; i<paras.length; i++) {
    3712                         var node = paras[i];
    3713                         while ((node = node.parentNode) != null) {
    3714                                 if (node.nodeName == "P")
    3715                                         node.outerHTML = node.innerHTML;
    3716                         }
    3717                 }
    3718 
    3719                 // Content duplication bug fix (Seems to be word crap)
    3720                 var html = doc.body.innerHTML;
    3721 
    3722                 if (html.indexOf('="mso') != -1) {
    3723                         for (var i=0; i<doc.body.all.length; i++) {
    3724                                 var el = doc.body.all[i];
    3725                                 el.removeAttribute("className","",0);
    3726                                 el.removeAttribute("style","",0);
    3727                         }
    3728 
    3729                         html = doc.body.innerHTML;
    3730                         html = tinyMCE.regexpReplace(html, "<o:p><\/o:p>", "<br />");
    3731                         html = tinyMCE.regexpReplace(html, "<o:p>&nbsp;<\/o:p>", "");
    3732                         html = tinyMCE.regexpReplace(html, "<st1:.*?>", "");
    3733                         html = tinyMCE.regexpReplace(html, "<p><\/p>", "");
    3734                         html = tinyMCE.regexpReplace(html, "<p><\/p>\r\n<p><\/p>", "");
    3735                         html = tinyMCE.regexpReplace(html, "<p>&nbsp;<\/p>", "<br />");
    3736                         html = tinyMCE.regexpReplace(html, "<p>\s*(<p>\s*)?", "<p>");
    3737                         html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "</p>");
    3738                 }
    3739 
    3740                 // Always set the htmlText output
    3741                 tinyMCE.setInnerHTML(doc.body, html);
    3742         }
    3743 
    3744         tinyMCE.cleanupAnchors(doc);
    3745 
    3746         if (tinyMCE.getParam("convert_fonts_to_spans"))
    3747                 tinyMCE.convertSpansToFonts(doc);
    3748 };
    3749 
    3750 TinyMCE.prototype.getImageSrc = function(str) {
    3751         var pos = -1;
    3752 
    3753         if (!str)
    3754                 return "";
    3755 
    3756         if ((pos = str.indexOf('this.src=')) != -1) {
    3757                 var src = str.substring(pos + 10);
    3758 
    3759                 src = src.substring(0, src.indexOf('\''));
    3760 
    3761                 return src;
    3762         }
    3763 
    3764         return "";
    3765 };
    3766 
    3767 TinyMCE.prototype._getElementById = function(element_id) {
    3768         var elm = document.getElementById(element_id);
    3769         if (!elm) {
    3770                 // Check for element in forms
    3771                 for (var j=0; j<document.forms.length; j++) {
    3772                         for (var k=0; k<document.forms[j].elements.length; k++) {
    3773                                 if (document.forms[j].elements[k].name == element_id) {
    3774                                         elm = document.forms[j].elements[k];
    3775                                         break;
    3776                                 }
    3777                         }
    3778                 }
    3779         }
    3780 
    3781         return elm;
    3782 };
    3783 
    3784 TinyMCE.prototype.getEditorId = function(form_element) {
    3785         var inst = this.getInstanceById(form_element);
    3786         if (!inst)
    3787                 return null;
    3788 
    3789         return inst.editorId;
    3790 };
    3791 
    3792 TinyMCE.prototype.getInstanceById = function(editor_id) {
    3793         var inst = this.instances[editor_id];
    3794         if (!inst) {
    3795                 for (var n in tinyMCE.instances) {
    3796                         var instance = tinyMCE.instances[n];
    3797                         if (!tinyMCE.isInstance(instance))
    3798                                 continue;
    3799 
    3800                         if (instance.formTargetElementId == editor_id) {
    3801                                 inst = instance;
    3802                                 break;
    3803                         }
    3804                 }
    3805         }
    3806 
    3807         return inst;
    3808 };
    3809 
    3810 TinyMCE.prototype.queryInstanceCommandValue = function(editor_id, command) {
    3811         var inst = tinyMCE.getInstanceById(editor_id);
    3812         if (inst)
    3813                 return inst.queryCommandValue(command);
    3814 
    3815         return false;
    3816 };
    3817 
    3818 TinyMCE.prototype.queryInstanceCommandState = function(editor_id, command) {
    3819         var inst = tinyMCE.getInstanceById(editor_id);
    3820         if (inst)
    3821                 return inst.queryCommandState(command);
    3822 
    3823         return null;
    3824 };
    3825 
    3826 TinyMCE.prototype.setWindowArg = function(name, value) {
    3827         this.windowArgs[name] = value;
    3828 };
    3829 
    3830 TinyMCE.prototype.getWindowArg = function(name, default_value) {
    3831         return (typeof(this.windowArgs[name]) == "undefined") ? default_value : this.windowArgs[name];
    3832 };
    3833 
    3834 TinyMCE.prototype.getCSSClasses = function(editor_id, doc) {
    3835         var output = new Array();
    3836 
    3837         // Is cached, use that
    3838         if (typeof(tinyMCE.cssClasses) != "undefined")
    3839                 return tinyMCE.cssClasses;
    3840 
    3841         if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") {
    3842                 var instance;
    3843 
    3844                 for (var instanceName in tinyMCE.instances) {
    3845                         instance = tinyMCE.instances[instanceName];
    3846                         if (!tinyMCE.isInstance(instance))
    3847                                 continue;
    3848 
    3849                         break;
    3850                 }
    3851 
    3852                 doc = instance.getDoc();
    3853         }
    3854 
    3855         if (typeof(doc) == "undefined") {
    3856                 var instance = tinyMCE.getInstanceById(editor_id);
    3857                 doc = instance.getDoc();
    3858         }
    3859 
    3860         if (doc) {
    3861                 var styles = tinyMCE.isMSIE ? doc.styleSheets : doc.styleSheets;
    3862 
    3863                 if (styles && styles.length > 0) {
    3864                         for (var x=0; x<styles.length; x++) {
    3865                                 var csses = null;
    3866 
    3867                                 // Just ignore any errors
    3868                                 eval("try {var csses = tinyMCE.isMSIE ? doc.styleSheets(" + x + ").rules : doc.styleSheets[" + x + "].cssRules;} catch(e) {}");
    3869                                 if (!csses)
    3870                                         return new Array();
    3871 
    3872                                 for (var i=0; i<csses.length; i++) {
    3873                                         var selectorText = csses[i].selectorText;
    3874 
    3875                                         // Can be multiple rules per selector
    3876                                         if (selectorText) {
    3877                                                 var rules = selectorText.split(',');
    3878                                                 for (var c=0; c<rules.length; c++) {
    3879                                                         // Invalid rule
    3880                                                         if (rules[c].indexOf(' ') != -1 || rules[c].indexOf(':') != -1 || rules[c].indexOf('mceItem') != -1)
    3881                                                                 continue;
    3882 
    3883                                                         if (rules[c] == "." + tinyMCE.settings['visual_table_class'])
    3884                                                                 continue;
    3885 
    3886                                                         // Is class rule
    3887                                                         if (rules[c].indexOf('.') != -1) {
    3888                                                                 //alert(rules[c].substring(rules[c].indexOf('.')));
    3889                                                                 output[output.length] = rules[c].substring(rules[c].indexOf('.')+1);
    3890                                                         }
    3891                                                 }
    3892                                         }
    3893                                 }
    3894                         }
    3895                 }
    3896         }
    3897 
    3898         // Cache em
    3899         if (output.length > 0)
    3900                 tinyMCE.cssClasses = output;
    3901 
    3902         return output;
    3903 };
    3904 
    3905 TinyMCE.prototype.regexpReplace = function(in_str, reg_exp, replace_str, opts) {
    3906         if (in_str == null)
    3907                 return in_str;
    3908 
    3909         if (typeof(opts) == "undefined")
    3910                 opts = 'g';
    3911 
    3912         var re = new RegExp(reg_exp, opts);
    3913         return in_str.replace(re, replace_str);
    3914 };
    3915 
    3916 TinyMCE.prototype.trim = function(str) {
    3917         return str.replace(/^\s*|\s*$/g, "");
    3918 };
    3919 
    3920 TinyMCE.prototype.cleanupEventStr = function(str) {
    3921         str = "" + str;
    3922         str = str.replace('function anonymous()\n{\n', '');
    3923         str = str.replace('\n}', '');
    3924         str = str.replace(/^return true;/gi, ''); // Remove event blocker
    3925 
    3926         return str;
    3927 };
    3928 
    3929 TinyMCE.prototype.getAbsPosition = function(node) {
    3930         var pos = new Object();
    3931 
    3932         pos.absLeft = pos.absTop = 0;
    3933 
    3934         var parentNode = node;
    3935         while (parentNode) {
    3936                 pos.absLeft += parentNode.offsetLeft;
    3937                 pos.absTop += parentNode.offsetTop;
    3938 
    3939                 parentNode = parentNode.offsetParent;
    3940         }
    3941 
    3942         return pos;
    3943 };
    3944 
    3945 TinyMCE.prototype.getControlHTML = function(control_name) {
    3946         var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
    3947         var templateFunction;
    3948 
    3949         // Is it defined in any plugins
    3950         for (var i=themePlugins.length; i>=0; i--) {
    3951                 templateFunction = 'TinyMCE_' + themePlugins[i] + "_getControlHTML";
    3952                 if (eval("typeof(" + templateFunction + ")") != 'undefined') {
    3953                         var html = eval(templateFunction + "('" + control_name + "');");
    3954                         if (html != "")
    3955                                 return tinyMCE.replaceVar(html, "pluginurl", tinyMCE.baseURL + "/plugins/" + themePlugins[i]);
    3956                 }
    3957         }
    3958 
    3959         return eval('TinyMCE_' + tinyMCE.settings['theme'] + "_getControlHTML" + "('" + control_name + "');");
    3960 };
    3961 
    3962 TinyMCE.prototype._themeExecCommand = function(editor_id, element, command, user_interface, value) {
    3963         var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
    3964         var templateFunction;
    3965 
    3966         // Is it defined in any plugins
    3967         for (var i=themePlugins.length; i>=0; i--) {
    3968                 templateFunction = 'TinyMCE_' + themePlugins[i] + "_execCommand";
    3969                 if (eval("typeof(" + templateFunction + ")") != 'undefined') {
    3970                         if (eval(templateFunction + "(editor_id, element, command, user_interface, value);"))
    3971                                 return true;
    3972                 }
    3973         }
    3974 
    3975         // Theme funtion
    3976         templateFunction = 'TinyMCE_' + tinyMCE.settings['theme'] + "_execCommand";
    3977         if (eval("typeof(" + templateFunction + ")") != 'undefined')
    3978                 return eval(templateFunction + "(editor_id, element, command, user_interface, value);");
    3979 
    3980         // Pass to normal
    3981         return false;
    3982 };
    3983 
    3984 TinyMCE.prototype._getThemeFunction = function(suffix, skip_plugins) {
    3985         if (skip_plugins)
    3986                 return 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
    3987 
    3988         var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
    3989         var templateFunction;
    3990 
    3991         // Is it defined in any plugins
    3992         for (var i=themePlugins.length; i>=0; i--) {
    3993                 templateFunction = 'TinyMCE_' + themePlugins[i] + suffix;
    3994                 if (eval("typeof(" + templateFunction + ")") != 'undefined')
    3995                         return templateFunction;
    3996         }
    3997 
    3998         return 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
    3999 };
    4000 
    4001 
    4002 TinyMCE.prototype.isFunc = function(func_name) {
    4003         if (func_name == null || func_name == "")
    4004                 return false;
    4005 
    4006         return eval("typeof(" + func_name + ")") != "undefined";
    4007 };
    4008 
    4009 TinyMCE.prototype.exec = function(func_name, args) {
    4010         var str = func_name + '(';
    4011 
    4012         // Add all arguments
    4013         for (var i=3; i<args.length; i++) {
    4014                 str += 'args[' + i + ']';
    4015 
    4016                 if (i < args.length-1)
    4017                         str += ',';
    4018         }
    4019 
    4020         str += ');';
    4021 
    4022         return eval(str);
    4023 };
    4024 
    4025 TinyMCE.prototype.executeCallback = function(param, suffix, mode) {
    4026         switch (mode) {
    4027                 // No chain
    4028                 case 0:
    4029                         var state = false;
    4030 
    4031                         // Execute each plugin callback
    4032                         var plugins = tinyMCE.getParam('plugins', '', true, ',');
    4033                         for (var i=0; i<plugins.length; i++) {
    4034                                 var func = "TinyMCE_" + plugins[i] + suffix;
    4035                                 if (tinyMCE.isFunc(func)) {
    4036                                         tinyMCE.exec(func, this.executeCallback.arguments);
    4037                                         state = true;
    4038                                 }
    4039                         }
    4040 
    4041                         // Execute theme callback
    4042                         var func = 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
    4043                         if (tinyMCE.isFunc(func)) {
    4044                                 tinyMCE.exec(func, this.executeCallback.arguments);
    4045                                 state = true;
    4046                         }
    4047 
    4048                         // Execute settings callback
    4049                         var func = tinyMCE.getParam(param, '');
    4050                         if (tinyMCE.isFunc(func)) {
    4051                                 tinyMCE.exec(func, this.executeCallback.arguments);
    4052                                 state = true;
    4053                         }
    4054 
    4055                         return state;
    4056 
    4057                 // Chain mode
    4058                 case 1:
    4059                         // Execute each plugin callback
    4060                         var plugins = tinyMCE.getParam('plugins', '', true, ',');
    4061                         for (var i=0; i<plugins.length; i++) {
    4062                                 var func = "TinyMCE_" + plugins[i] + suffix;
    4063                                 if (tinyMCE.isFunc(func)) {
    4064                                         if (tinyMCE.exec(func, this.executeCallback.arguments))
    4065                                                 return true;
    4066                                 }
    4067                         }
    4068 
    4069                         // Execute theme callback
    4070                         var func = 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
    4071                         if (tinyMCE.isFunc(func)) {
    4072                                 if (tinyMCE.exec(func, this.executeCallback.arguments))
    4073                                         return true;
    4074                         }
    4075 
    4076                         // Execute settings callback
    4077                         var func = tinyMCE.getParam(param, '');
    4078                         if (tinyMCE.isFunc(func)) {
    4079                                 if (tinyMCE.exec(func, this.executeCallback.arguments))
    4080                                         return true;
    4081                         }
    4082 
    4083                         return false;
    4084         }
    4085 };
    4086 
    4087 TinyMCE.prototype.debug = function() {
    4088         var msg = "";
    4089 
    4090         var elm = document.getElementById("tinymce_debug");
    4091         if (!elm) {
    4092                 var debugDiv = document.createElement("div");
    4093                 debugDiv.setAttribute("className", "debugger");
    4094                 debugDiv.className = "debugger";
    4095                 debugDiv.innerHTML = '\
    4096                         Debug output:\
    4097                         <textarea id="tinymce_debug" style="width: 100%; height: 300px" wrap="nowrap"></textarea>';
    4098 
    4099                 document.body.appendChild(debugDiv);
    4100                 elm = document.getElementById("tinymce_debug");
    4101         }
    4102 
    4103         var args = this.debug.arguments;
    4104         for (var i=0; i<args.length; i++) {
    4105                 msg += args[i];
    4106                 if (i<args.length-1)
    4107                         msg += ', ';
    4108         }
    4109 
    4110         elm.value += msg + "\n";
    4111 };
    4112 
    4113 // TinyMCEControl
    4114 function TinyMCEControl(settings) {
    4115         // Undo levels
     5710/* file:jscripts/tiny_mce/classes/TinyMCE_UndoRedo.class.js */
     5711
     5712function TinyMCE_UndoRedo(inst) {
     5713        this.instance = inst;
    41165714        this.undoLevels = new Array();
    41175715        this.undoIndex = 0;
    41185716        this.typingUndoIndex = -1;
    41195717        this.undoRedo = true;
    4120         this.isTinyMCEControl = true;
    4121 
    4122         // Default settings
    4123         this.settings = settings;
    4124         this.settings['theme'] = tinyMCE.getParam("theme", "default");
    4125         this.settings['width'] = tinyMCE.getParam("width", -1);
    4126         this.settings['height'] = tinyMCE.getParam("height", -1);
    41275718};
    41285719
    4129 TinyMCEControl.prototype.repaint = function() {
    4130         if (tinyMCE.isMSIE && !tinyMCE.isOpera)
    4131                 return;
    4132 
    4133         // Ugly mozilla hack to remove ghost resize handles
    4134         try {
    4135                 this.getBody().style.display = 'none';
    4136                 this.getDoc().execCommand('selectall', false, null);
    4137                 this.getSel().collapseToStart();
    4138                 this.getBody().style.display = 'block';
    4139         } catch (ex) {
    4140                 // Could I care less!!
     5720TinyMCE_UndoRedo.prototype = {
     5721        add : function(l) {
     5722                var b;
     5723
     5724                if (l) {
     5725                        this.undoLevels[this.undoLevels.length] = l;
     5726                        return true;
     5727                }
     5728
     5729                var inst = this.instance;
     5730
     5731                if (this.typingUndoIndex != -1) {
     5732                        this.undoIndex = this.typingUndoIndex;
     5733                        // tinyMCE.debug("Override: " + this.undoIndex);
     5734                }
     5735
     5736                var newHTML = tinyMCE.trim(inst.getBody().innerHTML);
     5737                if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) {
     5738                        //tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex]);
     5739
     5740                        tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst);
     5741
     5742                        // Time to compress
     5743                        var customUndoLevels = tinyMCE.settings['custom_undo_redo_levels'];
     5744                        if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) {
     5745                                for (var i=0; i<this.undoLevels.length-1; i++) {
     5746                                        //tinyMCE.debug(this.undoLevels[i] + "=" + this.undoLevels[i+1]);
     5747                                        this.undoLevels[i] = this.undoLevels[i+1];
     5748                                }
     5749
     5750                                this.undoLevels.length--;
     5751                                this.undoIndex--;
     5752                        }
     5753
     5754                        b = inst.undoBookmark;
     5755                        if (!b)
     5756                                b = inst.selection.getBookmark();
     5757
     5758                        this.undoIndex++;
     5759                        this.undoLevels[this.undoIndex] = {
     5760                                content : newHTML,
     5761                                bookmark : b
     5762                        };
     5763
     5764                        this.undoLevels.length = this.undoIndex + 1;
     5765
     5766                        //tinyMCE.debug("level added" + this.undoIndex);
     5767                        return true;
     5768
     5769                        // tinyMCE.debug(this.undoIndex + "," + (this.undoLevels.length-1));
     5770                }
     5771
     5772                return false;
     5773        },
     5774
     5775        undo : function() {
     5776                var inst = this.instance;
     5777
     5778                // Do undo
     5779                if (this.undoIndex > 0) {
     5780                        this.undoIndex--;
     5781                        tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content);
     5782                        inst.repaint();
     5783                        if (inst.settings.custom_undo_redo_restore_selection)
     5784                                inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark);
     5785                }
     5786
     5787                // tinyMCE.debug("Undo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex);
     5788        },
     5789
     5790        redo : function() {
     5791                var inst = this.instance;
     5792
     5793                tinyMCE.execCommand("mceEndTyping");
     5794
     5795                if (this.undoIndex < (this.undoLevels.length-1)) {
     5796                        this.undoIndex++;
     5797                        tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content);
     5798                        inst.repaint();
     5799//                                      if (this.undoIndex > 0)
     5800//                                              inst.selection.moveToBookmark(this.undoLevels[this.undoIndex-1].bookmark);
     5801                        if (inst.settings.custom_undo_redo_restore_selection)
     5802                                inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark);
     5803                        // tinyMCE.debug("Redo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex);
     5804                }
     5805
     5806                tinyMCE.triggerNodeChange();
    41415807        }
    41425808};
    41435809
    4144 TinyMCEControl.prototype.switchSettings = function() {
    4145         if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings['index']) {
    4146                 tinyMCE.settings = this.settings;
    4147                 tinyMCE.currentConfig = this.settings['index'];
     5810/* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */
     5811
     5812var TinyMCE_ForceParagraphs = {
     5813        _insertPara : function(inst, e) {
     5814                function isEmpty(para) {
     5815                        function isEmptyHTML(html) {
     5816                                return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == "";
     5817                        }
     5818
     5819                        // Check for images
     5820                        if (para.getElementsByTagName("img").length > 0)
     5821                                return false;
     5822
     5823                        // Check for tables
     5824                        if (para.getElementsByTagName("table").length > 0)
     5825                                return false;
     5826
     5827                        // Check for HRs
     5828                        if (para.getElementsByTagName("hr").length > 0)
     5829                                return false;
     5830
     5831                        // Check all textnodes
     5832                        var nodes = tinyMCE.getNodeTree(para, new Array(), 3);
     5833                        for (var i=0; i<nodes.length; i++) {
     5834                                if (!isEmptyHTML(nodes[i].nodeValue))
     5835                                        return false;
     5836                        }
     5837
     5838                        // No images, no tables, no hrs, no text content then it's empty
     5839                        return true;
     5840                }
     5841
     5842                var doc = inst.getDoc();
     5843                var sel = inst.getSel();
     5844                var win = inst.contentWindow;
     5845                var rng = sel.getRangeAt(0);
     5846                var body = doc.body;
     5847                var rootElm = doc.documentElement;
     5848                var blockName = "P";
     5849
     5850        //      tinyMCE.debug(body.innerHTML);
     5851
     5852        //      debug(e.target, sel.anchorNode.nodeName, sel.focusNode.nodeName, rng.startContainer, rng.endContainer, rng.commonAncestorContainer, sel.anchorOffset, sel.focusOffset, rng.toString());
     5853
     5854                // Setup before range
     5855                var rngBefore = doc.createRange();
     5856                rngBefore.setStart(sel.anchorNode, sel.anchorOffset);
     5857                rngBefore.collapse(true);
     5858
     5859                // Setup after range
     5860                var rngAfter = doc.createRange();
     5861                rngAfter.setStart(sel.focusNode, sel.focusOffset);
     5862                rngAfter.collapse(true);
     5863
     5864                // Setup start/end points
     5865                var direct = rngBefore.compareBoundaryPoints(rngBefore.START_TO_END, rngAfter) < 0;
     5866                var startNode = direct ? sel.anchorNode : sel.focusNode;
     5867                var startOffset = direct ? sel.anchorOffset : sel.focusOffset;
     5868                var endNode = direct ? sel.focusNode : sel.anchorNode;
     5869                var endOffset = direct ? sel.focusOffset : sel.anchorOffset;
     5870
     5871                startNode = startNode.nodeName == "BODY" ? startNode.firstChild : startNode;
     5872                endNode = endNode.nodeName == "BODY" ? endNode.firstChild : endNode;
     5873
     5874                // tinyMCE.debug(startNode, endNode);
     5875
     5876                // Get block elements
     5877                var startBlock = tinyMCE.getParentBlockElement(startNode);
     5878                var endBlock = tinyMCE.getParentBlockElement(endNode);
     5879
     5880                // Use current block name
     5881                if (startBlock != null) {
     5882                        blockName = startBlock.nodeName;
     5883
     5884                        // Use P instead
     5885                        if (blockName == "TD" || blockName == "TABLE" || (blockName == "DIV" && new RegExp('left|right', 'gi').test(startBlock.style.cssFloat)))
     5886                                blockName = "P";
     5887                }
     5888
     5889                // Within a list use normal behaviour
     5890                if (tinyMCE.getParentElement(startBlock, "OL,UL") != null)
     5891                        return false;
     5892
     5893                // Within a table create new paragraphs
     5894                if ((startBlock != null && startBlock.nodeName == "TABLE") || (endBlock != null && endBlock.nodeName == "TABLE"))
     5895                        startBlock = endBlock = null;
     5896
     5897                // Setup new paragraphs
     5898                var paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName);
     5899                var paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName);
     5900
     5901                // Is header, then force paragraph under
     5902                if (/^(H[1-6])$/.test(blockName))
     5903                        paraAfter = doc.createElement("p");
     5904
     5905                // Setup chop nodes
     5906                var startChop = startNode;
     5907                var endChop = endNode;
     5908
     5909                // Get startChop node
     5910                node = startChop;
     5911                do {
     5912                        if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
     5913                                break;
     5914
     5915                        startChop = node;
     5916                } while ((node = node.previousSibling ? node.previousSibling : node.parentNode));
     5917
     5918                // Get endChop node
     5919                node = endChop;
     5920                do {
     5921                        if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
     5922                                break;
     5923
     5924                        endChop = node;
     5925                } while ((node = node.nextSibling ? node.nextSibling : node.parentNode));
     5926
     5927                // Fix when only a image is within the TD
     5928                if (startChop.nodeName == "TD")
     5929                        startChop = startChop.firstChild;
     5930
     5931                if (endChop.nodeName == "TD")
     5932                        endChop = endChop.lastChild;
     5933
     5934                // If not in a block element
     5935                if (startBlock == null) {
     5936                        // Delete selection
     5937                        rng.deleteContents();
     5938                        sel.removeAllRanges();
     5939
     5940                        if (startChop != rootElm && endChop != rootElm) {
     5941                                // Insert paragraph before
     5942                                rngBefore = rng.cloneRange();
     5943
     5944                                if (startChop == body)
     5945                                        rngBefore.setStart(startChop, 0);
     5946                                else
     5947                                        rngBefore.setStartBefore(startChop);
     5948
     5949                                paraBefore.appendChild(rngBefore.cloneContents());
     5950
     5951                                // Insert paragraph after
     5952                                if (endChop.parentNode.nodeName == blockName)
     5953                                        endChop = endChop.parentNode;
     5954
     5955                                // If not after image
     5956                                //if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY")
     5957                                        rng.setEndAfter(endChop);
     5958
     5959                                if (endChop.nodeName != "#text" && endChop.nodeName != "BODY")
     5960                                        rngBefore.setEndAfter(endChop);
     5961
     5962                                var contents = rng.cloneContents();
     5963                                if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY"))
     5964                                        paraAfter.innerHTML = contents.firstChild.innerHTML;
     5965                                else
     5966                                        paraAfter.appendChild(contents);
     5967
     5968                                // Check if it's a empty paragraph
     5969                                if (isEmpty(paraBefore))
     5970                                        paraBefore.innerHTML = "&nbsp;";
     5971
     5972                                // Check if it's a empty paragraph
     5973                                if (isEmpty(paraAfter))
     5974                                        paraAfter.innerHTML = "&nbsp;";
     5975
     5976                                // Delete old contents
     5977                                rng.deleteContents();
     5978                                rngAfter.deleteContents();
     5979                                rngBefore.deleteContents();
     5980
     5981                                // Insert new paragraphs
     5982                                paraAfter.normalize();
     5983                                rngBefore.insertNode(paraAfter);
     5984                                paraBefore.normalize();
     5985                                rngBefore.insertNode(paraBefore);
     5986
     5987                                // tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML);
     5988                        } else {
     5989                                body.innerHTML = "<" + blockName + ">&nbsp;</" + blockName + "><" + blockName + ">&nbsp;</" + blockName + ">";
     5990                                paraAfter = body.childNodes[1];
     5991                        }
     5992
     5993                        inst.selection.selectNode(paraAfter, true, true);
     5994
     5995                        return true;
     5996                }
     5997
     5998                // Place first part within new paragraph
     5999                if (startChop.nodeName == blockName)
     6000                        rngBefore.setStart(startChop, 0);
     6001                else
     6002                        rngBefore.setStartBefore(startChop);
     6003
     6004                rngBefore.setEnd(startNode, startOffset);
     6005                paraBefore.appendChild(rngBefore.cloneContents());
     6006
     6007                // Place secound part within new paragraph
     6008                rngAfter.setEndAfter(endChop);
     6009                rngAfter.setStart(endNode, endOffset);
     6010                var contents = rngAfter.cloneContents();
     6011
     6012                if (contents.firstChild && contents.firstChild.nodeName == blockName) {
     6013        /*              var nodes = contents.firstChild.childNodes;
     6014                        for (var i=0; i<nodes.length; i++) {
     6015                                //tinyMCE.debug(nodes[i].nodeName);
     6016                                if (nodes[i].nodeName != "BODY")
     6017                                        paraAfter.appendChild(nodes[i]);
     6018                        }
     6019        */
     6020                        paraAfter.innerHTML = contents.firstChild.innerHTML;
     6021                } else
     6022                        paraAfter.appendChild(contents);
     6023
     6024                // Check if it's a empty paragraph
     6025                if (isEmpty(paraBefore))
     6026                        paraBefore.innerHTML = "&nbsp;";
     6027
     6028                // Check if it's a empty paragraph
     6029                if (isEmpty(paraAfter))
     6030                        paraAfter.innerHTML = "&nbsp;";
     6031
     6032                // Create a range around everything
     6033                var rng = doc.createRange();
     6034
     6035                if (!startChop.previousSibling && startChop.parentNode.nodeName.toUpperCase() == blockName) {
     6036                        rng.setStartBefore(startChop.parentNode);
     6037                } else {
     6038                        if (rngBefore.startContainer.nodeName.toUpperCase() == blockName && rngBefore.startOffset == 0)
     6039                                rng.setStartBefore(rngBefore.startContainer);
     6040                        else
     6041                                rng.setStart(rngBefore.startContainer, rngBefore.startOffset);
     6042                }
     6043
     6044                if (!endChop.nextSibling && endChop.parentNode.nodeName.toUpperCase() == blockName)
     6045                        rng.setEndAfter(endChop.parentNode);
     6046                else
     6047                        rng.setEnd(rngAfter.endContainer, rngAfter.endOffset);
     6048
     6049                // Delete all contents and insert new paragraphs
     6050                rng.deleteContents();
     6051                rng.insertNode(paraAfter);
     6052                rng.insertNode(paraBefore);
     6053                //tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML);
     6054
     6055                // Normalize
     6056                paraAfter.normalize();
     6057                paraBefore.normalize();
     6058
     6059                inst.selection.selectNode(paraAfter, true, true);
     6060
     6061                return true;
     6062        },
     6063
     6064        _handleBackSpace : function(inst) {
     6065                var r = inst.getRng();
     6066                var sn = r.startContainer;
     6067
     6068                if (sn && sn.nextSibling && sn.nextSibling.nodeName == "BR")
     6069                        sn.nextSibling.parentNode.removeChild(sn.nextSibling);
     6070
     6071                return false;
    41486072        }
    41496073};
    41506074
    4151 TinyMCEControl.prototype.convertAllRelativeURLs = function() {
    4152         var body = this.getBody();
    4153 
    4154         // Convert all image URL:s to absolute URL
    4155         var elms = body.getElementsByTagName("img");
    4156         for (var i=0; i<elms.length; i++) {
    4157                 var src = tinyMCE.getAttrib(elms[i], 'src');
    4158 
    4159                 var msrc = tinyMCE.getAttrib(elms[i], 'mce_src');
    4160                 if (msrc != "")
    4161                         src = msrc;
    4162 
    4163                 if (src != "") {
    4164                         src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src);
    4165                         elms[i].setAttribute("src", src);
    4166                 }
    4167         }
    4168 
    4169         // Convert all link URL:s to absolute URL
    4170         var elms = body.getElementsByTagName("a");
    4171         for (var i=0; i<elms.length; i++) {
    4172                 var href = tinyMCE.getAttrib(elms[i], 'href');
    4173 
    4174                 var mhref = tinyMCE.getAttrib(elms[i], 'mce_href');
    4175                 if (mhref != "")
    4176                         href = mhref;
    4177 
    4178                 if (href && href != "") {
    4179                         href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], href);
    4180                         elms[i].setAttribute("href", href);
    4181                 }
     6075/* file:jscripts/tiny_mce/classes/TinyMCE_Layer.class.js */
     6076
     6077function TinyMCE_Layer(id, bm) {
     6078        this.id = id;
     6079        this.blockerElement = null;
     6080        this.events = false;
     6081        this.element = null;
     6082        this.blockMode = typeof(bm) != 'undefined' ? bm : true;
     6083};
     6084
     6085TinyMCE_Layer.prototype = {
     6086        moveRelativeTo : function(re, p) {
     6087                var rep = this.getAbsPosition(re);
     6088                var w = parseInt(re.offsetWidth);
     6089                var h = parseInt(re.offsetHeight);
     6090                var e = this.getElement();
     6091                var ew = parseInt(e.offsetWidth);
     6092                var eh = parseInt(e.offsetHeight);
     6093                var x, y;
     6094
     6095                switch (p) {
     6096                        case "tl":
     6097                                x = rep.absLeft;
     6098                                y = rep.absTop;
     6099                                break;
     6100
     6101                        case "tr":
     6102                                x = rep.absLeft + w;
     6103                                y = rep.absTop;
     6104                                break;
     6105
     6106                        case "bl":
     6107                                x = rep.absLeft;
     6108                                y = rep.absTop + h;
     6109                                break;
     6110
     6111                        case "br":
     6112                                x = rep.absLeft + w;
     6113                                y = rep.absTop + h;
     6114                                break;
     6115
     6116                        case "cc":
     6117                                x = rep.absLeft + (w / 2) - (ew / 2);
     6118                                y = rep.absTop + (h / 2) - (eh / 2);
     6119                                break;
     6120                }
     6121
     6122                this.moveTo(x, y);
     6123        },
     6124
     6125        moveBy : function(x, y) {
     6126                var e = this.getElement();
     6127                this.moveTo(parseInt(e.style.left) + x, parseInt(e.style.top) + y);
     6128        },
     6129
     6130        moveTo : function(x, y) {
     6131                var e = this.getElement();
     6132
     6133                e.style.left = x + "px";
     6134                e.style.top = y + "px";
     6135
     6136                this.updateBlocker();
     6137        },
     6138
     6139        resizeBy : function(w, h) {
     6140                var e = this.getElement();
     6141                this.resizeTo(parseInt(e.style.width) + w, parseInt(e.style.height) + h);
     6142        },
     6143
     6144        resizeTo : function(w, h) {
     6145                var e = this.getElement();
     6146
     6147                e.style.width = w + "px";
     6148                e.style.height = h + "px";
     6149
     6150                this.updateBlocker();
     6151        },
     6152
     6153        show : function() {
     6154                this.getElement().style.display = 'block';
     6155                this.updateBlocker();
     6156        },
     6157
     6158        hide : function() {
     6159                this.getElement().style.display = 'none';
     6160                this.updateBlocker();
     6161        },
     6162
     6163        isVisible : function() {
     6164                return this.getElement().style.display == 'block';
     6165        },
     6166
     6167        getElement : function() {
     6168                if (!this.element)
     6169                        this.element = document.getElementById(this.id);
     6170
     6171                return this.element;
     6172        },
     6173
     6174        setBlockMode : function(s) {
     6175                this.blockMode = s;
     6176        },
     6177
     6178        updateBlocker : function() {
     6179                var e, b, x, y, w, h;
     6180
     6181                b = this.getBlocker();
     6182                if (b) {
     6183                        if (this.blockMode) {
     6184                                e = this.getElement();
     6185                                x = this.parseInt(e.style.left);
     6186                                y = this.parseInt(e.style.top);
     6187                                w = this.parseInt(e.offsetWidth);
     6188                                h = this.parseInt(e.offsetHeight);
     6189
     6190                                b.style.left = x + 'px';
     6191                                b.style.top = y + 'px';
     6192                                b.style.width = w + 'px';
     6193                                b.style.height = h + 'px';
     6194                                b.style.display = e.style.display;
     6195                        } else
     6196                                b.style.display = 'none';
     6197                }
     6198        },
     6199
     6200        getBlocker : function() {
     6201                var d, b;
     6202
     6203                if (!this.blockerElement && this.blockMode) {
     6204                        d = document;
     6205                        b = d.createElement("iframe");
     6206
     6207                        b.style.cssText = 'display: none; position: absolute; left: 0; top: 0';
     6208                        b.src = 'javascript:false;';
     6209                        b.frameBorder = '0';
     6210                        b.scrolling = 'no';
     6211
     6212                        d.body.appendChild(b);
     6213                        this.blockerElement = b;
     6214                }
     6215
     6216                return this.blockerElement;
     6217        },
     6218
     6219        getAbsPosition : function(n) {
     6220                var p = {absLeft : 0, absTop : 0};
     6221
     6222                while (n) {
     6223                        p.absLeft += n.offsetLeft;
     6224                        p.absTop += n.offsetTop;
     6225                        n = n.offsetParent;
     6226                }
     6227
     6228                return p;
     6229        },
     6230
     6231        create : function(n, c, p) {
     6232                var d = document, e = d.createElement(n);
     6233
     6234                e.setAttribute('id', this.id);
     6235
     6236                if (c)
     6237                        e.className = c;
     6238
     6239                if (!p)
     6240                        p = d.body;
     6241
     6242                p.appendChild(e);
     6243
     6244                return this.element = e;
     6245        },
     6246/*
     6247        addCSSClass : function(e, c) {
     6248                this.removeCSSClass(e, c);
     6249                var a = this.explode(' ', e.className);
     6250                a[a.length] = c;
     6251                e.className = a.join(' ');
     6252        },
     6253
     6254        removeCSSClass : function(e, c) {
     6255                var a = this.explode(' ', e.className), i;
     6256
     6257                for (i=0; i<a.length; i++) {
     6258                        if (a[i] == c)
     6259                                a[i] = '';
     6260                }
     6261
     6262                e.className = a.join(' ');
     6263        },
     6264
     6265        explode : function(d, s) {
     6266                var ar = s.split(d);
     6267                var oar = new Array();
     6268
     6269                for (var i = 0; i<ar.length; i++) {
     6270                        if (ar[i] != "")
     6271                                oar[oar.length] = ar[i];
     6272                }
     6273
     6274                return oar;
     6275        },
     6276*/
     6277
     6278        parseInt : function(s) {
     6279                if (s == null || s == '')
     6280                        return 0;
     6281
     6282                return parseInt(s);
    41826283        }
    41836284};
    41846285
    4185 TinyMCEControl.prototype.getSelectedHTML = function() {
    4186         if (tinyMCE.isSafari) {
    4187                 // Not realy perfect!!
    4188 
    4189                 return this.getRng().toString();
     6286/* file:jscripts/tiny_mce/classes/TinyMCE_Menu.class.js */
     6287
     6288function TinyMCE_Menu() {
     6289        var id;
     6290
     6291        if (typeof(tinyMCE.menuCounter) == "undefined")
     6292                tinyMCE.menuCounter = 0;
     6293
     6294        id = "mc_menu_" + tinyMCE.menuCounter++;
     6295
     6296        TinyMCE_Layer.call(this, id, true);
     6297
     6298        this.id = id;
     6299        this.items = new Array();
     6300        this.needsUpdate = true;
     6301};
     6302
     6303// Extends the TinyMCE_Layer class
     6304TinyMCE_Menu.prototype = tinyMCE.extend(TinyMCE_Layer.prototype, {
     6305        init : function(s) {
     6306                var n;
     6307
     6308                // Default params
     6309                this.settings = {
     6310                        separator_class : 'mceMenuSeparator',
     6311                        title_class : 'mceMenuTitle',
     6312                        disabled_class : 'mceMenuDisabled',
     6313                        menu_class : 'mceMenu',
     6314                        drop_menu : true
     6315                };
     6316
     6317                for (n in s)
     6318                        this.settings[n] = s[n];
     6319
     6320                this.create('div', this.settings.menu_class);
     6321        },
     6322
     6323        clear : function() {
     6324                this.items = new Array();
     6325        },
     6326
     6327        addTitle : function(t) {
     6328                this.add({type : 'title', text : t});
     6329        },
     6330
     6331        addDisabled : function(t) {
     6332                this.add({type : 'disabled', text : t});
     6333        },
     6334
     6335        addSeparator : function() {
     6336                this.add({type : 'separator'});
     6337        },
     6338
     6339        addItem : function(t, js) {
     6340                this.add({text : t, js : js});
     6341        },
     6342
     6343        add : function(mi) {
     6344                this.items[this.items.length] = mi;
     6345                this.needsUpdate = true;
     6346        },
     6347
     6348        update : function() {
     6349                var e = this.getElement(), h = '', i, t, m = this.items, s = this.settings;
     6350
     6351                if (this.settings.drop_menu)
     6352                        h += '<span class="mceMenuLine"></span>';
     6353
     6354                h += '<table border="0" cellpadding="0" cellspacing="0">';
     6355
     6356                for (i=0; i<m.length; i++) {
     6357                        t = tinyMCE.xmlEncode(m[i].text);
     6358                        c = m[i].class_name ? ' class="' + m[i].class_name + '"' : '';
     6359
     6360                        switch (m[i].type) {
     6361                                case 'separator':
     6362                                        h += '<tr class="' + s.separator_class + '"><td>';
     6363                                        break;
     6364
     6365                                case 'title':
     6366                                        h += '<tr class="' + s.title_class + '"><td><span' + c +'>' + t + '</span>';
     6367                                        break;
     6368
     6369                                case 'disabled':
     6370                                        h += '<tr class="' + s.disabled_class + '"><td><span' + c +'>' + t + '</span>';
     6371                                        break;
     6372
     6373                                default:
     6374                                        h += '<tr><td><a href="javascript:void(0);" onmousedown="' + tinyMCE.xmlEncode(m[i].js) + ';return false;"><span' + c +'>' + t + '</span></a>';
     6375                        }
     6376
     6377                        h += '</td></tr>';
     6378                }
     6379
     6380                h += '</table>';
     6381
     6382                e.innerHTML = h;
     6383
     6384                this.needsUpdate = false;
     6385                this.updateBlocker();
     6386        },
     6387
     6388        show : function() {
     6389                var nl, i;
     6390
     6391                if (tinyMCE.lastMenu == this)
     6392                        return;
     6393
     6394                if (this.needsUpdate)
     6395                        this.update();
     6396
     6397                if (tinyMCE.lastMenu && tinyMCE.lastMenu != this)
     6398                        tinyMCE.lastMenu.hide();
     6399
     6400                this.parent.show.call(this);
     6401
     6402                if (!tinyMCE.isOpera) {
     6403                        // Accessibility stuff
     6404/*                      nl = this.getElement().getElementsByTagName("a");
     6405                        if (nl.length > 0)
     6406                                nl[0].focus();*/
     6407                }
     6408
     6409                tinyMCE.lastMenu = this;
    41906410        }
    4191 
    4192         var elm = document.createElement("body");
    4193 
    4194         if (tinyMCE.isGecko)
    4195                 elm.appendChild(this.getRng().cloneContents());
    4196         else
    4197                 elm.innerHTML = this.getRng().htmlText;
    4198 
    4199         return tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, elm, this.visualAid);
     6411});
     6412
     6413/* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */
     6414
     6415TinyMCE_Engine.prototype.debug = function() {
     6416        var m = "", e, a, i;
     6417
     6418        e = document.getElementById("tinymce_debug");
     6419        if (!e) {
     6420                var d = document.createElement("div");
     6421                d.setAttribute("className", "debugger");
     6422                d.className = "debugger";
     6423                d.innerHTML = 'Debug output:<textarea id="tinymce_debug" style="width: 100%; height: 300px" wrap="nowrap" mce_editable="false"></textarea>';
     6424
     6425                document.body.appendChild(d);
     6426                e = document.getElementById("tinymce_debug");
     6427        }
     6428
     6429        a = this.debug.arguments;
     6430        for (i=0; i<a.length; i++) {
     6431                m += a[i];
     6432                if (i<a.length-1)
     6433                        m += ', ';
     6434        }
     6435
     6436        e.value += m + "\n";
    42006437};
    4201 
    4202 TinyMCEControl.prototype.getBookmark = function() {
    4203         var rng = this.getRng();
    4204 
    4205         if (tinyMCE.isSafari)
    4206                 return rng;
    4207 
    4208         if (tinyMCE.isMSIE)
    4209                 return rng;
    4210 
    4211         if (tinyMCE.isGecko)
    4212                 return rng.cloneRange();
    4213 
    4214         return null;
    4215 };
    4216 
    4217 TinyMCEControl.prototype.moveToBookmark = function(bookmark) {
    4218         if (tinyMCE.isSafari) {
    4219                 var sel = this.getSel().realSelection;
    4220 
    4221                 sel.setBaseAndExtent(bookmark.startContainer, bookmark.startOffset, bookmark.endContainer, bookmark.endOffset);
    4222 
    4223                 return true;
    4224         }
    4225 
    4226         if (tinyMCE.isMSIE)
    4227                 return bookmark.select();
    4228 
    4229         if (tinyMCE.isGecko) {
    4230                 var rng = this.getDoc().createRange();
    4231                 var sel = this.getSel();
    4232 
    4233                 rng.setStart(bookmark.startContainer, bookmark.startOffset);
    4234                 rng.setEnd(bookmark.endContainer, bookmark.endOffset);
    4235 
    4236                 sel.removeAllRanges();
    4237                 sel.addRange(rng);
    4238 
    4239                 return true;
    4240         }
    4241 
    4242         return false;
    4243 };
    4244 
    4245 TinyMCEControl.prototype.getSelectedText = function() {
    4246         if (tinyMCE.isMSIE) {
    4247                 var doc = this.getDoc();
    4248 
    4249                 if (doc.selection.type == "Text") {
    4250                         var rng = doc.selection.createRange();
    4251                         selectedText = rng.text;
    4252                 } else
    4253                         selectedText = '';
    4254         } else {
    4255                 var sel = this.getSel();
    4256 
    4257                 if (sel && sel.toString)
    4258                         selectedText = sel.toString();
    4259                 else
    4260                         selectedText = '';
    4261         }
    4262 
    4263         return selectedText;
    4264 };
    4265 
    4266 TinyMCEControl.prototype.selectNode = function(node, collapse, select_text_node, to_start) {
    4267         if (!node)
    4268                 return;
    4269 
    4270         if (typeof(collapse) == "undefined")
    4271                 collapse = true;
    4272 
    4273         if (typeof(select_text_node) == "undefined")
    4274                 select_text_node = false;
    4275 
    4276         if (typeof(to_start) == "undefined")
    4277                 to_start = true;
    4278 
    4279         if (tinyMCE.isMSIE) {
    4280                 var rng = this.getBody().createTextRange();
    4281 
    4282                 try {
    4283                         rng.moveToElementText(node);
    4284 
    4285                         if (collapse)
    4286                                 rng.collapse(to_start);
    4287 
    4288                         rng.select();
    4289                 } catch (e) {
    4290                         // Throws illigal agrument in MSIE some times
    4291                 }
    4292         } else {
    4293                 var sel = this.getSel();
    4294 
    4295                 if (!sel)
    4296                         return;
    4297 
    4298                 if (tinyMCE.isSafari) {
    4299                         sel.realSelection.setBaseAndExtent(node, 0, node, node.innerText.length);
    4300 
    4301                         if (collapse) {
    4302                                 if (to_start)
    4303                                         sel.realSelection.collapseToStart();
    4304                                 else
    4305                                         sel.realSelection.collapseToEnd();
    4306                         }
    4307 
    4308                         this.scrollToNode(node);
    4309 
    4310                         return;
    4311                 }
    4312 
    4313                 var rng = this.getDoc().createRange();
    4314 
    4315                 if (select_text_node) {
    4316                         // Find first textnode in tree
    4317                         var nodes = tinyMCE.getNodeTree(node, new Array(), 3);
    4318                         if (nodes.length > 0)
    4319                                 rng.selectNodeContents(nodes[0]);
    4320                         else
    4321                                 rng.selectNodeContents(node);
    4322                 } else
    4323                         rng.selectNode(node);
    4324 
    4325                 if (collapse) {
    4326                         // Special treatment of textnode collapse
    4327                         if (!to_start && node.nodeType == 3) {
    4328                                 rng.setStart(node, node.nodeValue.length);
    4329                                 rng.setEnd(node, node.nodeValue.length);
    4330                         } else
    4331                                 rng.collapse(to_start);
    4332                 }
    4333 
    4334                 sel.removeAllRanges();
    4335                 sel.addRange(rng);
    4336         }
    4337 
    4338         this.scrollToNode(node);
    4339 
    4340         // Set selected element
    4341         tinyMCE.selectedElement = null;
    4342         if (node.nodeType == 1)
    4343                 tinyMCE.selectedElement = node;
    4344 };
    4345 
    4346 TinyMCEControl.prototype.scrollToNode = function(node) {
    4347         // Scroll to node position
    4348         var pos = tinyMCE.getAbsPosition(node);
    4349         var doc = this.getDoc();
    4350         var scrollX = doc.body.scrollLeft + doc.documentElement.scrollLeft;
    4351         var scrollY = doc.body.scrollTop + doc.documentElement.scrollTop;
    4352         var height = tinyMCE.isMSIE ? document.getElementById(this.editorId).style.pixelHeight : this.targetElement.clientHeight;
    4353 
    4354         // Only scroll if out of visible area
    4355         if (!tinyMCE.settings['auto_resize'] && !(pos.absTop > scrollY && pos.absTop < (scrollY - 25 + height)))
    4356                 this.contentWindow.scrollTo(pos.absLeft, pos.absTop - height + 25);
    4357 };
    4358 
    4359 TinyMCEControl.prototype.getBody = function() {
    4360         return this.getDoc().body;
    4361 };
    4362 
    4363 TinyMCEControl.prototype.getDoc = function() {
    4364         return this.contentWindow.document;
    4365 };
    4366 
    4367 TinyMCEControl.prototype.getWin = function() {
    4368         return this.contentWindow;
    4369 };
    4370 
    4371 TinyMCEControl.prototype.getSel = function() {
    4372         if (tinyMCE.isMSIE && !tinyMCE.isOpera)
    4373                 return this.getDoc().selection;
    4374 
    4375         var sel = this.contentWindow.getSelection();
    4376 
    4377         // Fake getRangeAt
    4378         if (tinyMCE.isSafari && !sel.getRangeAt) {
    4379                 var newSel = new Object();
    4380                 var doc = this.getDoc();
    4381 
    4382                 function getRangeAt(idx) {
    4383                         var rng = new Object();
    4384 
    4385                         rng.startContainer = this.focusNode;
    4386                         rng.endContainer = this.anchorNode;
    4387                         rng.commonAncestorContainer = this.focusNode;
    4388                         rng.createContextualFragment = function (html) {
    4389                                 // Seems to be a tag
    4390                                 if (html.charAt(0) == '<') {
    4391                                         var elm = doc.createElement("div");
    4392 
    4393                                         elm.innerHTML = html;
    4394 
    4395                                         return elm.firstChild;
    4396                                 }
    4397 
    4398                                 return doc.createTextNode("UNSUPPORTED, DUE TO LIMITATIONS IN SAFARI!");
    4399                         };
    4400 
    4401                         rng.deleteContents = function () {
    4402                                 doc.execCommand("Delete", false, "");
    4403                         };
    4404 
    4405                         return rng;
    4406                 }
    4407 
    4408                 // Patch selection
    4409 
    4410                 newSel.focusNode = sel.baseNode;
    4411                 newSel.focusOffset = sel.baseOffset;
    4412                 newSel.anchorNode = sel.extentNode;
    4413                 newSel.anchorOffset = sel.extentOffset;
    4414                 newSel.getRangeAt = getRangeAt;
    4415                 newSel.text = "" + sel;
    4416                 newSel.realSelection = sel;
    4417 
    4418                 newSel.toString = function () {return this.text;};
    4419 
    4420                 return newSel;
    4421         }
    4422 
    4423         return sel;
    4424 };
    4425 
    4426 TinyMCEControl.prototype.getRng = function() {
    4427         var sel = this.getSel();
    4428         if (sel == null)
    4429                 return null;
    4430 
    4431         if (tinyMCE.isMSIE && !tinyMCE.isOpera)
    4432                 return sel.createRange();
    4433 
    4434         if (tinyMCE.isSafari) {
    4435                 var rng = this.getDoc().createRange();
    4436                 var sel = this.getSel().realSelection;
    4437 
    4438                 rng.setStart(sel.baseNode, sel.baseOffset);
    4439                 rng.setEnd(sel.extentNode, sel.extentOffset);
    4440 
    4441                 return rng;
    4442         }
    4443 
    4444         return this.getSel().getRangeAt(0);
    4445 };
    4446 
    4447 TinyMCEControl.prototype._insertPara = function(e) {
    4448         function isEmpty(para) {
    4449                 function isEmptyHTML(html) {
    4450                         return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == "";
    4451                 }
    4452 
    4453                 // Check for images
    4454                 if (para.getElementsByTagName("img").length > 0)
    4455                         return false;
    4456 
    4457                 // Check for tables
    4458                 if (para.getElementsByTagName("table").length > 0)
    4459                         return false;
    4460 
    4461                 // Check for HRs
    4462                 if (para.getElementsByTagName("hr").length > 0)
    4463                         return false;
    4464 
    4465                 // Check all textnodes
    4466                 var nodes = tinyMCE.getNodeTree(para, new Array(), 3);
    4467                 for (var i=0; i<nodes.length; i++) {
    4468                         if (!isEmptyHTML(nodes[i].nodeValue))
    4469                                 return false;
    4470                 }
    4471 
    4472                 // No images, no tables, no hrs, no text content then it's empty
    4473                 return true;
    4474         }
    4475 
    4476         var doc = this.getDoc();
    4477         var sel = this.getSel();
    4478         var win = this.contentWindow;
    4479         var rng = sel.getRangeAt(0);
    4480         var body = doc.body;
    4481         var rootElm = doc.documentElement;
    4482         var self = this;
    4483         var blockName = "P";
    4484 
    4485 //      tinyMCE.debug(body.innerHTML);
    4486 
    4487 //      debug(e.target, sel.anchorNode.nodeName, sel.focusNode.nodeName, rng.startContainer, rng.endContainer, rng.commonAncestorContainer, sel.anchorOffset, sel.focusOffset, rng.toString());
    4488 
    4489         // Setup before range
    4490         var rngBefore = doc.createRange();
    4491         rngBefore.setStart(sel.anchorNode, sel.anchorOffset);
    4492         rngBefore.collapse(true);
    4493 
    4494         // Setup after range
    4495         var rngAfter = doc.createRange();
    4496         rngAfter.setStart(sel.focusNode, sel.focusOffset);
    4497         rngAfter.collapse(true);
    4498 
    4499         // Setup start/end points
    4500         var direct = rngBefore.compareBoundaryPoints(rngBefore.START_TO_END, rngAfter) < 0;
    4501         var startNode = direct ? sel.anchorNode : sel.focusNode;
    4502         var startOffset = direct ? sel.anchorOffset : sel.focusOffset;
    4503         var endNode = direct ? sel.focusNode : sel.anchorNode;
    4504         var endOffset = direct ? sel.focusOffset : sel.anchorOffset;
    4505 
    4506         startNode = startNode.nodeName == "BODY" ? startNode.firstChild : startNode;
    4507         endNode = endNode.nodeName == "BODY" ? endNode.firstChild : endNode;
    4508 
    4509         // tinyMCE.debug(startNode, endNode);
    4510 
    4511         // Get block elements
    4512         var startBlock = tinyMCE.getParentBlockElement(startNode);
    4513         var endBlock = tinyMCE.getParentBlockElement(endNode);
    4514 
    4515         // Use current block name
    4516         if (startBlock != null) {
    4517                 blockName = startBlock.nodeName;
    4518 
    4519                 // Use P instead
    4520                 if (blockName == "TD" || blockName == "TABLE" || (blockName == "DIV" && new RegExp('left|right', 'gi').test(startBlock.style.cssFloat)))
    4521                         blockName = "P";
    4522         }
    4523 
    4524         // Within a list use normal behaviour
    4525         if (tinyMCE.getParentElement(startBlock, "OL,UL") != null)
    4526                 return false;
    4527 
    4528         // Within a table create new paragraphs
    4529         if ((startBlock != null && startBlock.nodeName == "TABLE") || (endBlock != null && endBlock.nodeName == "TABLE"))
    4530                 startBlock = endBlock = null;
    4531 
    4532         // Setup new paragraphs
    4533         var paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName);
    4534         var paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName);
    4535 
    4536         // Is header, then force paragraph under
    4537         if (/^(H[1-6])$/.test(blockName))
    4538                 paraAfter = doc.createElement("p");
    4539 
    4540         // Setup chop nodes
    4541         var startChop = startNode;
    4542         var endChop = endNode;
    4543 
    4544         // Get startChop node
    4545         node = startChop;
    4546         do {
    4547                 if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
    4548                         break;
    4549 
    4550                 startChop = node;
    4551         } while ((node = node.previousSibling ? node.previousSibling : node.parentNode));
    4552 
    4553         // Get endChop node
    4554         node = endChop;
    4555         do {
    4556                 if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
    4557                         break;
    4558 
    4559                 endChop = node;
    4560         } while ((node = node.nextSibling ? node.nextSibling : node.parentNode));
    4561 
    4562         // Fix when only a image is within the TD
    4563         if (startChop.nodeName == "TD")
    4564                 startChop = startChop.firstChild;
    4565 
    4566         if (endChop.nodeName == "TD")
    4567                 endChop = endChop.lastChild;
    4568 
    4569         // If not in a block element
    4570         if (startBlock == null) {
    4571                 // Delete selection
    4572                 rng.deleteContents();
    4573                 sel.removeAllRanges();
    4574 
    4575                 if (startChop != rootElm && endChop != rootElm) {
    4576                         // Insert paragraph before
    4577                         rngBefore = rng.cloneRange();
    4578 
    4579                         if (startChop == body)
    4580                                 rngBefore.setStart(startChop, 0);
    4581                         else
    4582                                 rngBefore.setStartBefore(startChop);
    4583 
    4584                         paraBefore.appendChild(rngBefore.cloneContents());
    4585 
    4586                         // Insert paragraph after
    4587                         if (endChop.parentNode.nodeName == blockName)
    4588                                 endChop = endChop.parentNode;
    4589 
    4590                         // If not after image
    4591                         //if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY")
    4592                                 rng.setEndAfter(endChop);
    4593 
    4594                         if (endChop.nodeName != "#text" && endChop.nodeName != "BODY")
    4595                                 rngBefore.setEndAfter(endChop);
    4596 
    4597                         var contents = rng.cloneContents();
    4598                         if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY"))
    4599                                 paraAfter.innerHTML = contents.firstChild.innerHTML;
    4600                         else
    4601                                 paraAfter.appendChild(contents);
    4602 
    4603                         // Check if it's a empty paragraph
    4604                         if (isEmpty(paraBefore))
    4605                                 paraBefore.innerHTML = "&nbsp;";
    4606 
    4607                         // Check if it's a empty paragraph
    4608                         if (isEmpty(paraAfter))
    4609                                 paraAfter.innerHTML = "&nbsp;";
    4610 
    4611                         // Delete old contents
    4612                         rng.deleteContents();
    4613                         rngAfter.deleteContents();
    4614                         rngBefore.deleteContents();
    4615 
    4616                         // Insert new paragraphs
    4617                         paraAfter.normalize();
    4618                         rngBefore.insertNode(paraAfter);
    4619                         paraBefore.normalize();
    4620                         rngBefore.insertNode(paraBefore);
    4621 
    4622                         // tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML);
    4623                 } else {
    4624                         body.innerHTML = "<" + blockName + ">&nbsp;</" + blockName + "><" + blockName + ">&nbsp;</" + blockName + ">";
    4625                         paraAfter = body.childNodes[1];
    4626                 }
    4627 
    4628                 this.selectNode(paraAfter, true, true);
    4629 
    4630                 return true;
    4631         }
    4632 
    4633         // Place first part within new paragraph
    4634         if (startChop.nodeName == blockName)
    4635                 rngBefore.setStart(startChop, 0);
    4636         else
    4637                 rngBefore.setStartBefore(startChop);
    4638 
    4639         rngBefore.setEnd(startNode, startOffset);
    4640         paraBefore.appendChild(rngBefore.cloneContents());
    4641 
    4642         // Place secound part within new paragraph
    4643         rngAfter.setEndAfter(endChop);
    4644         rngAfter.setStart(endNode, endOffset);
    4645         var contents = rngAfter.cloneContents();
    4646 
    4647         if (contents.firstChild && contents.firstChild.nodeName == blockName) {
    4648 /*              var nodes = contents.firstChild.childNodes;
    4649                 for (var i=0; i<nodes.length; i++) {
    4650                         //tinyMCE.debug(nodes[i].nodeName);
    4651                         if (nodes[i].nodeName != "BODY")
    4652                                 paraAfter.appendChild(nodes[i]);
    4653                 }
    4654 */
    4655                 paraAfter.innerHTML = contents.firstChild.innerHTML;
    4656         } else
    4657                 paraAfter.appendChild(contents);
    4658 
    4659         // Check if it's a empty paragraph
    4660         if (isEmpty(paraBefore))
    4661                 paraBefore.innerHTML = "&nbsp;";
    4662 
    4663         // Check if it's a empty paragraph
    4664         if (isEmpty(paraAfter))
    4665                 paraAfter.innerHTML = "&nbsp;";
    4666 
    4667         // Create a range around everything
    4668         var rng = doc.createRange();
    4669 
    4670         if (!startChop.previousSibling && startChop.parentNode.nodeName.toUpperCase() == blockName) {
    4671                 rng.setStartBefore(startChop.parentNode);
    4672         } else {
    4673                 if (rngBefore.startContainer.nodeName.toUpperCase() == blockName && rngBefore.startOffset == 0)
    4674                         rng.setStartBefore(rngBefore.startContainer);
    4675                 else
    4676                         rng.setStart(rngBefore.startContainer, rngBefore.startOffset);
    4677         }
    4678 
    4679         if (!endChop.nextSibling && endChop.parentNode.nodeName.toUpperCase() == blockName)
    4680                 rng.setEndAfter(endChop.parentNode);
    4681         else
    4682                 rng.setEnd(rngAfter.endContainer, rngAfter.endOffset);
    4683 
    4684         // Delete all contents and insert new paragraphs
    4685         rng.deleteContents();
    4686         rng.insertNode(paraAfter);
    4687         rng.insertNode(paraBefore);
    4688         //tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML);
    4689 
    4690         // Normalize
    4691         paraAfter.normalize();
    4692         paraBefore.normalize();
    4693 
    4694         this.selectNode(paraAfter, true, true);
    4695 
    4696         return true;
    4697 };
    4698 
    4699 TinyMCEControl.prototype._handleBackSpace = function(evt_type) {
    4700         var doc = this.getDoc();
    4701         var sel = this.getSel();
    4702         if (sel == null)
    4703                 return false;
    4704 
    4705         var rng = sel.getRangeAt(0);
    4706         var node = rng.startContainer;
    4707         var elm = node.nodeType == 3 ? node.parentNode : node;
    4708 
    4709         if (node == null)
    4710                 return;
    4711 
    4712         // Empty node, wrap contents in paragraph
    4713         if (elm && elm.nodeName == "") {
    4714                 var para = doc.createElement("p");
    4715 
    4716                 while (elm.firstChild)
    4717                         para.appendChild(elm.firstChild);
    4718 
    4719                 elm.parentNode.insertBefore(para, elm);
    4720                 elm.parentNode.removeChild(elm);
    4721 
    4722                 var rng = rng.cloneRange();
    4723                 rng.setStartBefore(node.nextSibling);
    4724                 rng.setEndAfter(node.nextSibling);
    4725                 rng.extractContents();
    4726 
    4727                 this.selectNode(node.nextSibling, true, true);
    4728         }
    4729 
    4730         // Remove empty paragraphs
    4731         var para = tinyMCE.getParentBlockElement(node);
    4732         if (para != null && para.nodeName.toLowerCase() == 'p' && evt_type == "keypress") {
    4733                 var htm = para.innerHTML;
    4734                 var block = tinyMCE.getParentBlockElement(node);
    4735 
    4736                 // Empty node, we do the killing!!
    4737                 if (htm == "" || htm == "&nbsp;" || block.nodeName.toLowerCase() == "li") {
    4738                         var prevElm = para.previousSibling;
    4739 
    4740                         while (prevElm != null && prevElm.nodeType != 1)
    4741                                 prevElm = prevElm.previousSibling;
    4742 
    4743                         if (prevElm == null)
    4744                                 return false;
    4745 
    4746                         // Get previous elements last text node
    4747                         var nodes = tinyMCE.getNodeTree(prevElm, new Array(), 3);
    4748                         var lastTextNode = nodes.length == 0 ? null : nodes[nodes.length-1];
    4749 
    4750                         // Select the last text node and move curstor to end
    4751                         if (lastTextNode != null)
    4752                                 this.selectNode(lastTextNode, true, false, false);
    4753 
    4754                         // Remove the empty paragrapsh
    4755                         para.parentNode.removeChild(para);
    4756 
    4757                         //debug("within p element" + para.innerHTML);
    4758                         //showHTML(this.getBody().innerHTML);
    4759                         return true;
    4760                 }
    4761         }
    4762 
    4763         // Remove BR elements
    4764 /*      while (node != null && (node = node.nextSibling) != null) {
    4765                 if (node.nodeName.toLowerCase() == 'br')
    4766                         node.parentNode.removeChild(node);
    4767                 else if (node.nodeType == 1) // Break at other element
    4768                         break;
    4769         }*/
    4770 
    4771         //showHTML(this.getBody().innerHTML);
    4772 
    4773         return false;
    4774 };
    4775 
    4776 TinyMCEControl.prototype._insertSpace = function() {
    4777         return true;
    4778 };
    4779 
    4780 TinyMCEControl.prototype.autoResetDesignMode = function() {
    4781         // Add fix for tab/style.display none/block problems in Gecko
    4782         if (!tinyMCE.isMSIE && tinyMCE.settings['auto_reset_designmode'] && this.isHidden())
    4783                 eval('try { this.getDoc().designMode = "On"; } catch(e) {}');
    4784 };
    4785 
    4786 TinyMCEControl.prototype.isHidden = function() {
    4787         if (tinyMCE.isMSIE)
    4788                 return false;
    4789 
    4790         var sel = this.getSel();
    4791 
    4792         // Weird, wheres that cursor selection?
    4793         return (!sel || !sel.rangeCount || sel.rangeCount == 0);
    4794 };
    4795 
    4796 TinyMCEControl.prototype.isDirty = function() {
    4797         // Is content modified and not in a submit procedure
    4798         return this.startContent != tinyMCE.trim(this.getBody().innerHTML) && !tinyMCE.isNotDirty;
    4799 };
    4800 
    4801 TinyMCEControl.prototype._mergeElements = function(scmd, pa, ch, override) {
    4802         if (scmd == "removeformat") {
    4803                 pa.className = "";
    4804                 pa.style.cssText = "";
    4805                 ch.className = "";
    4806                 ch.style.cssText = "";
    4807                 return;
    4808         }
    4809 
    4810         var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style"));
    4811         var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style"));
    4812         var className = tinyMCE.getAttrib(pa, "class");
    4813 
    4814         className += " " + tinyMCE.getAttrib(ch, "class");
    4815 
    4816         if (override) {
    4817                 for (var n in st) {
    4818                         if (typeof(st[n]) == 'function')
    4819                                 continue;
    4820 
    4821                         stc[n] = st[n];
    4822                 }
    4823         } else {
    4824                 for (var n in stc) {
    4825                         if (typeof(stc[n]) == 'function')
    4826                                 continue;
    4827 
    4828                         st[n] = stc[n];
    4829                 }
    4830         }
    4831 
    4832         tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st));
    4833         tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className));
    4834         ch.className = "";
    4835         ch.style.cssText = "";
    4836         ch.removeAttribute("class");
    4837         ch.removeAttribute("style");
    4838 };
    4839 
    4840 TinyMCEControl.prototype.setUseCSS = function(b) {
    4841         var doc = this.getDoc();
    4842         try {doc.execCommand("useCSS", false, !b);} catch (ex) {}
    4843         try {doc.execCommand("styleWithCSS", false, b);} catch (ex) {}
    4844 
    4845         if (!tinyMCE.getParam("table_inline_editing"))
    4846                 try {doc.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {}
    4847 
    4848         if (!tinyMCE.getParam("object_resizing"))
    4849                 try {doc.execCommand('enableObjectResizing', false, "false");} catch (ex) {}
    4850 };
    4851 
    4852 TinyMCEControl.prototype.execCommand = function(command, user_interface, value) {
    4853         var doc = this.getDoc();
    4854         var win = this.getWin();
    4855         var focusElm = this.getFocusElement();
    4856 
    4857         if (this.lastSafariSelection && !new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) {
    4858                 this.moveToBookmark(this.lastSafariSelection);
    4859                 tinyMCE.selectedElement = this.lastSafariSelectedElement;
    4860         }
    4861 
    4862         // Mozilla issue
    4863         if (!tinyMCE.isMSIE && !this.useCSS) {
    4864                 this.setUseCSS(false);
    4865                 this.useCSS = true;
    4866         }
    4867 
    4868         //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value);
    4869         this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks
    4870 
    4871         // Call theme execcommand
    4872         if (tinyMCE._themeExecCommand(this.editorId, this.getBody(), command, user_interface, value))
    4873                 return;
    4874 
    4875         // Fix align on images
    4876         if (focusElm && focusElm.nodeName == "IMG") {
    4877                 var align = focusElm.getAttribute('align');
    4878                 var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm;
    4879 
    4880                 switch (command) {
    4881                         case "JustifyLeft":
    4882                                 if (align == 'left')
    4883                                         img.removeAttribute('align');
    4884                                 else
    4885                                         img.setAttribute('align', 'left');
    4886 
    4887                                 // Remove the div
    4888                                 var div = focusElm.parentNode;
    4889                                 if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
    4890                                         div.parentNode.replaceChild(img, div);
    4891 
    4892                                 this.selectNode(img);
    4893                                 this.repaint();
    4894                                 tinyMCE.triggerNodeChange();
    4895                                 return;
    4896 
    4897                         case "JustifyCenter":
    4898                                 img.removeAttribute('align');
    4899 
    4900                                 // Is centered
    4901                                 var div = tinyMCE.getParentElement(focusElm, "div");
    4902                                 if (div && div.style.textAlign == "center") {
    4903                                         // Remove div
    4904                                         if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
    4905                                                 div.parentNode.replaceChild(img, div);
    4906                                 } else {
    4907                                         // Add div
    4908                                         var div = this.getDoc().createElement("div");
    4909                                         div.style.textAlign = 'center';
    4910                                         div.appendChild(img);
    4911                                         focusElm.parentNode.replaceChild(div, focusElm);
    4912                                 }
    4913 
    4914                                 this.selectNode(img);
    4915                                 this.repaint();
    4916                                 tinyMCE.triggerNodeChange();
    4917                                 return;
    4918 
    4919                         case "JustifyRight":
    4920                                 if (align == 'right')
    4921                                         img.removeAttribute('align');
    4922                                 else
    4923                                         img.setAttribute('align', 'right');
    4924 
    4925                                 // Remove the div
    4926                                 var div = focusElm.parentNode;
    4927                                 if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
    4928                                         div.parentNode.replaceChild(img, div);
    4929 
    4930                                 this.selectNode(img);
    4931                                 this.repaint();
    4932                                 tinyMCE.triggerNodeChange();
    4933                                 return;
    4934                 }
    4935         }
    4936 
    4937         if (tinyMCE.settings['force_br_newlines']) {
    4938                 var alignValue = "";
    4939 
    4940                 if (doc.selection.type != "Control") {
    4941                         switch (command) {
    4942                                         case "JustifyLeft":
    4943                                                 alignValue = "left";
    4944                                                 break;
    4945 
    4946                                         case "JustifyCenter":
    4947                                                 alignValue = "center";
    4948                                                 break;
    4949 
    4950                                         case "JustifyFull":
    4951                                                 alignValue = "justify";
    4952                                                 break;
    4953 
    4954                                         case "JustifyRight":
    4955                                                 alignValue = "right";
    4956                                                 break;
    4957                         }
    4958 
    4959                         if (alignValue != "") {
    4960                                 var rng = doc.selection.createRange();
    4961 
    4962                                 if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null)
    4963                                         divElm.setAttribute("align", alignValue);
    4964                                 else if (rng.pasteHTML && rng.htmlText.length > 0)
    4965                                         rng.pasteHTML('<div align="' + alignValue + '">' + rng.htmlText + "</div>");
    4966 
    4967                                 tinyMCE.triggerNodeChange();
    4968                                 return;
    4969                         }
    4970                 }
    4971         }
    4972 
    4973         switch (command) {
    4974                 case "mceRepaint":
    4975                         this.repaint();
    4976                         return true;
    4977 
    4978                 case "mceStoreSelection":
    4979                         this.selectionBookmark = this.getBookmark();
    4980                         return true;
    4981 
    4982                 case "mceRestoreSelection":
    4983                         this.moveToBookmark(this.selectionBookmark);
    4984                         return true;
    4985 
    4986                 case "InsertUnorderedList":
    4987                 case "InsertOrderedList":
    4988                         var tag = (command == "InsertUnorderedList") ? "ul" : "ol";
    4989 
    4990                         if (tinyMCE.isSafari)
    4991                                 this.execCommand("mceInsertContent", false, "<" + tag + "><li>&nbsp;</li><" + tag + ">");
    4992                         else
    4993                                 this.getDoc().execCommand(command, user_interface, value);
    4994 
    4995                         tinyMCE.triggerNodeChange();
    4996                         break;
    4997 
    4998                 case "Strikethrough":
    4999                         if (tinyMCE.isSafari)
    5000                                 this.execCommand("mceInsertContent", false, "<strike>" + this.getSelectedHTML() + "</strike>");
    5001                         else
    5002                                 this.getDoc().execCommand(command, user_interface, value);
    5003 
    5004                         tinyMCE.triggerNodeChange();
    5005                         break;
    5006 
    5007                 case "mceSelectNode":
    5008                         this.selectNode(value);
    5009                         tinyMCE.triggerNodeChange();
    5010                         tinyMCE.selectedNode = value;
    5011                         break;
    5012 
    5013                 case "FormatBlock":
    5014                         if (value == null || value == "") {
    5015                                 var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address");
    5016 
    5017                                 if (elm)
    5018                                         this.execCommand("mceRemoveNode", false, elm);
    5019                         } else
    5020                                 this.getDoc().execCommand("FormatBlock", false, value);
    5021 
    5022                         tinyMCE.triggerNodeChange();
    5023 
    5024                         break;
    5025 
    5026                 case "mceRemoveNode":
    5027                         if (!value)
    5028                                 value = tinyMCE.getParentElement(this.getFocusElement());
    5029 
    5030                         if (tinyMCE.isMSIE) {
    5031                                 value.outerHTML = value.innerHTML;
    5032                         } else {
    5033                                 var rng = value.ownerDocument.createRange();
    5034                                 rng.setStartBefore(value);
    5035                                 rng.setEndAfter(value);
    5036                                 rng.deleteContents();
    5037                                 rng.insertNode(rng.createContextualFragment(value.innerHTML));
    5038                         }
    5039 
    5040                         tinyMCE.triggerNodeChange();
    5041 
    5042                         break;
    5043 
    5044                 case "mceSelectNodeDepth":
    5045                         var parentNode = this.getFocusElement();
    5046                         for (var i=0; parentNode; i++) {
    5047                                 if (parentNode.nodeName.toLowerCase() == "body")
    5048                                         break;
    5049 
    5050                                 if (parentNode.nodeName.toLowerCase() == "#text") {
    5051                                         i--;
    5052                                         parentNode = parentNode.parentNode;
    5053                                         continue;
    5054                                 }
    5055 
    5056                                 if (i == value) {
    5057                                         this.selectNode(parentNode, false);
    5058                                         tinyMCE.triggerNodeChange();
    5059                                         tinyMCE.selectedNode = parentNode;
    5060                                         return;
    5061                                 }
    5062 
    5063                                 parentNode = parentNode.parentNode;
    5064                         }
    5065 
    5066                         break;
    5067 
    5068                 case "SetStyleInfo":
    5069                         var rng = this.getRng();
    5070                         var sel = this.getSel();
    5071                         var scmd = value['command'];
    5072                         var sname = value['name'];
    5073                         var svalue = value['value'] == null ? '' : value['value'];
    5074                         //var svalue = value['value'] == null ? '' : value['value'];
    5075                         var wrapper = value['wrapper'] ? value['wrapper'] : "span";
    5076                         var parentElm = null;
    5077                         var invalidRe = new RegExp("^BODY|HTML$", "g");
    5078                         var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null;
    5079 
    5080                         // Whole element selected check
    5081                         if (tinyMCE.isMSIE) {
    5082                                 // Control range
    5083                                 if (rng.item)
    5084                                         parentElm = rng.item(0);
    5085                                 else {
    5086                                         var pelm = rng.parentElement();
    5087                                         var prng = doc.selection.createRange();
    5088                                         prng.moveToElementText(pelm);
    5089 
    5090                                         if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) {
    5091                                                 if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName))
    5092                                                         parentElm = pelm;
    5093                                         }
    5094                                 }
    5095                         } else {
    5096                                 var felm = this.getFocusElement();
    5097                                 if (sel.isCollapsed || (/td|tr|tbody|table/ig.test(felm.nodeName) && sel.anchorNode == felm.parentNode))
    5098                                         parentElm = felm;
    5099                         }
    5100 
    5101                         // Whole element selected
    5102                         if (parentElm && !invalidRe.test(parentElm.nodeName)) {
    5103                                 if (scmd == "setstyle")
    5104                                         tinyMCE.setStyleAttrib(parentElm, sname, svalue);
    5105 
    5106                                 if (scmd == "setattrib")
    5107                                         tinyMCE.setAttrib(parentElm, sname, svalue);
    5108 
    5109                                 if (scmd == "removeformat") {
    5110                                         parentElm.style.cssText = '';
    5111                                         tinyMCE.setAttrib(parentElm, 'class', '');
    5112                                 }
    5113 
    5114                                 // Remove style/attribs from all children
    5115                                 var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1);
    5116                                 for (var z=0; z<ch.length; z++) {
    5117                                         if (ch[z] == parentElm)
    5118                                                 continue;
    5119 
    5120                                         if (scmd == "setstyle")
    5121                                                 tinyMCE.setStyleAttrib(ch[z], sname, '');
    5122 
    5123                                         if (scmd == "setattrib")
    5124                                                 tinyMCE.setAttrib(ch[z], sname, '');
    5125 
    5126                                         if (scmd == "removeformat") {
    5127                                                 ch[z].style.cssText = '';
    5128                                                 tinyMCE.setAttrib(ch[z], 'class', '');
    5129                                         }
    5130                                 }
    5131                         } else {
    5132                                 doc.execCommand("fontname", false, "#mce_temp_font#");
    5133                                 var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#");
    5134 
    5135                                 // Change them all
    5136                                 for (var x=0; x<elementArray.length; x++) {
    5137                                         elm = elementArray[x];
    5138                                         if (elm) {
    5139                                                 var spanElm = doc.createElement(wrapper);
    5140 
    5141                                                 if (scmd == "setstyle")
    5142                                                         tinyMCE.setStyleAttrib(spanElm, sname, svalue);
    5143 
    5144                                                 if (scmd == "setattrib")
    5145                                                         tinyMCE.setAttrib(spanElm, sname, svalue);
    5146 
    5147                                                 if (scmd == "removeformat") {
    5148                                                         spanElm.style.cssText = '';
    5149                                                         tinyMCE.setAttrib(spanElm, 'class', '');
    5150                                                 }
    5151 
    5152                                                 if (elm.hasChildNodes()) {
    5153                                                         for (var i=0; i<elm.childNodes.length; i++)
    5154                                                                 spanElm.appendChild(elm.childNodes[i].cloneNode(true));
    5155                                                 }
    5156 
    5157                                                 spanElm.setAttribute("mce_new", "true");
    5158                                                 elm.parentNode.replaceChild(spanElm, elm);
    5159 
    5160                                                 // Remove style/attribs from all children
    5161                                                 var ch = tinyMCE.getNodeTree(spanElm, new Array(), 1);
    5162                                                 for (var z=0; z<ch.length; z++) {
    5163                                                         if (ch[z] == spanElm)
    5164                                                                 continue;
    5165 
    5166                                                         if (scmd == "setstyle")
    5167                                                                 tinyMCE.setStyleAttrib(ch[z], sname, '');
    5168 
    5169                                                         if (scmd == "setattrib")
    5170                                                                 tinyMCE.setAttrib(ch[z], sname, '');
    5171 
    5172                                                         if (scmd == "removeformat") {
    5173                                                                 ch[z].style.cssText = '';
    5174                                                                 tinyMCE.setAttrib(ch[z], 'class', '');
    5175                                                         }
    5176                                                 }
    5177                                         }
    5178                                 }
    5179                         }
    5180 
    5181                         // Cleaup wrappers
    5182                         var nodes = doc.getElementsByTagName(wrapper);
    5183                         for (var i=nodes.length-1; i>=0; i--) {
    5184                                 var elm = nodes[i];
    5185                                 var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true";
    5186 
    5187                                 elm.removeAttribute("mce_new");
    5188 
    5189                                 // Is only child a element
    5190                                 if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) {
    5191                                         //tinyMCE.debug("merge1" + isNew);
    5192                                         this._mergeElements(scmd, elm, elm.childNodes[0], isNew);
    5193                                         continue;
    5194                                 }
    5195 
    5196                                 // Is I the only child
    5197                                 if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) {
    5198                                         //tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName);
    5199                                         if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName))
    5200                                                 this._mergeElements(scmd, elm.parentNode, elm, false);
    5201                                 }
    5202                         }
    5203 
    5204                         // Remove empty wrappers
    5205                         var nodes = doc.getElementsByTagName(wrapper);
    5206                         for (var i=nodes.length-1; i>=0; i--) {
    5207                                 var elm = nodes[i];
    5208                                 var isEmpty = true;
    5209 
    5210                                 // Check if it has any attribs
    5211                                 var tmp = doc.createElement("body");
    5212                                 tmp.appendChild(elm.cloneNode(false));
    5213 
    5214                                 // Is empty span, remove it
    5215                                 tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), '');
    5216                                 //tinyMCE.debug(tmp.innerHTML);
    5217                                 if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) {
    5218                                         for (var x=0; x<elm.childNodes.length; x++) {
    5219                                                 if (elm.parentNode != null)
    5220                                                         elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm);
    5221                                         }
    5222 
    5223                                         elm.parentNode.removeChild(elm);
    5224                                 }
    5225                         }
    5226 
    5227                         // Re add the visual aids
    5228                         if (scmd == "removeformat")
    5229                                 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
    5230 
    5231                         tinyMCE.triggerNodeChange();
    5232 
    5233                         break;
    5234 
    5235                 case "FontName":
    5236                         if (value == null) {
    5237                                 var s = this.getSel();
    5238 
    5239                                 // Find font and select it
    5240                                 if (tinyMCE.isGecko && s.isCollapsed) {
    5241                                         var f = tinyMCE.getParentElement(this.getFocusElement(), "font");
    5242 
    5243                                         if (f != null)
    5244                                                 this.selectNode(f, false);
    5245                                 }
    5246 
    5247                                 // Remove format
    5248                                 this.getDoc().execCommand("RemoveFormat", false, null);
    5249 
    5250                                 // Collapse range if font was found
    5251                                 if (f != null && tinyMCE.isGecko) {
    5252                                         var r = this.getRng().cloneRange();
    5253                                         r.collapse(true);
    5254                                         s.removeAllRanges();
    5255                                         s.addRange(r);
    5256                                 }
    5257                         } else
    5258                                 this.getDoc().execCommand('FontName', false, value);
    5259 
    5260                         if (tinyMCE.isGecko)
    5261                                 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
    5262 
    5263                         return;
    5264 
    5265                 case "FontSize":
    5266                         this.getDoc().execCommand('FontSize', false, value);
    5267 
    5268                         if (tinyMCE.isGecko)
    5269                                 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
    5270 
    5271                         return;
    5272 
    5273                 case "forecolor":
    5274                         this.getDoc().execCommand('forecolor', false, value);
    5275                         break;
    5276 
    5277                 case "HiliteColor":
    5278                         if (tinyMCE.isGecko) {
    5279                                 this.setUseCSS(true);
    5280                                 this.getDoc().execCommand('hilitecolor', false, value);
    5281                                 this.setUseCSS(false);
    5282                         } else
    5283                                 this.getDoc().execCommand('BackColor', false, value);
    5284                         break;
    5285 
    5286                 case "Cut":
    5287                 case "Copy":
    5288                 case "Paste":
    5289                         var cmdFailed = false;
    5290 
    5291                         // Try executing command
    5292                         eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}');
    5293 
    5294                         if (tinyMCE.isOpera && cmdFailed)
    5295                                 alert('Currently not supported by your browser, use keyboard shortcuts instead.');
    5296 
    5297                         // Alert error in gecko if command failed
    5298                         if (tinyMCE.isGecko && cmdFailed) {
    5299                                 // Confirm more info
    5300                                 if (confirm(tinyMCE.getLang('lang_clipboard_msg')))
    5301                                         window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
    5302 
    5303                                 return;
    5304                         } else
    5305                                 tinyMCE.triggerNodeChange();
    5306                 break;
    5307 
    5308                 case "mceSetContent":
    5309                         if (!value)
    5310                                 value = "";
    5311 
    5312                         // Call custom cleanup code
    5313                         value = tinyMCE.storeAwayURLs(value);
    5314                         //value = tinyMCE._customCleanup(this, "insert_to_editor", value);
    5315                         tinyMCE._setHTML(doc, value);
    5316                         tinyMCE.setInnerHTML(doc.body, tinyMCE._cleanupHTML(this, doc, tinyMCE.settings, doc.body));
    5317                         this.convertAllRelativeURLs();
    5318                         tinyMCE.handleVisualAid(doc.body, true, this.visualAid, this);
    5319                         tinyMCE._setEventsEnabled(doc.body, false);
    5320                         return true;
    5321 
    5322                 case "mceLink":
    5323                         var selectedText = "";
    5324 
    5325                         if (tinyMCE.isMSIE) {
    5326                                 var rng = doc.selection.createRange();
    5327                                 selectedText = rng.text;
    5328                         } else
    5329                                 selectedText = this.getSel().toString();
    5330 
    5331                         if (!tinyMCE.linkElement) {
    5332                                 if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0))
    5333                                         return;
    5334                         }
    5335 
    5336                         var href = "", target = "", title = "", onclick = "", action = "insert", style_class = "";
    5337 
    5338                         if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a")
    5339                                 tinyMCE.linkElement = tinyMCE.selectedElement;
    5340 
    5341                         // Is anchor not a link
    5342                         if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "")
    5343                                 tinyMCE.linkElement = null;
    5344 
    5345                         if (tinyMCE.linkElement) {
    5346                                 href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href');
    5347                                 target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target');
    5348                                 title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title');
    5349                 onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
    5350                                 style_class = tinyMCE.getAttrib(tinyMCE.linkElement, 'class');
    5351 
    5352                                 // Try old onclick to if copy/pasted content
    5353                                 if (onclick == "")
    5354                                         onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
    5355 
    5356                                 onclick = tinyMCE.cleanupEventStr(onclick);
    5357 
    5358                                 href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
    5359 
    5360                                 // Use mce_href if defined
    5361                                 mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_href');
    5362                                 if (mceRealHref != "") {
    5363                                         href = mceRealHref;
    5364 
    5365                                         if (tinyMCE.getParam('convert_urls'))
    5366                                                 href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
    5367                                 }
    5368 
    5369                                 action = "update";
    5370                         }
    5371 
    5372                         if (this.settings['insertlink_callback']) {
    5373                                 var returnVal = eval(this.settings['insertlink_callback'] + "(href, target, title, onclick, action, style_class);");
    5374                                 if (returnVal && returnVal['href'])
    5375                                         tinyMCE.insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']);
    5376                         } else {
    5377                                 tinyMCE.openWindow(this.insertLinkTemplate, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class, inline : "yes"});
    5378                         }
    5379                 break;
    5380 
    5381                 case "mceImage":
    5382                         var src = "", alt = "", border = "", hspace = "", vspace = "", width = "", height = "", align = "";
    5383                         var title = "", onmouseover = "", onmouseout = "", action = "insert";
    5384                         var img = tinyMCE.imgElement;
    5385 
    5386                         if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") {
    5387                                 img = tinyMCE.selectedElement;
    5388                                 tinyMCE.imgElement = img;
    5389                         }
    5390 
    5391                         if (img) {
    5392                                 // Is it a internal MCE visual aid image, then skip this one.
    5393                                 if (tinyMCE.getAttrib(img, 'name').indexOf('mce_') == 0)
    5394                                         return;
    5395 
    5396                                 src = tinyMCE.getAttrib(img, 'src');
    5397                                 alt = tinyMCE.getAttrib(img, 'alt');
    5398 
    5399                                 // Try polling out the title
    5400                                 if (alt == "")
    5401                                         alt = tinyMCE.getAttrib(img, 'title');
    5402 
    5403                                 // Fix width/height attributes if the styles is specified
    5404                                 if (tinyMCE.isGecko) {
    5405                                         var w = img.style.width;
    5406                                         if (w != null && w != "")
    5407                                                 img.setAttribute("width", w);
    5408 
    5409                                         var h = img.style.height;
    5410                                         if (h != null && h != "")
    5411                                                 img.setAttribute("height", h);
    5412                                 }
    5413 
    5414                                 border = tinyMCE.getAttrib(img, 'border');
    5415                                 hspace = tinyMCE.getAttrib(img, 'hspace');
    5416                                 vspace = tinyMCE.getAttrib(img, 'vspace');
    5417                                 width = tinyMCE.getAttrib(img, 'width');
    5418                                 height = tinyMCE.getAttrib(img, 'height');
    5419                                 align = tinyMCE.getAttrib(img, 'align');
    5420                 onmouseover = tinyMCE.getAttrib(img, 'onmouseover');
    5421                 onmouseout = tinyMCE.getAttrib(img, 'onmouseout');
    5422                 title = tinyMCE.getAttrib(img, 'title');
    5423 
    5424                                 // Is realy specified?
    5425                                 if (tinyMCE.isMSIE) {
    5426                                         width = img.attributes['width'].specified ? width : "";
    5427                                         height = img.attributes['height'].specified ? height : "";
    5428                                 }
    5429 
    5430                                 onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover));
    5431                                 onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout));
    5432 
    5433                                 src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
    5434 
    5435                                 // Use mce_src if defined
    5436                                 mceRealSrc = tinyMCE.getAttrib(img, 'mce_src');
    5437                                 if (mceRealSrc != "") {
    5438                                         src = mceRealSrc;
    5439 
    5440                                         if (tinyMCE.getParam('convert_urls'))
    5441                                                 src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
    5442                                 }
    5443 
    5444                                 if (onmouseover != "")
    5445                                         onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);");
    5446 
    5447                                 if (onmouseout != "")
    5448                                         onmouseout = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, img, true);");
    5449 
    5450                                 action = "update";
    5451                         }
    5452 
    5453                         if (this.settings['insertimage_callback']) {
    5454                                 var returnVal = eval(this.settings['insertimage_callback'] + "(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);");
    5455                                 if (returnVal && returnVal['src'])
    5456                                         tinyMCE.insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']);
    5457                         } else
    5458                                 tinyMCE.openWindow(this.insertImageTemplate, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action, inline : "yes"});
    5459                 break;
    5460 
    5461                 case "mceCleanup":
    5462                         tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML);
    5463                         tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid));
    5464                         this.convertAllRelativeURLs();
    5465                         tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
    5466                         tinyMCE._setEventsEnabled(this.getBody(), false);
    5467                         this.repaint();
    5468                         tinyMCE.triggerNodeChange();
    5469                 break;
    5470 
    5471                 case "mceReplaceContent":
    5472                         this.getWin().focus();
    5473 
    5474                         var selectedText = "";
    5475 
    5476                         if (tinyMCE.isMSIE) {
    5477                                 var rng = doc.selection.createRange();
    5478                                 selectedText = rng.text;
    5479                         } else
    5480                                 selectedText = this.getSel().toString();
    5481 
    5482                         if (selectedText.length > 0) {
    5483                                 value = tinyMCE.replaceVar(value, "selection", selectedText);
    5484                                 tinyMCE.execCommand('mceInsertContent', false, value);
    5485                         }
    5486 
    5487                         tinyMCE.triggerNodeChange();
    5488                 break;
    5489 
    5490                 case "mceSetAttribute":
    5491                         if (typeof(value) == 'object') {
    5492                                 var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets'];
    5493                                 var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms);
    5494 
    5495                                 if (targetNode) {
    5496                                         targetNode.setAttribute(value['name'], value['value']);
    5497                                         tinyMCE.triggerNodeChange();
    5498                                 }
    5499                         }
    5500                 break;
    5501 
    5502                 case "mceSetCSSClass":
    5503                         this.execCommand("SetStyleInfo", false, {command : "setattrib", name : "class", value : value});
    5504                 break;
    5505 
    5506                 case "mceInsertRawHTML":
    5507                         var key = 'tiny_mce_marker';
    5508 
    5509                         this.execCommand('mceBeginUndoLevel');
    5510 
    5511                         // Insert marker key
    5512                         this.execCommand('mceInsertContent', false, key);
    5513 
    5514                         // Store away scroll pos
    5515                         var scrollX = this.getDoc().body.scrollLeft + this.getDoc().documentElement.scrollLeft;
    5516                         var scrollY = this.getDoc().body.scrollTop + this.getDoc().documentElement.scrollTop;
    5517 
    5518                         // Find marker and replace with RAW HTML
    5519                         var html = this.getBody().innerHTML;
    5520                         if ((pos = html.indexOf(key)) != -1)
    5521                                 tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length));
    5522 
    5523                         // Restore scoll pos
    5524                         this.contentWindow.scrollTo(scrollX, scrollY);
    5525 
    5526                         this.execCommand('mceEndUndoLevel');
    5527 
    5528                         break;
    5529 
    5530                 case "mceInsertContent":
    5531                         var insertHTMLFailed = false;
    5532                         this.getWin().focus();
    5533 /* WP
    5534                         if (tinyMCE.isGecko || tinyMCE.isOpera) {
    5535                                 try {
    5536                                         // Is plain text or HTML
    5537                                         if (value.indexOf('<') == -1) {
    5538                                                 var r = this.getRng();
    5539                                                 var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value));
    5540                                                 var s = this.getSel();
    5541                                                 var r2 = r.cloneRange();
    5542 
    5543                                                 // Insert text at cursor position
    5544                                                 s.removeAllRanges();
    5545                                                 r.deleteContents();
    5546                                                 r.insertNode(n);
    5547 
    5548                                                 // Move the cursor to the end of text
    5549                                                 r2.selectNode(n);
    5550                                                 r2.collapse(false);
    5551                                                 s.removeAllRanges();
    5552                                                 s.addRange(r2);
    5553                                         } else {
    5554                                                 value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value);
    5555                                                 this.getDoc().execCommand('inserthtml', false, value);
    5556                                                 tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
    5557                                         }
    5558                                 } catch (ex) {
    5559                                         insertHTMLFailed = true;
    5560                                 }
    5561 
    5562                                 if (!insertHTMLFailed) {
    5563                                         tinyMCE.triggerNodeChange();
    5564                                         return;
    5565                                 }
    5566                         }
    5567 */
    5568                         // Ugly hack in Opera due to non working "inserthtml"
    5569                         if (tinyMCE.isOpera && insertHTMLFailed) {
    5570                                 this.getDoc().execCommand("insertimage", false, tinyMCE.uniqueURL);
    5571                                 var ar = tinyMCE.getElementsByAttributeValue(this.getBody(), "img", "src", tinyMCE.uniqueURL);
    5572                                 ar[0].outerHTML = value;
    5573                                 return;
    5574                         }
    5575 
    5576                         if (!tinyMCE.isMSIE) {
    5577                                 var isHTML = value.indexOf('<') != -1;
    5578                                 var sel = this.getSel();
    5579                                 var rng = this.getRng();
    5580 
    5581                                 if (isHTML) {
    5582                                         if (tinyMCE.isSafari) {
    5583                                                 var tmpRng = this.getDoc().createRange();
    5584 
    5585                                                 tmpRng.setStart(this.getBody(), 0);
    5586                                                 tmpRng.setEnd(this.getBody(), 0);
    5587 
    5588                                                 value = tmpRng.createContextualFragment(value);
    5589                                         } else
    5590                                                 value = rng.createContextualFragment(value);
    5591                                 } else {
    5592                                         // Setup text node
    5593                                         var el = document.createElement("div");
    5594                                         el.innerHTML = value;
    5595                                         value = el.firstChild.nodeValue;
    5596                                         value = doc.createTextNode(value);
    5597                                 }
    5598 
    5599                                 // Insert plain text in Safari
    5600                                 if (tinyMCE.isSafari && !isHTML) {
    5601                                         this.execCommand('InsertText', false, value.nodeValue);
    5602                                         tinyMCE.triggerNodeChange();
    5603                                         return true;
    5604                                 } else if (tinyMCE.isSafari && isHTML) {
    5605                                         rng.deleteContents();
    5606                                         rng.insertNode(value);
    5607                                         tinyMCE.triggerNodeChange();
    5608                                         return true;
    5609                                 }
    5610 
    5611                                 rng.deleteContents();
    5612 
    5613                                 // If target node is text do special treatment, (Mozilla 1.3 fix)
    5614                                 if (rng.startContainer.nodeType == 3) {
    5615                                         var node = rng.startContainer.splitText(rng.startOffset);
    5616                                         node.parentNode.insertBefore(value, node);
    5617                                 } else
    5618                                         rng.insertNode(value);
    5619 
    5620                                 if (!isHTML) {
    5621                                         // Removes weird selection trails
    5622                                         sel.selectAllChildren(doc.body);
    5623                                         sel.removeAllRanges();
    5624 
    5625                                         // Move cursor to end of content
    5626                                         var rng = doc.createRange();
    5627 
    5628                                         rng.selectNode(value);
    5629                                         rng.collapse(false);
    5630 
    5631                                         sel.addRange(rng);
    5632                                 } else
    5633                                         rng.collapse(false);
    5634                         } else {
    5635                                 var rng = doc.selection.createRange();
    5636                                 var c = value.indexOf('<!--') != -1;
    5637 
    5638                                 // Fix comment bug, add tag before comments
    5639                                 if (c)
    5640                                         value = tinyMCE.uniqueTag + value;
    5641 
    5642                                 if (rng.item)
    5643                                         rng.item(0).outerHTML = value;
    5644                                 else
    5645                                         rng.pasteHTML(value);
    5646 
    5647                                 // Remove unique tag
    5648                                 if (c) {
    5649                                         var e = this.getDoc().getElementById('mceTMPElement');
    5650                                         e.parentNode.removeChild(e);
    5651                                 }
    5652                         }
    5653 
    5654                         tinyMCE.triggerNodeChange();
    5655                 break;
    5656 
    5657                 case "mceStartTyping":
    5658                         if (tinyMCE.settings['custom_undo_redo'] && this.typingUndoIndex == -1) {
    5659                                 this.typingUndoIndex = this.undoIndex;
    5660                                 this.execCommand('mceAddUndoLevel');
    5661                                 //tinyMCE.debug("mceStartTyping");
    5662                         }
    5663                         break;
    5664 
    5665                 case "mceEndTyping":
    5666                         if (tinyMCE.settings['custom_undo_redo'] && this.typingUndoIndex != -1) {
    5667                                 this.execCommand('mceAddUndoLevel');
    5668                                 this.typingUndoIndex = -1;
    5669                                 //tinyMCE.debug("mceEndTyping");
    5670                         }
    5671                         break;
    5672 
    5673                 case "mceBeginUndoLevel":
    5674                         this.undoRedo = false;
    5675                         break;
    5676 
    5677                 case "mceEndUndoLevel":
    5678                         this.undoRedo = true;
    5679                         this.execCommand('mceAddUndoLevel');
    5680                         break;
    5681 
    5682                 case "mceAddUndoLevel":
    5683                         if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo) {
    5684                                 // tinyMCE.debug("add level");
    5685 
    5686                                 if (this.typingUndoIndex != -1) {
    5687                                         this.undoIndex = this.typingUndoIndex;
    5688                                         // tinyMCE.debug("Override: " + this.undoIndex);
    5689                                 }
    5690 
    5691                                 var newHTML = tinyMCE.trim(this.getBody().innerHTML);
    5692                                 if (newHTML != this.undoLevels[this.undoIndex]) {
    5693                                         tinyMCE.executeCallback('onchange_callback', '_onchange', 0, this);
    5694 
    5695                                         // Time to compress
    5696                                         var customUndoLevels = tinyMCE.settings['custom_undo_redo_levels'];
    5697                                         if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) {
    5698                                                 for (var i=0; i<this.undoLevels.length-1; i++) {
    5699                                                         //tinyMCE.debug(this.undoLevels[i] + "=" + this.undoLevels[i+1]);
    5700                                                         this.undoLevels[i] = this.undoLevels[i+1];
    5701                                                 }
    5702 
    5703                                                 this.undoLevels.length--;
    5704                                                 this.undoIndex--;
    5705                                         }
    5706 
    5707                                         this.undoIndex++;
    5708                                         this.undoLevels[this.undoIndex] = newHTML;
    5709                                         this.undoLevels.length = this.undoIndex + 1;
    5710 
    5711                                         // tinyMCE.debug("level added" + this.undoIndex);
    5712                                         tinyMCE.triggerNodeChange(false);
    5713 
    5714                                         // tinyMCE.debug(this.undoIndex + "," + (this.undoLevels.length-1));
    5715                                 }
    5716                         }
    5717                         break;
    5718 
    5719                 case "Undo":
    5720                         if (tinyMCE.settings['custom_undo_redo']) {
    5721                                 tinyMCE.execCommand("mceEndTyping");
    5722 
    5723                                 // Do undo
    5724                                 if (this.undoIndex > 0) {
    5725                                         this.undoIndex--;
    5726                                         tinyMCE.setInnerHTML(this.getBody(), this.undoLevels[this.undoIndex]);
    5727                                         this.repaint();
    5728                                 }
    5729 
    5730                                 // tinyMCE.debug("Undo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex);
    5731                                 tinyMCE.triggerNodeChange();
    5732                         } else
    5733                                 this.getDoc().execCommand(command, user_interface, value);
    5734                         break;
    5735 
    5736                 case "Redo":
    5737                         if (tinyMCE.settings['custom_undo_redo']) {
    5738                                 tinyMCE.execCommand("mceEndTyping");
    5739 
    5740                                 if (this.undoIndex < (this.undoLevels.length-1)) {
    5741                                         this.undoIndex++;
    5742                                         tinyMCE.setInnerHTML(this.getBody(), this.undoLevels[this.undoIndex]);
    5743                                         this.repaint();
    5744                                         // tinyMCE.debug("Redo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex);
    5745                                 }
    5746 
    5747                                 tinyMCE.triggerNodeChange();
    5748                         } else
    5749                                 this.getDoc().execCommand(command, user_interface, value);
    5750                         break;
    5751 
    5752                 case "mceToggleVisualAid":
    5753                         this.visualAid = !this.visualAid;
    5754                         tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
    5755                         tinyMCE.triggerNodeChange();
    5756                         break;
    5757 
    5758                 case "Indent":
    5759                         this.getDoc().execCommand(command, user_interface, value);
    5760                         tinyMCE.triggerNodeChange();
    5761                         if (tinyMCE.isMSIE) {
    5762                                 var n = tinyMCE.getParentElement(this.getFocusElement(), "blockquote");
    5763                                 do {
    5764                                         if (n && n.nodeName == "BLOCKQUOTE") {
    5765                                                 n.removeAttribute("dir");
    5766                                                 n.removeAttribute("style");
    5767                                         }
    5768                                 } while (n != null && (n = n.parentNode) != null);
    5769                         }
    5770                         break;
    5771 
    5772                 case "removeformat":
    5773                         var text = this.getSelectedText();
    5774 
    5775                         if (tinyMCE.isOpera) {
    5776                                 this.getDoc().execCommand("RemoveFormat", false, null);
    5777                                 return;
    5778                         }
    5779 
    5780                         if (tinyMCE.isMSIE) {
    5781                                 try {
    5782                                         var rng = doc.selection.createRange();
    5783                                         rng.execCommand("RemoveFormat", false, null);
    5784                                 } catch (e) {
    5785                                         // Do nothing
    5786                                 }
    5787 
    5788                                 this.execCommand("SetStyleInfo", false, {command : "removeformat"});
    5789                         } else {
    5790                                 this.getDoc().execCommand(command, user_interface, value);
    5791 
    5792                                 this.execCommand("SetStyleInfo", false, {command : "removeformat"});
    5793                         }
    5794 
    5795                         // Remove class
    5796                         if (text.length == 0)
    5797                                 this.execCommand("mceSetCSSClass", false, "");
    5798 
    5799                         tinyMCE.triggerNodeChange();
    5800                         break;
    5801 
    5802                 default:
    5803                         this.getDoc().execCommand(command, user_interface, value);
    5804 
    5805                         if (tinyMCE.isGecko)
    5806                                 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
    5807                         else
    5808                                 tinyMCE.triggerNodeChange();
    5809         }
    5810 
    5811         // Add undo level after modification
    5812         if (command != "mceAddUndoLevel" && command != "Undo" && command != "Redo" && command != "mceStartTyping" && command != "mceEndTyping")
    5813                 tinyMCE.execCommand("mceAddUndoLevel");
    5814 };
    5815 
    5816 TinyMCEControl.prototype.queryCommandValue = function(command) {
    5817         try {
    5818                 return this.getDoc().queryCommandValue(command);
    5819         } catch (ex) {
    5820                 return null;
    5821         }
    5822 };
    5823 
    5824 TinyMCEControl.prototype.queryCommandState = function(command) {
    5825         return this.getDoc().queryCommandState(command);
    5826 };
    5827 
    5828 TinyMCEControl.prototype.onAdd = function(replace_element, form_element_name, target_document) {
    5829         var targetDoc = target_document ? target_document : document;
    5830 
    5831         this.targetDoc = targetDoc;
    5832 
    5833         tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme'];
    5834         this.settings['themeurl'] = tinyMCE.themeURL;
    5835 
    5836         if (!replace_element) {
    5837                 alert("Error: Could not find the target element.");
    5838                 return false;
    5839         }
    5840 
    5841         var templateFunction = tinyMCE._getThemeFunction('_getInsertLinkTemplate');
    5842         if (eval("typeof(" + templateFunction + ")") != 'undefined')
    5843                 this.insertLinkTemplate = eval(templateFunction + '(this.settings);');
    5844 
    5845         var templateFunction = tinyMCE._getThemeFunction('_getInsertImageTemplate');
    5846         if (eval("typeof(" + templateFunction + ")") != 'undefined')
    5847                 this.insertImageTemplate = eval(templateFunction + '(this.settings);');
    5848 
    5849         var templateFunction = tinyMCE._getThemeFunction('_getEditorTemplate');
    5850         if (eval("typeof(" + templateFunction + ")") == 'undefined') {
    5851                 alert("Error: Could not find the template function: " + templateFunction);
    5852                 return false;
    5853         }
    5854 
    5855         var editorTemplate = eval(templateFunction + '(this.settings, this.editorId);');
    5856 
    5857         var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0;
    5858         var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0;
    5859         var html = '<span id="' + this.editorId + '_parent">' + editorTemplate['html'];
    5860 
    5861         var templateFunction = tinyMCE._getThemeFunction('_handleNodeChange', true);
    5862         if (eval("typeof(" + templateFunction + ")") != 'undefined')
    5863                 this.settings['handleNodeChangeCallback'] = templateFunction;
    5864 
    5865         html = tinyMCE.replaceVar(html, "editor_id", this.editorId);
    5866         this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm";
    5867 
    5868         this.settings['old_width'] = this.settings['width'];
    5869         this.settings['old_height'] = this.settings['height'];
    5870 
    5871         // Set default width, height
    5872         if (this.settings['width'] == -1)
    5873                 this.settings['width'] = replace_element.offsetWidth;
    5874 
    5875         if (this.settings['height'] == -1)
    5876                 this.settings['height'] = replace_element.offsetHeight;
    5877 
    5878         // Try the style width
    5879         if (this.settings['width'] == 0)
    5880                 this.settings['width'] = replace_element.style.width;
    5881 
    5882         // Try the style height
    5883         if (this.settings['height'] == 0)
    5884                 this.settings['height'] = replace_element.style.height;
    5885 
    5886         // If no width/height then default to 320x240, better than nothing
    5887         if (this.settings['width'] == 0)
    5888                 this.settings['width'] = 320;
    5889 
    5890         if (this.settings['height'] == 0)
    5891                 this.settings['height'] = 240;
    5892 
    5893         this.settings['area_width'] = parseInt(this.settings['width']);
    5894         this.settings['area_height'] = parseInt(this.settings['height']);
    5895         this.settings['area_width'] += deltaWidth;
    5896         this.settings['area_height'] += deltaHeight;
    5897 
    5898         // Special % handling
    5899         if (("" + this.settings['width']).indexOf('%') != -1)
    5900                 this.settings['area_width'] = "100%";
    5901 
    5902         if (("" + this.settings['height']).indexOf('%') != -1)
    5903                 this.settings['area_height'] = "100%";
    5904 
    5905         if (("" + replace_element.style.width).indexOf('%') != -1) {
    5906                 this.settings['width'] = replace_element.style.width;
    5907                 this.settings['area_width'] = "100%";
    5908         }
    5909 
    5910         if (("" + replace_element.style.height).indexOf('%') != -1) {
    5911                 this.settings['height'] = replace_element.style.height;
    5912                 this.settings['area_height'] = "100%";
    5913         }
    5914 
    5915         html = tinyMCE.applyTemplate(html);
    5916 
    5917         this.settings['width'] = this.settings['old_width'];
    5918         this.settings['height'] = this.settings['old_height'];
    5919 
    5920         this.visualAid = this.settings['visual'];
    5921         this.formTargetElementId = form_element_name;
    5922 
    5923         // Get replace_element contents
    5924         if (replace_element.nodeName == "TEXTAREA" || replace_element.nodeName == "INPUT")
    5925                 this.startContent = replace_element.value;
    5926         else
    5927                 this.startContent = replace_element.innerHTML;
    5928 
    5929         // If not text area
    5930         if (replace_element.nodeName.toLowerCase() != "textarea") {
    5931                 this.oldTargetElement = replace_element.cloneNode(true);
    5932 
    5933                 // Debug mode
    5934                 if (tinyMCE.settings['debug'])
    5935                         html += '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>';
    5936                 else
    5937                         html += '<input type="hidden" type="text" id="' + form_element_name + '" name="' + form_element_name + '" />';
    5938 
    5939                 html += '</span>';
    5940 
    5941                 // Output HTML and set editable
    5942                 if (!tinyMCE.isMSIE) {
    5943                         var rng = replace_element.ownerDocument.createRange();
    5944                         rng.setStartBefore(replace_element);
    5945 
    5946                         var fragment = rng.createContextualFragment(html);
    5947                         replace_element.parentNode.replaceChild(fragment, replace_element);
    5948                 } else
    5949                         replace_element.outerHTML = html;
    5950         } else {
    5951                 html += '</span>';
    5952 
    5953                 // Just hide the textarea element
    5954                 this.oldTargetElement = replace_element;
    5955 
    5956                 if (!tinyMCE.settings['debug'])
    5957                         this.oldTargetElement.style.display = "none";
    5958 
    5959                 // Output HTML and set editable
    5960                 if (!tinyMCE.isMSIE) {
    5961                         var rng = replace_element.ownerDocument.createRange();
    5962                         rng.setStartBefore(replace_element);
    5963 
    5964                         var fragment = rng.createContextualFragment(html);
    5965 
    5966                         if (tinyMCE.isGecko)
    5967                                 tinyMCE.insertAfter(fragment, replace_element);
    5968                         else
    5969                                 replace_element.parentNode.insertBefore(fragment, replace_element);
    5970                 } else
    5971                         replace_element.insertAdjacentHTML("beforeBegin", html);
    5972         }
    5973 
    5974         // Setup iframe
    5975         var dynamicIFrame = false;
    5976         var tElm = targetDoc.getElementById(this.editorId);
    5977 
    5978         if (!tinyMCE.isMSIE) {
    5979                 if (tElm && tElm.nodeName.toLowerCase() == "span") {
    5980                         tElm = tinyMCE._createIFrame(tElm);
    5981                         dynamicIFrame = true;
    5982                 }
    5983 
    5984                 this.targetElement = tElm;
    5985                 this.iframeElement = tElm;
    5986                 this.contentDocument = tElm.contentDocument;
    5987                 this.contentWindow = tElm.contentWindow;
    5988 
    5989                 //this.getDoc().designMode = "on";
    5990         } else {
    5991                 if (tElm && tElm.nodeName.toLowerCase() == "span")
    5992                         tElm = tinyMCE._createIFrame(tElm);
    5993                 else
    5994                         tElm = targetDoc.frames[this.editorId];
    5995 
    5996                 this.targetElement = tElm;
    5997                 this.iframeElement = targetDoc.getElementById(this.editorId);
    5998 
    5999                 if (tinyMCE.isOpera) {
    6000                         this.contentDocument = this.iframeElement.contentDocument;
    6001                         this.contentWindow = this.iframeElement.contentWindow;
    6002                         dynamicIFrame = true;
    6003                 } else {
    6004                         this.contentDocument = tElm.window.document;
    6005                         this.contentWindow = tElm.window;
    6006                 }
    6007 
    6008                 this.getDoc().designMode = "on";
    6009         }
    6010 
    6011         // Setup base HTML
    6012         var doc = this.contentDocument;
    6013         if (dynamicIFrame) {
    6014                 var html = tinyMCE.getParam('doctype') + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + tinyMCE.settings['base_href'] + '" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body class="mceContentBody"></body></html>';
    6015 
    6016                 try {
    6017                         if (!this.isHidden())
    6018                                 this.getDoc().designMode = "on";
    6019 
    6020                         doc.open();
    6021                         doc.write(html);
    6022                         doc.close();
    6023                 } catch (e) {
    6024                         // Failed Mozilla 1.3
    6025                         this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm";
    6026                 }
    6027         }
    6028 
    6029         // This timeout is needed in MSIE 5.5 for some odd reason
    6030         // it seems that the document.frames isn't initialized yet?
    6031         if (tinyMCE.isMSIE)
    6032                 window.setTimeout("TinyMCE.prototype.addEventHandlers('" + this.editorId + "');", 1);
    6033 
    6034         tinyMCE.setupContent(this.editorId, true);
    6035 
    6036         return true;
    6037 };
    6038 
    6039 TinyMCEControl.prototype.getFocusElement = function() {
    6040         if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
    6041                 var doc = this.getDoc();
    6042                 var rng = doc.selection.createRange();
    6043 
    6044 //              if (rng.collapse)
    6045 //                      rng.collapse(true);
    6046 
    6047                 var elm = rng.item ? rng.item(0) : rng.parentElement();
    6048         } else {
    6049                 if (this.isHidden())
    6050                         return this.getBody();
    6051 
    6052                 var sel = this.getSel();
    6053                 var rng = this.getRng();
    6054 
    6055                 var elm = rng.commonAncestorContainer;
    6056                 //var elm = (sel && sel.anchorNode) ? sel.anchorNode : null;
    6057 
    6058                 // Handle selection a image or other control like element such as anchors
    6059                 if (!rng.collapsed) {
    6060                         // Is selection small
    6061                         if (rng.startContainer == rng.endContainer) {
    6062                                 if (rng.startOffset - rng.endOffset < 2) {
    6063                                         if (rng.startContainer.hasChildNodes())
    6064                                                 elm = rng.startContainer.childNodes[rng.startOffset];
    6065                                 }
    6066                         }
    6067                 }
    6068 
    6069                 // Get the element parent of the node
    6070                 elm = tinyMCE.getParentElement(elm);
    6071 
    6072                 //if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img")
    6073                 //      elm = tinyMCE.selectedElement;
    6074         }
    6075 
    6076         return elm;
    6077 };
    6078 
    6079 // Global instances
    6080 var tinyMCE = new TinyMCE();
    6081 var tinyMCELang = new Array();
  • trunk/wp-includes/js/tinymce/tiny_mce_gzip.php

    r3623 r3664  
    11<?php
    2         /**
    3          * $RCSfile: tiny_mce_gzip.php,v $
    4          * $Revision: $
    5          * $Date: $
    6          *
    7          * @version 1.02
    8          * @author Moxiecode
    9          * @copyright Copyright © 2005, Moxiecode Systems AB, All rights reserved.
    10          *
    11          * This file compresses the TinyMCE JavaScript using GZip and
    12          * enables the browser to do two requests instead of one for each .js file.
    13          * Notice: This script defaults the button_tile_map option to true for extra performance.
    14          *
    15          * Todo:
    16          *  - Add local file cache for the GZip:ed version.
    17          */
    18 
    19         /* Heavily edited to add flexibilty in WordPress */
    20         @ require('../../../wp-config.php');
    21 
    22         function wp_translate_tinymce_lang($text) {
    23                 if ( ! function_exists('__') ) {
    24                         return $text;
    25                 } else {
    26                         $search1 = "/^tinyMCELang\\[(['\"])(.*)\\1\]( ?= ?)(['\"])(.*)\\4/Uem";
    27                         $replace1 = "'tinyMCELang[\\1\\2\\1]\\3'.stripslashes('\\4').__('\\5').stripslashes('\\4')";
    28 
    29                         $search2 = "/ : (['\"])(.*)\\1/Uem";
    30                         $replace2 = "' : '.stripslashes('\\1').__('\\2').stripslashes('\\1')";
    31 
    32                         $search = array($search1, $search2);
    33                         $replace = array($replace1, $replace2);
    34 
    35                         $text = preg_replace($search, $replace, $text);
    36 
    37                         return $text;
    38                 }
    39         }
    40 
    41         function wp_compact_tinymce_js($text) {
    42                 // This function was custom-made for TinyMCE 2.0, not expected to work with any other JS.
    43 
    44                 // Strip comments
    45                 $text = preg_replace("!(^|\s+)//.*$!m", '', $text);
    46                 $text = preg_replace("!/\*.*?\*/!s", '', $text);
    47 
    48                 // Strip leading tabs, carriage returns and unnecessary line breaks.
    49                 $text = preg_replace("!^\t+!m", '', $text);
    50                 $text = str_replace("\r", '', $text);
    51                 $text = preg_replace("!(^|{|}|;|:|\))\n!m", '\\1', $text);
     2/**
     3 * $RCSfile: tiny_mce_gzip.php,v $
     4 * $Revision: $
     5 * $Date: $
     6 *
     7 * @version 1.07
     8 * @author Moxiecode
     9 * @copyright Copyright © 20052006, Moxiecode Systems AB, All rights reserved.
     10 *
     11 * This file compresses the TinyMCE JavaScript using GZip and
     12 * enables the browser to do two requests instead of one for each .js file.
     13 * Notice: This script defaults the button_tile_map option to true for extra performance.
     14 */
     15
     16@require_once('../../../wp-config.php');
     17
     18gzip_compression();
     19
     20function wp_tinymce_lang($path) {
     21        global $language;
     22
     23        $text = '';
     24
     25        // Look for xx_YY.js, xx_yy.js, xx.js
     26        $file = realpath(sprintf($path, $language));
     27        if ( file_exists($file) )
     28                $text = file_get_contents($file);
     29        $file = realpath(sprintf($path, strtolower($language)));
     30        if ( file_exists($file) )
     31                $text = file_get_contents($file);
     32        $file = realpath(sprintf($path, substr($language, 0, 2)));
     33        if ( file_exists($file) )
     34                $text = file_get_contents($file);
     35
     36
     37        // Fall back on en.js
     38        if ( empty($text) )
     39                $text = file_get_contents(realpath(sprintf($path, 'en')));
     40
     41        // Send lang file through gettext
     42        if ( function_exists('__') && strtolower(substr($language, 0, 2)) != 'en' ) {
     43                $search1 = "/^tinyMCELang\\[(['\"])(.*)\\1\]( ?= ?)(['\"])(.*)\\4/Uem";
     44                $replace1 = "'tinyMCELang[\\1\\2\\1]\\3'.stripslashes('\\4').__('\\5').stripslashes('\\4')";
     45
     46                $search2 = "/\\s:\\s(['\"])(.*)\\1(,|\\s*})/Uem";
     47                $replace2 = "' : '.stripslashes('\\1').__('\\2foo').stripslashes('\\1').'\\3'";
     48
     49                $search = array($search1, $search2);
     50                $replace = array($replace1, $replace2);
     51
     52                $text = preg_replace($search, $replace, $text);
    5253
    5354                return $text;
    5455        }
    5556
    56         // General options
    57         $expiresOffset = 3600 * 24 * 30; // 30 days util client cache expires
    58 
    59         gzip_compression();
    60 
    61         // Output rest of headers
    62         header("Content-type: text/javascript; charset: UTF-8");
    63         header("Vary: Accept-Encoding"); // Handle proxies
    64         header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expiresOffset) . " GMT");
    65 
    66         // Write main script
    67         $tinymce = file_get_contents(realpath("tiny_mce.js"));
    68         echo wp_compact_tinymce_js($tinymce);
    69         echo "\n\n";
    70 
    71         // Remove some functions
    72         echo "\n/* WP cancels all TinyMCE language and import handling */\n";
    73         echo "TinyMCE.prototype.importThemeLanguagePack = function() {};\n";
    74         echo "TinyMCE.prototype.importPluginLanguagePack = function() {};\n\n";
    75         echo "TinyMCE.prototype.loadScript = function() {};\n";
     57        return $text;
     58}
     59
     60function wp_compact_tinymce_js($text) {
     61        // This function was custom-made for TinyMCE 2.0, not expected to work with any other JS.
     62
     63        // Strip comments
     64        $text = preg_replace("!(^|\s+)//.*$!m", '', $text);
     65        $text = preg_replace("!/\*.*?\*/!s", '', $text);
     66
     67        // Strip leading tabs, carriage returns and unnecessary line breaks.
     68        $text = preg_replace("!^\t+!m", '', $text);
     69        $text = str_replace("\r", '', $text);
     70        $text = preg_replace("!(^|{|}|;|:|\))\n!m", '\\1', $text);
     71
     72        return "$text\n";
     73}
     74
     75
     76// General options
     77$suffix = "";                                                   // Set to "_src" to use source version
     78$expiresOffset = 3600 * 24 * 10;                // 10 days util client cache expires
     79$diskCache = false;                                             // If you enable this option gzip files will be cached on disk.
     80$cacheDir = realpath(".");                              // Absolute directory path to where cached gz files will be stored
     81$debug = false;                                                 // Enable this option if you need debuging info
     82
     83// Headers
     84header("Content-type: text/javascript; charset: UTF-8");
     85// header("Cache-Control: must-revalidate");
     86header("Vary: Accept-Encoding"); // Handle proxies
     87header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expiresOffset) . " GMT");
     88
     89// Get data to load
     90$theme = isset($_GET['theme']) ? TinyMCE_cleanInput($_GET['theme']) : "";
     91$language = isset($_GET['language']) ? TinyMCE_cleanInput($_GET['language']) : "";
     92$plugins = isset($_GET['plugins']) ? TinyMCE_cleanInput($_GET['plugins']) : "";
     93$lang = isset($_GET['lang']) ? TinyMCE_cleanInput($_GET['lang']) : "en";
     94$index = isset($_GET['index']) ? TinyMCE_cleanInput($_GET['index']) : -1;
     95$cacheKey = md5($theme . $language . $plugins . $lang . $index . $debug);
     96$cacheFile = $cacheDir == "" ? "" : $cacheDir . "/" . "tinymce_" .  $cacheKey . ".gz";
     97$cacheData = "";
     98
     99// Patch older versions of PHP < 4.3.0
     100if (!function_exists('file_get_contents')) {
     101        function file_get_contents($filename) {
     102                $fd = fopen($filename, 'rb');
     103                $content = fread($fd, filesize($filename));
     104                fclose($fd);
     105                return $content;
     106        }
     107}
     108
     109// Security check function, can only contain a-z 0-9 , _ - and whitespace.
     110function TinyMCE_cleanInput($str) {
     111        return preg_replace("/[^0-9a-z\-_,]+/i", "", $str); // Remove anything but 0-9,a-z,-_
     112}
     113
     114function TinyMCE_echo($str) {
     115        global $cacheData, $diskCache;
     116
     117        if ($diskCache)
     118                $cacheData .= $str;
     119        else
     120                echo $str;
     121}
     122/* WP
     123// Only gzip the contents if clients and server support it
     124$encodings = array();
     125
     126if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
     127        $encodings = explode(',', strtolower(preg_replace("/\s+/", "", $_SERVER['HTTP_ACCEPT_ENCODING'])));
     128
     129// Check for gzip header or northon internet securities
     130if ((in_array('gzip', $encodings) || isset($_SERVER['---------------'])) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression')) {
     131        // Use cached file if it exists but not in debug mode
     132        if (file_exists($cacheFile) && !$debug) {
     133                header("Content-Encoding: gzip");
     134                echo file_get_contents($cacheFile);
     135                die;
     136        }
     137
     138        if (!$diskCache)
     139                ob_start("ob_gzhandler");
     140} else
     141        $diskCache = false;
     142WP */
     143if ($index > -1) {
     144        // Write main script and patch some things
     145        if ($index == 0) {
     146                TinyMCE_echo(wp_compact_tinymce_js(file_get_contents(realpath("tiny_mce" . $suffix . ".js")))); // WP
     147                TinyMCE_echo('TinyMCE.prototype.loadScript = function() {};var realTinyMCE = tinyMCE;');
     148        } else
     149                TinyMCE_echo('tinyMCE = realTinyMCE;');
     150
     151        // Do init based on index
     152        TinyMCE_echo("tinyMCE.init(tinyMCECompressed.configs[" . $index . "]);");
    76153
    77154        // Load theme, language pack and theme language packs
    78         $theme = apply_filters('mce_theme', 'advanced');
    79 
    80         echo wp_compact_tinymce_js(file_get_contents(realpath("themes/" . $theme . "/editor_template.js")));
    81 
    82         // Get the WordPress locale
    83         $locale = get_locale();
    84 
    85         $themeLanguageFile = realpath("themes/" . $theme . "/langs/" . $locale . ".js");
    86 
    87         if (!file_exists($themeLanguageFile))
    88                 $themeLanguageFile = realpath("themes/" . $theme . "/langs/en.js");
    89         echo wp_translate_tinymce_lang(file_get_contents($themeLanguageFile));
    90 
    91         $tinymceLanguageFile = realpath("langs/" . $locale . ".js");
    92 
    93         if (!file_exists($tinymceLanguageFile))
    94                 $tinymceLanguageFile = realpath("langs/en.js");
    95         echo wp_translate_tinymce_lang(file_get_contents($tinymceLanguageFile));
     155        if ($theme) {
     156                TinyMCE_echo(wp_compact_tinymce_js(file_get_contents(realpath("themes/" . $theme . "/editor_template" . $suffix . ".js"))));
     157                TinyMCE_echo(wp_tinymce_lang("themes/" . $theme . "/langs/%s.js")); // WP
     158        }
     159
     160        /* WP if ($language) WP */
     161                TinyMCE_echo(wp_tinymce_lang("langs/%s.js"));
    96162
    97163        // Load all plugins and their language packs
    98         $plugins = apply_filters('mce_plugins', array('wordpress', 'autosave','wphelp'));
    99 
     164        $plugins = explode(",", $plugins);
    100165        foreach ($plugins as $plugin) {
    101                 $pluginFile = realpath("plugins/" . $plugin . "/editor_plugin.js");
    102                 $languageFile = realpath("plugins/" . $plugin . "/langs/" . $locale . ".js");
    103                 if (!file_exists($languageFile))
    104                         $languageFile = realpath("plugins/" . $plugin . "/langs/en.js");
     166                $pluginFile = realpath("plugins/" . $plugin . "/editor_plugin" . $suffix . ".js");
     167                /* WP $languageFile = realpath("plugins/" . $plugin . "/langs/" . $lang . ".js"); WP */
    105168
    106169                if ($pluginFile)
    107                         echo file_get_contents($pluginFile);
    108 
    109                 if ($languageFile)
    110                         echo wp_translate_tinymce_lang(file_get_contents($languageFile));
    111         }
    112 
    113         // Set up init variables
    114         if ( current_user_can('unfiltered_html') ) // Use the full XHTML set provided in the docs
    115                 $valid_elements = 'a[accesskey|charset|class|coords|dir<ltr?rtl|href|hreflang|id|lang|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rel|rev|shape<circle?default?poly?rect|style|tabindex|title|target|type],abbr[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],acronym[class|dir<ltr?rtl|id|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],address[class|align|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],applet[align<bottom?left?middle?right?top|alt|archive|class|code|codebase|height|hspace|id|name|object|style|title|vspace|width],area[accesskey|alt|class|coords|dir<ltr?rtl|href|id|lang|nohref<nohref|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|shape<circle?default?poly?rect|style|tabindex|title|target],base[href|target],basefont[color|face|id|size],bdo[class|dir<ltr?rtl|id|lang|style|title],big[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],blockquote[dir|style|cite|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],body[alink|background|bgcolor|class|dir<ltr?rtl|id|lang|link|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onload|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onunload|style|title|text|vlink],br[class|clear<all?left?none?right|id|style|title],button[accesskey|class|dir<ltr?rtl|disabled<disabled|id|lang|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|tabindex|title|type|value],caption[align<bottom?left?right?top|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],center[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
    116                         . 'cite[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],code[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],col[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|span|style|title|valign<baseline?bottom?middle?top|width],colgroup[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|span|style|title|valign<baseline?bottom?middle?top|width],dd[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],del[cite|class|datetime|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dfn[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dir[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],div[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dl[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dt[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],em/i[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
    117                         . 'fieldset[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],font[class|color|dir<ltr?rtl|face|id|lang|size|style|title],form[accept|accept-charset|action|class|dir<ltr?rtl|enctype|id|lang|method<get?post|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onreset|onsubmit|style|title|target],frame[class|frameborder|id|longdesc|marginheight|marginwidth|name|noresize<noresize|scrolling<auto?no?yes|src|style|title],frameset[class|cols|id|onload|onunload|rows|style|title],h1[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h2[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h3[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h4[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h5[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h6[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],head[dir<ltr?rtl|lang|profile],hr[align<center?left?right|class|dir<ltr?rtl|id|lang|noshade<noshade|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|size|style|title|width],html[dir<ltr?rtl|lang|version],'
    118                         . 'iframe[align<bottom?left?middle?right?top|class|frameborder|height|id|longdesc|marginheight|marginwidth|name|scrolling<auto?no?yes|src|style|title|width],img[align<bottom?left?middle?right?top|alt|border|class|dir<ltr?rtl|height|hspace|id|ismap<ismap|lang|longdesc|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|src|style|title|usemap|vspace|width],input[accept|accesskey|align<bottom?left?middle?right?top|alt|checked<checked|class|dir<ltr?rtl|disabled<disabled|id|ismap<ismap|lang|maxlength|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onselect|readonly<readonly|size|src|style|tabindex|title|type<button?checkbox?file?hidden?image?password?radio?reset?submit?text|usemap|value],ins[cite|class|datetime|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],isindex[class|dir<ltr?rtl|id|lang|prompt|style|title],kbd[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],label[accesskey|class|dir<ltr?rtl|for|id|lang|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],legend[align<bottom?left?right?top|accesskey|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],li[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|type|value],link[charset|class|dir<ltr?rtl|href|hreflang|id|lang|media|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rel|rev|style|title|target|type],map[class|dir<ltr?rtl|id|lang|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
    119                         . 'menu[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],meta[content|dir<ltr?rtl|http-equiv|lang|name|scheme],noframes[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],noscript[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],object[align<bottom?left?middle?right?top|archive|border|class|classid|codebase|codetype|data|declare|dir<ltr?rtl|height|hspace|id|lang|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|standby|style|tabindex|title|type|usemap|vspace|width],ol[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|start|style|title|type],optgroup[class|dir<ltr?rtl|disabled<disabled|id|label|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],option[class|dir<ltr?rtl|disabled<disabled|id|label|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|selected<selected|style|title|value],p[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],param[id|name|type|value|valuetype<DATA?OBJECT?REF],pre/listing/plaintext/xmp[align|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|width],q[cite|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
    120                         . 's[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],samp[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],script[charset|defer|language|src|type],select[class|dir<ltr?rtl|disabled<disabled|id|lang|multiple<multiple|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|size|style|tabindex|title],small[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],span[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],strike[class|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],strong/b[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],style[dir<ltr?rtl|lang|media|title|type],sub[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],sup[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],table[align<center?left?right|bgcolor|border|cellpadding|cellspacing|class|dir<ltr?rtl|frame|height|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rules|style|summary|title|width],'
    121                         . 'tbody[align<center?char?justify?left?right|char|class|charoff|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],td[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rowspan|scope<col?colgroup?row?rowgroup|style|title|valign<baseline?bottom?middle?top|width],textarea[accesskey|class|cols|dir<ltr?rtl|disabled<disabled|id|lang|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onselect|readonly<readonly|rows|style|tabindex|title],tfoot[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],th[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rowspan|scope<col?colgroup?row?rowgroup|style|title|valign<baseline?bottom?middle?top|width],thead[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],'
    122                         . 'title[dir<ltr?rtl|lang],tr[abbr|align<center?char?justify?left?right|bgcolor|char|charoff|class|rowspan|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],tt[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],u[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],ul[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|type],var[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title]';
    123         else // Use a much smaller set
    124                 $valid_elements = '-a[id|href|title|rel],-strong/b,-em/i,-strike,-del,-u,p[class|align|dir],-ol,-ul,-li,br,img[class|src|alt|title|width|height|align],-sub,-sup,-blockquote[dir],-table[border|cellspacing|cellpadding|width|height|class|align|dir],thead[class|rowspan|width|height|align|valign|dir],tr[class|rowspan|width|height|align|valign|dir],th[dir|class|colspan|rowspan|width|height|align|valign|scope],td[dir|class|colspan|rowspan|width|height|align|valign],-div[dir|class|align],-span[class|align],-pre[class],-code[class],-address,-h1[class|align|dir],-h2[class|align|dir],-h3[class|align|dir],-h4[class|align|dir],-h5[class|align|dir],-h6[class|align|dir],hr';
    125         $valid_elements = apply_filters('mce_valid_elements', $valid_elements);
    126         $plugins = implode($plugins, ',');
    127         $mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'separator', 'bullist', 'numlist', 'outdent', 'indent', 'separator', 'justifyleft', 'justifycenter', 'justifyright' ,'separator', 'link', 'unlink', 'image', 'wordpress', 'separator', 'undo', 'redo', 'code', 'wphelp'));
    128         $mce_buttons = implode($mce_buttons, ',');
    129         $mce_buttons_2 = apply_filters('mce_buttons_2', array());
    130         $mce_buttons_2 = implode($mce_buttons_2, ',');
    131         $mce_buttons_3 = apply_filters('mce_buttons_3', array());
    132         $mce_buttons_3 = implode($mce_buttons_3, ',');
    133         $mce_browsers = apply_filters('mce_browsers', array('msie', 'gecko', 'opera'));
    134         $mce_browsers = implode($mce_browsers, ',');
     170                        TinyMCE_echo(file_get_contents($pluginFile));
     171
     172                /* WP if ($languageFile) WP */
     173                        TinyMCE_echo(wp_tinymce_lang("plugins/" . $plugin . "/langs/%s.js")); // WP
     174        }
     175
     176        // Reset tinyMCE compressor engine
     177        TinyMCE_echo("tinyMCE = tinyMCECompressed;");
     178
     179        // Write to cache
     180        if ($diskCache) {
     181                // Calculate compression ratio and debug target output path
     182                if ($debug) {
     183                        $ratio = round(100 - strlen(gzencode($cacheData, 9, FORCE_GZIP)) / strlen($cacheData) * 100.0);
     184                        TinyMCE_echo("alert('TinyMCE was compressed by " . $ratio . "%.\\nOutput cache file: " . $cacheFile . "');");
     185                }
     186
     187                $cacheData = gzencode($cacheData, 9, FORCE_GZIP);
     188
     189                // Write to file if possible
     190                $fp = @fopen($cacheFile, "wb");
     191                if ($fp) {
     192                        fwrite($fp, $cacheData);
     193                        fclose($fp);
     194                }
     195
     196                // Output
     197                header("Content-Encoding: gzip");
     198                echo $cacheData;
     199        }
     200
     201        die;
     202}
    135203?>
    136204
    137 initArray = {
    138         mode : "specific_textareas",
    139         textarea_trigger : "title",
    140         width : "100%",
    141         theme : "advanced",
    142         theme_advanced_buttons1 : "<?php echo $mce_buttons; ?>",
    143         theme_advanced_buttons2 : "<?php echo $mce_buttons_2; ?>",
    144         theme_advanced_buttons3 : "<?php echo $mce_buttons_3; ?>",
    145         theme_advanced_toolbar_location : "top",
    146         theme_advanced_toolbar_align : "left",
    147         theme_advanced_path_location : "bottom",
    148         theme_advanced_resizing : true,
    149         browsers : "<?php echo $mce_browsers; ?>",
    150         dialog_type : "modal",
    151         theme_advanced_resize_horizontal : false,
    152         entity_encoding : "raw",
    153         relative_urls : false,
    154         remove_script_host : false,
    155         force_p_newlines : true,
    156         force_br_newlines : false,
    157         convert_newlines_to_brs : false,
    158         remove_linebreaks : true,
    159         save_callback : "wp_save_callback",
    160         document_base_url : "<?php echo trailingslashit(get_bloginfo('home')); ?>",
    161         valid_elements : "<?php echo $valid_elements; ?>",
    162 <?php do_action('mce_options'); ?>
    163         plugins : "<?php echo $plugins; ?>"
    164 };
    165 
    166 <?php
    167         // For people who really REALLY know what they're doing with TinyMCE
    168         do_action('tinymce_before_init');
    169 ?>
    170 
    171 tinyMCE.init(initArray);
    172 
     205function TinyMCECompressed() {
     206        this.configs = new Array();
     207        this.loadedFiles = new Array();
     208        this.loadAdded = false;
     209        this.isLoaded = false;
     210}
     211
     212TinyMCECompressed.prototype.init = function(settings) {
     213        var elements = document.getElementsByTagName('script');
     214        var scriptURL = "";
     215
     216        for (var i=0; i<elements.length; i++) {
     217                if (elements[i].src && elements[i].src.indexOf("tiny_mce_gzip.php") != -1) {
     218                        scriptURL = elements[i].src;
     219                        break;
     220                }
     221        }
     222
     223        settings["theme"] = typeof(settings["theme"]) != "undefined" ? settings["theme"] : "default";
     224        settings["plugins"] = typeof(settings["plugins"]) != "undefined" ? settings["plugins"] : "";
     225        settings["language"] = typeof(settings["language"]) != "undefined" ? settings["language"] : "en";
     226        settings["button_tile_map"] = typeof(settings["button_tile_map"]) != "undefined" ? settings["button_tile_map"] : true;
     227        this.configs[this.configs.length] = settings;
     228        this.settings = settings;
     229
     230        scriptURL += "?theme=" + escape(this.getOnce(settings["theme"])) + "&language=" + escape(this.getOnce(settings["language"])) + "&plugins=" + escape(this.getOnce(settings["plugins"])) + "&lang=" + settings["language"] + "&index=" + escape(this.configs.length-1);
     231        document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + scriptURL + '"></script>');
     232
     233        if (!this.loadAdded) {
     234                tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCECompressed.prototype.onLoad);
     235                tinyMCE.addEvent(window, "load", TinyMCECompressed.prototype.onLoad);
     236                this.loadAdded = true;
     237        }
     238}
     239
     240TinyMCECompressed.prototype.onLoad = function() {
     241        if (tinyMCE.isLoaded)
     242                return true;
     243
     244        tinyMCE = realTinyMCE;
     245        TinyMCE_Engine.prototype.onLoad();
     246        tinyMCE._addUnloadEvents();
     247        tinyMCE.isLoaded = true;
     248}
     249
     250TinyMCECompressed.prototype.addEvent = function(o, n, h) {
     251        if (o.attachEvent)
     252                o.attachEvent("on" + n, h);
     253        else
     254                o.addEventListener(n, h, false);
     255}
     256
     257TinyMCECompressed.prototype.getOnce = function(str) {
     258        var ar = str.split(',');
     259
     260        for (var i=0; i<ar.length; i++) {
     261                if (ar[i] == '')
     262                        continue;
     263
     264                // Skip load
     265                for (var x=0; x<this.loadedFiles.length; x++) {
     266                        if (this.loadedFiles[x] == ar[i])
     267                                ar[i] = null;
     268                }
     269
     270                this.loadedFiles[this.loadedFiles.length] = ar[i];
     271        }
     272
     273        // Glue
     274        str = "";
     275        for (var i=0; i<ar.length; i++) {
     276                if (ar[i] == null)
     277                        continue;
     278
     279                str += ar[i];
     280
     281                if (i != ar.length-1)
     282                        str += ",";
     283        }
     284
     285        return str;
     286}
     287
     288var tinyMCE = new TinyMCECompressed();
     289var tinyMCECompressed = tinyMCE;
  • trunk/wp-includes/js/tinymce/tiny_mce_popup.js

    r2993 r3664  
    1 /**
    2  * $RCSfile: tiny_mce_popup.js,v $
    3  * $Revision: 1.18 $
    4  * $Date: 2005/10/29 19:13:20 $
    5  *
    6  * @author Moxiecode
    7  * @copyright Copyright © 2004, Moxiecode Systems AB, All rights reserved.
    8  */
    9 
     1
     2
     3// Some global instances, this will be filled later
    104var tinyMCE = null, tinyMCELang = null;
    115
    12 function TinyMCEPopup() {
    13 };
    14 
    15 TinyMCEPopup.prototype.init = function() {
     6
     7function TinyMCE_Popup() {
     8};
     9
     10
     11TinyMCE_Popup.prototype.init = function() {
    1612        var win = window.opener ? window.opener : window.dialogArguments;
    17 
    18         if (!win)
    19                 win = top;
     13        var inst;
     14
     15        if (!win) {
     16                // Try parent
     17                win = parent.parent;
     18
     19                // Try top
     20                if (typeof(win.tinyMCE) == "undefined")
     21                        win = top;
     22        }
    2023
    2124        window.opener = win;
    … …  
    3235        }
    3336
     37        inst = tinyMCE.selectedInstance;
    3438        this.isWindow = tinyMCE.getWindowArg('mce_inside_iframe', false) == false;
    35         this.storeSelection = tinyMCE.isMSIE && !this.isWindow && tinyMCE.getWindowArg('mce_store_selection', true);
     39        this.storeSelection = (tinyMCE.isMSIE && !tinyMCE.isOpera) && !this.isWindow && tinyMCE.getWindowArg('mce_store_selection', true);
    3640
    3741        if (this.isWindow)
    … …  
    4044        // Store selection
    4145        if (this.storeSelection)
    42                 tinyMCE.selectedInstance.execCommand('mceStoreSelection');
     46                inst.selectionBookmark = inst.selection.getBookmark(true);
    4347
    4448        // Setup dir
    … …  
    6468};
    6569
    66 TinyMCEPopup.prototype.onLoad = function() {
    67         var body = document.body;
     70
     71TinyMCE_Popup.prototype.onLoad = function() {
     72        var dir, i, elms, body = document.body;
    6873
    6974        body.onkeydown = function (e) {
    7075                e = e ? e : window.event;
    7176                if ( e.keyCode == 27 && !e.shiftKey && !e.controlKey && !e.altKey ) {
    72                         tinyMCEPopup.close();
     77                        tinyMCE.closeWindow(window);
    7378                }
    7479        }
    … …  
    7782                body.innerHTML = tinyMCE.applyTemplate(body.innerHTML, tinyMCE.windowArgs);
    7883
    79         var dir = tinyMCE.selectedInstance.settings['directionality'];
    80         if (dir == "rtl") {
    81                 var elms = document.forms[0].elements;
    82                 for (var i=0; i<elms.length; i++) {
     84        dir = tinyMCE.selectedInstance.settings['directionality'];
     85        if (dir == "rtl" && document.forms && document.forms.length > 0) {
     86                elms = document.forms[0].elements;
     87                for (i=0; i<elms.length; i++) {
    8388                        if ((elms[i].type == "text" || elms[i].type == "textarea") && elms[i].getAttribute("dir") != "ltr")
    8489                                elms[i].dir = dir;
    … …  
    9095
    9196        // Execute real onload (Opera fix)
    92         if (tinyMCEPopup.onLoadEval != "") {
     97        if (tinyMCEPopup.onLoadEval != "")
    9398                eval(tinyMCEPopup.onLoadEval);
    94         }
    95 };
    96 
    97 TinyMCEPopup.prototype.executeOnLoad = function(str) {
     99};
     100
     101
     102TinyMCE_Popup.prototype.executeOnLoad = function(str) {
    98103        if (tinyMCE.isOpera)
    99104                this.onLoadEval = str;
    … …  
    102107};
    103108
    104 TinyMCEPopup.prototype.resizeToInnerSize = function() {
     109
     110TinyMCE_Popup.prototype.resizeToInnerSize = function() {
    105111        // Netscape 7.1 workaround
    106112        if (this.isWindow && tinyMCE.isNS71) {
    … …  
    119125                // Remove margin
    120126                oldMargin = body.style.margin;
    121                 body.style.margin = '0px';
     127                body.style.margin = '0';
    122128
    123129                // Create wrapper
    … …  
    125131                wrapper.id = 'mcBodyWrapper';
    126132                wrapper.style.display = 'none';
    127                 wrapper.style.margin = '0px';
     133                wrapper.style.margin = '0';
    128134
    129135                // Wrap body elements
    … …  
    147153                iframe.width = "100%";
    148154                iframe.height = "100%";
    149                 iframe.style.margin = '0px';
     155                iframe.style.margin = '0';
    150156
    151157                // Add iframe
    … …  
    168174};
    169175
    170 TinyMCEPopup.prototype.resizeToContent = function() {
     176
     177TinyMCE_Popup.prototype.resizeToContent = function() {
    171178        var isMSIE = (navigator.appName == "Microsoft Internet Explorer");
    172179        var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
    … …  
    198205};
    199206
    200 TinyMCEPopup.prototype.getWindowArg = function(name, default_value) {
     207
     208TinyMCE_Popup.prototype.getWindowArg = function(name, default_value) {
    201209        return tinyMCE.getWindowArg(name, default_value);
    202210};
    203211
    204 TinyMCEPopup.prototype.execCommand = function(command, user_interface, value) {
     212
     213TinyMCE_Popup.prototype.restoreSelection = function() {
     214        if (this.storeSelection) {
     215                var inst = tinyMCE.selectedInstance;
     216
     217                inst.getWin().focus();
     218
     219                if (inst.selectionBookmark)
     220                        inst.selection.moveToBookmark(inst.selectionBookmark);
     221        }
     222};
     223
     224
     225TinyMCE_Popup.prototype.execCommand = function(command, user_interface, value) {
    205226        var inst = tinyMCE.selectedInstance;
    206227
    207         // Restore selection
    208         if (this.storeSelection) {
    209                 inst.getWin().focus();
    210                 inst.execCommand('mceRestoreSelection');
    211         }
    212 
     228        this.restoreSelection();
    213229        inst.execCommand(command, user_interface, value);
    214230
    215231        // Store selection
    216232        if (this.storeSelection)
    217                 inst.execCommand('mceStoreSelection');
    218 };
    219 
    220 TinyMCEPopup.prototype.close = function() {
     233                inst.selectionBookmark = inst.selection.getBookmark(true);
     234};
     235
     236
     237TinyMCE_Popup.prototype.close = function() {
    221238        tinyMCE.closeWindow(window);
    222239};
    223240
    224 TinyMCEPopup.prototype.pickColor = function(e, element_id) {
     241
     242TinyMCE_Popup.prototype.pickColor = function(e, element_id) {
    225243        tinyMCE.selectedInstance.execCommand('mceColorPicker', true, {
    226244                element_id : element_id,
    … …  
    231249};
    232250
    233 TinyMCEPopup.prototype.openBrowser = function(element_id, type, option) {
     251
     252TinyMCE_Popup.prototype.openBrowser = function(element_id, type, option) {
    234253        var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback"));
    235254        var url = document.getElementById(element_id).value;
    … …  
    246265
    247266// Setup global instance
    248 var tinyMCEPopup = new TinyMCEPopup();
     267var tinyMCEPopup = new TinyMCE_Popup();
    249268
    250269tinyMCEPopup.init();
  • trunk/wp-includes/js/tinymce/utils/form_utils.js

    r3163 r3664  
    11/**
    22 * $RCSfile: form_utils.js,v $
    3  * $Revision: 1.5 $
    4  * $Date: 2005/10/25 16:01:51 $
     3 * $Revision: 1.10 $
     4 * $Date: 2006/03/22 12:21:24 $
    55 *
    66 * Various form utilitiy functions.
    77 *
    88 * @author Moxiecode
    9  * @copyright Copyright © 2005, Moxiecode Systems AB, All rights reserved.
     9 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
    1010 */
    1111
    … …  
    1414
    1515        html += '<a id="' + id + '_link" href="javascript:void(0);" onkeydown="pickColor(event,\'' + target_form_element +'\');" onmousedown="pickColor(event,\'' + target_form_element +'\');return false;">';
    16         html += '<img id="' + id + '" src="../../themes/advanced/images/color.gif"';
    17         html += ' onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');"';
    18         html += ' onmouseout="tinyMCE.restoreClass(this);"';
    19         html += ' onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');"';
     16        html += '<img id="' + id + '" src="../../themes/' + tinyMCE.getParam("theme") + '/images/color.gif"';
     17        html += ' onmouseover="this.className=\'mceButtonOver\'"';
     18        html += ' onmouseout="this.className=\'mceButtonNormal\'"';
     19        html += ' onmousedown="this.className=\'mceButtonDown\'"';
    2020        html += ' width="20" height="16" border="0" title="' + tinyMCE.getLang('lang_browse') + '"';
    2121        html += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>';
    … …  
    5858
    5959        html += '<a id="' + id + '_link" href="javascript:openBrower(\'' + id + '\',\'' + target_form_element + '\', \'' + type + '\',\'' + option + '\');" onmousedown="return false;">';
    60         html += '<img id="' + id + '" src="../../themes/advanced/images/browse.gif"';
    61         html += ' onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');"';
    62         html += ' onmouseout="tinyMCE.restoreClass(this);"';
    63         html += ' onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');"';
     60        html += '<img id="' + id + '" src="../../themes/' + tinyMCE.getParam("theme") + '/images/browse.gif"';
     61        html += ' onmouseover="this.className=\'mceButtonOver\';"';
     62        html += ' onmouseout="this.className=\'mceButtonNormal\';"';
     63        html += ' onmousedown="this.className=\'mceButtonDown\';"';
    6464        html += ' width="20" height="18" border="0" title="' + tinyMCE.getLang('lang_browse') + '"';
    6565        html += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>';
    … …  
    7575}
    7676
    77 function selectByValue(form_obj, field_name, value, add_custom) {
     77function selectByValue(form_obj, field_name, value, add_custom, ignore_case) {
    7878        if (!form_obj || !form_obj.elements[field_name])
    7979                return;
    … …  
    8585                var option = sel.options[i];
    8686
    87                 if (option.value == value) {
     87                if (option.value == value || (ignore_case && option.value.toLowerCase() == value.toLowerCase())) {
    8888                        option.selected = true;
    8989                        found = true;
    … …  
    110110}
    111111
     112function addSelectValue(form_obj, field_name, name, value) {
     113        var s = form_obj.elements[field_name];
     114        var o = new Option(name, value);
     115        s.options[s.options.length] = o;
     116}
     117
    112118function addClassesToList(list_id, specific_option) {
    113 return;
    114119        // Setup class droplist
    115120        var styleSelectElm = document.getElementById(list_id);
  • trunk/wp-includes/js/tinymce/utils/mctabs.js

    r2954 r3664  
    11/**
    22 * $RCSfile: mctabs.js,v $
    3  * $Revision: 1.1 $
    4  * $Date: 2005/08/01 18:36:35 $
     3 * $Revision: 1.2 $
     4 * $Date: 2006/02/06 20:11:09 $
    55 *
    66 * Moxiecode DHTML Tabs script.
    77 *
    88 * @author Moxiecode
    9  * @copyright Copyright © 2004, Moxiecode Systems AB, All rights reserved.
     9 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
    1010 */
    1111
  • trunk/wp-includes/js/tinymce/utils/validate.js

    r2954 r3664  
    11/**
    22 * $RCSfile: validate.js,v $
    3  * $Revision: 1.2 $
    4  * $Date: 2005/08/13 12:20:37 $
     3 * $Revision: 1.3 $
     4 * $Date: 2006/02/06 20:11:09 $
    55 *
    66 * Various form validation methods.
    77 *
    88 * @author Moxiecode
    9  * @copyright Copyright © 2005, Moxiecode Systems AB, All rights reserved.
     9 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
    1010 */
    1111
  • trunk/wp-includes/js/tinymce/wp-mce-help.php

    r3517 r3664  
    119119<div id="content1">
    120120        <h2><?php _e('Rich Editing Basics') ?></h2>
    121         <p><?php _e('<em>Rich editing</em>, also called WYSIWYG for What You See Is What You Get, means your text is formatted as you type. The rich editor creates HTML code behind the scenes while you concentrate on writing. Font styles, links and images all appear just as they will on the internet.') ?></p>
    122         <p><?php _e('WordPress includes TinyMCE, a rich editor that works well in most web browsers used today. It is powerful but it has limitations. Pasting text from other word processors may not give the results you expect. If you do not like the way the rich editor works, you may turn it off in the My Profile form, under Users in the admin menu.') ?></p>
    123         <p><?php _e('Because HTML code depends on the less-than character (&lt;) to render web pages, this character is reserved for HTML code. If you want a "<" to be visible on your site, you must encode it as "&amp;lt;" without the quotes.') ?></p>
     121        <p><?php _e('<em>Rich editing</em>, also called WYSIWYG for What You See Is What You Get, means your text is formatted as you type. The rich editor creates HTML code behind the scenes while you concentrate on writing. Font styles, links and images all appear approximately as they will on the internet.') ?></p>
     122        <p><?php _e('WordPress includes a rich HTML editor that works well in most web browsers used today. It is powerful but it has limitations. Pasting text from other word processors may not give the results you expect. If you do not like the way the rich editor works, you may turn it off in the Your Profile and Personal Options form, under Users in the admin menu.') ?></p>
    124123</div>
    125124
    … …  
    127126        <h2><?php _e('Advanced Rich Editing') ?></h2>
    128127        <h3><?php _e('Images and Attachments') ?></h3>
    129         <p><?php _e('Some (not all) browsers allow you to drag images and other items directly into the editor. Most <a href="http://www.mozilla.org/products/firefox/" title="Mozilla.org, home of the Firefox web browser" target="_blank">Firefox</a> users can drag images from the uploading box (directly below the editor) and see their images instantly, complete with a link. If you cannot do this, use your clipboard Copy and Paste functions to insert the image and link tags. The rich editor will display the images after you have saved the post or used the HTML Editor to refresh the display.') ?></p>
     128        <p><?php _e('There is a button in the editor toolbar for inserting images that are already hosted somewhere on the internet. If you have a URL for an image, click this button and enter the URL in the box which appears.') ?></p>
     129        <p><?php _e('If you need to upload an image or sound file from your computer, you can use the uploading tool below the editor. The tool will attempt to create a thumbnail-sized image when you upload an image. To insert your uploaded image into the post, first click on the thumbnail to reveal a menu of options. Clicking on a "Using.." or "Linked..." option will change that option. For instance, you might want to use the thumbnail in the post and link it to a page showing the original with a caption. When you have selected the options you like, click "Send to Editor" and your image or file will appear in the post you are editing.</p>') ?>
    130130        <h3><?php _e('HTML in the Rich Editor') ?></h3>
    131         <p><?php _e('When you want to include HTML elements that are not generated by the toolbar buttons, you must enter it by hand. Examples are &lt;pre> and &lt;code>. Simply type the code into the editor. If the code is valid and allowed by the editor, you should see it rendered the next time you update the display, usually by saving or using the HTML Editor. If you want to display "&lt;" on the web, you must encode it as "&amp;lt;" in the editor.') ?></p>
    132         <h3><?php _e('The HTML Editor') ?></h3>
    133         <p><?php _e('The editor will not always understand your intentions as your editing gets more complex. Use the HTML Editor to sort out any rough spots, such as extra elements or attributes. WordPress will strip all empty &lt;p> tags and &lt;br /> tags in favor of simple newline characters. However, it will preserve any tag such as this: &lt;p class="anyclass">&lt;/p>. When using the HTML editor, all less-thans are double-encoded: &amp;amp;lt;. This ensures they display as &amp;lt; in the rich editor and &lt; on the web.') ?></p>
     131        <p><?php _e('Any HTML entered directly into the rich editor will show up as text when the post is viewed. What you see is what you get. When you want to include HTML elements that cannot be generated with the toolbar buttons, you must enter it by hand in the HTML editor. Examples are tables and &lt;code&gt;. To do this, click the HTML button and edit the code, then click Update. If the code is valid and understood by the editor, you should see it rendered immediately.') ?></p>
    134132</div>
    135133
    … …  
    138136        <p><?php _e('Rather than reaching for your mouse to click on the toolbar, use these access keys. Windows and Linux use Alt+&lt;letter>. Macintosh uses Ctrl+&lt;letter>.') ?></p>
    139137        <table id="keys" width="100%" border="0">
    140                 <tr class="top"><th class="key center"><?php _e('Key') ?></th><th class="left"><?php _e('Action') ?></th><th class="key center"><?php _e('Key') ?></th><th class="left"><?php _e('Action') ?></th></tr>
    141                 <tr><th>b</th><td><strong><?php _e('Bold') ?></strong></td><th>f</th><td class="align left"><?php _e('Align Left') ?></td></tr>
    142                 <tr><th>i</th><td><em><?php _e('Italic') ?></em></td><th>c</th><td class="align center"><?php _e('Align Center') ?></td></tr>
    143                 <tr><th>d</th><td><strike><?php _e('Strikethrough') ?></strike></td><th>r</th><td class="align right"><?php _e('Align Right') ?></td></tr>
     138                <tr class="top"><th class="key center"><?php _e('Letter') ?></th><th class="left"><?php _e('Action') ?></th><th class="key center"><?php _e('Letter') ?></th><th class="left"><?php _e('Action') ?></th></tr>
     139                <tr><th>n</th><td><?php _e('Check Spelling') ?></td><th>f</th><td class="align left"><?php _e('Align Left') ?></td></tr>
     140                <tr><th>j</th><td><?php _e('Justify Text') ?></td><th>c</th><td class="align center"><?php _e('Align Center') ?></td></tr>
     141                <tr><th>k</th><td><strike><?php _e('Strikethrough') ?></strike></td><th>r</th><td class="align right"><?php _e('Align Right') ?></td></tr>
    144142                <tr><th>l</th><td><b>&bull;</b> <?php _e('List') ?></td><th>a</th><td><?php _e('Insert <span class="anchor">Anchor</span>') ?></td></tr>
    145143                <tr><th>o</th><td>1. <?php _e('List') ?></td><th>s</th><td><?php _e('Unlink Anchor') ?></td></tr>
Note: See TracChangeset for help on using the changeset viewer.