Make WordPress Core

Changeset 3664


Ignore:
Timestamp:
03/30/2006 07:50:33 AM (20 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.