Make WordPress Core

Changeset 5577


Ignore:
Timestamp:
05/28/2007 07:30:05 PM (19 years ago)
Author:
rob1n
Message:

Update TinyMCE to 2.1.1.1 (look at all those 1's...). fixes #4262

Location:
trunk/wp-includes
Files:
1 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js

    r5256 r5577  
    11/**
    2  * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
     2 * $Id: editor_plugin_src.js 268 2007-04-28 15:52:59Z spocke $
    33 *
    44 * Moxiecode DHTML Windows script.
     
    8383        pos.absLeft += Math.round((elm.firstChild.clientWidth / 2) - (width / 2));
    8484        pos.absTop += Math.round((elm.firstChild.clientHeight / 2) - (height / 2));
    85 
    86         url += tinyMCE.settings['imp_version'] ? (url.indexOf('?')==-1?'?':'&') + 'ver=' + tinyMCE.settings['imp_version'] : ''; // WordPress cache buster
     85       
     86        // WordPress cache buster
     87        url += tinyMCE.settings['imp_version'] ? (url.indexOf('?')==-1?'?':'&') + 'ver=' + tinyMCE.settings['imp_version'] : '';
    8788
    8889        mcWindows.open(url, mcWindows.idCounter++, "modal=yes,width=" + width+ ",height=" + height + ",resizable=" + resizable + ",scrollbars=" + scrollbars + ",statusbar=" + resizable + ",left=" + pos.absLeft + ",top=" + pos.absTop + ",minWidth=" + minWidth + ",minHeight=" + minHeight );
     
    9192TinyMCE_Engine.prototype.closeWindow = function(win) {
    9293        var gotit = false, n, w;
     94
    9395        for (n in mcWindows.windows) {
    9496                w = mcWindows.windows[n];
    95                 if (typeof(w) == 'function') continue;
     97
     98                if (typeof(w) == 'function')
     99                        continue;
     100
    96101                if (win.name == w.id + '_iframe') {
    97102                        w.close();
     
    99104                }
    100105        }
     106
    101107        if (!gotit)
    102108                this.orgCloseWindow(win);
     
    393399        html += '<head>';
    394400        html += '<title>Wrapper iframe</title>';
     401       
     402        // WordPress: put the window buttons on the left as in Macs
    395403        if (this.isMac) html += '<style type="text/css">.mceWindowTitle{float:none;margin:0;width:100%;text-align:center;}.mceWindowClose{float:none;position:absolute;left:0px;top:0px;}</style>';
     404       
    396405        html += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
    397406        html += '<link href="' + this.getParam("css_file") + '" rel="stylesheet" type="text/css" />';
  • trunk/wp-includes/js/tinymce/themes/advanced/editor_template.js

    r5256 r5577  
    11/**
    2  * $Id: editor_template_src.js 218 2007-02-13 11:08:01Z spocke $
     2 * $Id: editor_template_src.js 256 2007-04-24 09:03:20Z spocke $
    33 *
    44 * @author Moxiecode
     
    141141                        case "|":
    142142                        case "separator":
    143                                 return '<img src="{$themeurl}/images/separator.gif" width="2" height="20" class="mceSeparatorLine" />';
     143                                return '<img src="{$themeurl}/images/separator.gif" width="2" height="20" class="mceSeparatorLine" alt="" />';
    144144
    145145                        case "spacer":
    146                                 return '<img src="{$themeurl}/images/separator.gif" width="2" height="15" border="0" class="mceSeparatorLine" style="vertical-align: middle" />';
     146                                return '<img src="{$themeurl}/images/separator.gif" width="2" height="15" border="0" class="mceSeparatorLine" style="vertical-align: middle" alt="" />';
    147147
    148148                        case "rowseparator":
     
    12431243                if (set_w)
    12441244                        tableElm.style.width = w + "px";
    1245 
     1245               
    12461246                if ( !tinyMCE.isMSIE || tinyMCE.isMSIE7 || tinyMCE.isOpera ) // WordPress: do this later to avoid creeping toolbar bug in MSIE6
    12471247                tableElm.style.height = h + "px";
     
    12521252                iw = iw < 1 ? 30 : iw;
    12531253                ih = ih < 1 ? 30 : ih;
    1254 
    1255 /* WordPress found that this led to a shrinking editor with every resize. (Gray background creeps in 1px at a time.)
     1254/*              WordPress: found that this led to a shrinking editor with every resize.
     1255                        (Gray background creeps in 1px at a time.)
    12561256                if (tinyMCE.isGecko) {
    12571257                        iw -= 2;
     
    12751275                        }
    12761276                }
    1277 
     1277               
    12781278                tableElm.style.height = h + "px"; // WordPress: see above
    12791279
     
    14051405
    14061406                if (tinyMCE.getParam("theme_advanced_more_colors", true))
    1407                         h += '<a href="#" onclick="TinyMCE_AdvancedTheme._pickColor(\'' + id + '\',\'' + cm + '\');" class="mceMoreColors">' + tinyMCE.getLang('lang_more_colors') + '</a>';
     1407                        h += '<a href="javascript:void(0);" onclick="TinyMCE_AdvancedTheme._pickColor(\'' + id + '\',\'' + cm + '\');" class="mceMoreColors">' + tinyMCE.getLang('lang_more_colors') + '</a>';
    14081408
    14091409                return h;
     
    14251425
    14261426        _insertImage : function(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout) {
    1427                 tinyMCE.execCommand('mceBeginUndoLevel');
    1428 
    1429                 if (src == "")
    1430                         return;
    1431 
    1432                 if (!tinyMCE.imgElement && tinyMCE.isSafari) {
    1433                         var html = "";
    1434 
    1435                         html += '<img src="' + src + '" alt="' + alt + '"';
    1436                         html += ' border="' + border + '" hspace="' + hspace + '"';
    1437                         html += ' vspace="' + vspace + '" width="' + width + '"';
    1438                         html += ' height="' + height + '" align="' + align + '" title="' + title + '" onmouseover="' + onmouseover + '" onmouseout="' + onmouseout + '" />';
    1439 
    1440                         tinyMCE.execCommand("mceInsertContent", false, html);
    1441                 } else {
    1442                         if (!tinyMCE.imgElement && tinyMCE.selectedInstance) {
    1443                                 if (tinyMCE.isSafari)
    1444                                         tinyMCE.execCommand("mceInsertContent", false, '<img src="' + tinyMCE.uniqueURL + '" />');
    1445                                 else
    1446                                         tinyMCE.selectedInstance.contentDocument.execCommand("insertimage", false, tinyMCE.uniqueURL);
    1447 
    1448                                 tinyMCE.imgElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "img", "src", tinyMCE.uniqueURL);
    1449                         }
    1450                 }
    1451 
    1452                 if (tinyMCE.imgElement) {
    1453                         var needsRepaint = false;
    1454                         var msrc = src;
    1455 
    1456                         src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, tinyMCE.imgElement);");
    1457 
    1458                         if (tinyMCE.getParam('convert_urls'))
    1459                                 msrc = src;
    1460 
    1461                         if (onmouseover && onmouseover != "")
    1462                                 onmouseover = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, tinyMCE.imgElement);") + "';";
    1463 
    1464                         if (onmouseout && onmouseout != "")
    1465                                 onmouseout = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, tinyMCE.imgElement);") + "';";
    1466 
    1467                         // Use alt as title if it's undefined
    1468                         if (typeof(title) == "undefined")
    1469                                 title = alt;
    1470 
    1471                         if (width != tinyMCE.imgElement.getAttribute("width") || height != tinyMCE.imgElement.getAttribute("height") || align != tinyMCE.imgElement.getAttribute("align"))
    1472                                 needsRepaint = true;
    1473 
    1474                         tinyMCE.setAttrib(tinyMCE.imgElement, 'src', src);
    1475                         tinyMCE.setAttrib(tinyMCE.imgElement, 'mce_src', msrc);
    1476                         tinyMCE.setAttrib(tinyMCE.imgElement, 'alt', alt);
    1477                         tinyMCE.setAttrib(tinyMCE.imgElement, 'title', title);
    1478                         tinyMCE.setAttrib(tinyMCE.imgElement, 'align', align);
    1479                         tinyMCE.setAttrib(tinyMCE.imgElement, 'border', border, true);
    1480                         tinyMCE.setAttrib(tinyMCE.imgElement, 'hspace', hspace, true);
    1481                         tinyMCE.setAttrib(tinyMCE.imgElement, 'vspace', vspace, true);
    1482                         tinyMCE.setAttrib(tinyMCE.imgElement, 'width', width, true);
    1483                         tinyMCE.setAttrib(tinyMCE.imgElement, 'height', height, true);
    1484                         tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseover', onmouseover);
    1485                         tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseout', onmouseout);
    1486 
    1487                         // Fix for bug #989846 - Image resize bug
    1488                         if (width && width != "")
    1489                                 tinyMCE.imgElement.style.pixelWidth = width;
    1490 
    1491                         if (height && height != "")
    1492                                 tinyMCE.imgElement.style.pixelHeight = height;
    1493 
    1494                         if (needsRepaint)
    1495                                 tinyMCE.selectedInstance.repaint();
    1496                 }
    1497 
    1498                 tinyMCE.execCommand('mceEndUndoLevel');
     1427                tinyMCE.execCommand("mceInsertContent", false, tinyMCE.createTagHTML('img', {
     1428                        src : tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src), // Force absolute
     1429                        mce_src : src,
     1430                        alt : alt,
     1431                        border : border,
     1432                        hspace : hspace,
     1433                        vspace : vspace,
     1434                        width : width,
     1435                        height : height,
     1436                        align : align,
     1437                        title : title,
     1438                        onmouseover : onmouseover,
     1439                        onmouseout : onmouseout
     1440                }));
    14991441        },
    15001442
  • trunk/wp-includes/js/tinymce/themes/advanced/image.htm

    r3709 r5577  
    88        <base target="_self" />
    99</head>
     10<!-- WordPress: extra onload stuff is WP -->
    1011<body id="image" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('src').focus();" style="display: none">
    1112<form onsubmit="insertImage();return false;" action="#">
     
    2324            <td><table border="0" cellspacing="0" cellpadding="0">
    2425                <tr>
    25                   <td><input id="src" name="src" type="text" value="" style="width: 200px" onchange="getImageData();"></td>
     26                  <td><input id="src" name="src" type="text" value="" style="width: 200px" onchange="getImageData();" /></td>
    2627                  <td id="srcbrowsercontainer">&nbsp;</td>
    2728                </tr>
     
    4849          <tr>
    4950            <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>
     51            <td><input id="alt" name="alt" type="text" value="" style="width: 200px" /></td>
    5152          </tr>
    5253          <tr>
     
    6768          <tr>
    6869            <td nowrap="nowrap"><label for="width">{$lang_insert_image_dimensions}</label></td>
    69             <td><input id="width" name="width" type="text" value="" size="4" maxlength="4">
     70            <td><input id="width" name="width" type="text" value="" size="3" maxlength="5" />
    7071              x
    71               <input id="height" name="height" type="text" value="" size="4" maxlength="4"></td>
     72              <input id="height" name="height" type="text" value="" size="3" maxlength="5" /></td>
    7273          </tr>
    7374          <tr>
    7475            <td nowrap="nowrap"><label for="border">{$lang_insert_image_border}</label></td>
    75             <td><input id="border" name="border" type="text" value="" size="4" maxlength="4"></td>
     76            <td><input id="border" name="border" type="text" value="" size="3" maxlength="3" /></td>
    7677          </tr>
    7778          <tr>
    7879            <td nowrap="nowrap"><label for="vspace">{$lang_insert_image_vspace}</label></td>
    79             <td><input id="vspace" name="vspace" type="text" value="" size="4" maxlength="4"></td>
     80            <td><input id="vspace" name="vspace" type="text" value="" size="3" maxlength="3" /></td>
    8081          </tr>
    8182          <tr>
    8283            <td nowrap="nowrap"><label for="hspace">{$lang_insert_image_hspace}</label></td>
    83             <td><input id="hspace" name="hspace" type="text" value="" size="4" maxlength="4"></td>
     84            <td><input id="hspace" name="hspace" type="text" value="" size="3" maxlength="3" /></td>
    8485          </tr>
    8586        </table>
     
    8889
    8990        <div class="mceActionPanel">
     91                <!-- WordPress: buttons reversed! -->
    9092                <div style="float: left">
    9193                        <input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/color_picker.js

    r5256 r5577  
    154154        for (i=0; i<colors.length; i++) {
    155155                h += '<td bgcolor="' + colors[i] + '">'
    156                         + '<a href="javascript:selectColor();" onfocus="showColor(\'' + colors[i] +  '\');" onmouseover="showColor(\'' + colors[i] +  '\');">'
     156                        + '<a href="javascript:insertAction();" onfocus="showColor(\'' + colors[i] +  '\');" onmouseover="showColor(\'' + colors[i] +  '\');">'
    157157                        + '<img border="0" src="images/spacer.gif" width="10" height="10" title="' + colors[i] +  '" alt="' + colors[i] +  '" /></a></td>';
    158158                if ((i+1) % 18 == 0)
     
    174174        for (n in named) {
    175175                v = named[n];
    176                 h += '<a href="javascript:selectColor();" onmouseover="showColor(\'' + n +  '\',\'' + v + '\');" style="background-color: ' + n + '"><!-- IE --></a>'
     176                h += '<a href="javascript:insertAction();" onmouseover="showColor(\'' + n +  '\',\'' + v + '\');" style="background-color: ' + n + '"><!-- IE --></a>'
    177177        }
    178178
    179179        el.innerHTML = h;
    180180        el.className = 'generated';
    181 }
    182 
    183 function selectColor() {
    184         var color = document.getElementById("color").value;
    185 
    186         if(window.opener)
    187                 window.opener.tinyMCE.execInstanceCommand(tinyMCE.getWindowArg('editor_id'),tinyMCE.getWindowArg('command'),false,color);
    188 
    189         window.close();
    190181}
    191182
  • trunk/wp-includes/js/tinymce/themes/advanced/jscripts/link.js

    r5256 r5577  
    2525                        option.selected = true;
    2626        }
    27 
     27       
     28        // WordPress -- next 3 lines
    2829        document.forms[0].href.value = tinyMCE.getWindowArg('href') || 'http://';
    2930        document.forms[0].href.select();
    3031        document.forms[0].href.focus();
     32       
    3133        document.forms[0].linktitle.value = tinyMCE.getWindowArg('title');
    3234        document.forms[0].insert.value = tinyMCE.getLang('lang_' + tinyMCE.getWindowArg('action'), 'Insert', true);
     
    5355}
    5456
     57function checkPrefix(n) {
     58        if (Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCE.getLang('lang_is_email')))
     59                n.value = 'mailto:' + n.value;
     60
     61        if (/^\s*www./i.test(n.value) && confirm(tinyMCE.getLang('lang_is_external')))
     62                n.value = 'http://' + n.value;
     63}
     64
    5565function insertLink() {
    5666        var href = document.forms[0].href.value;
     
    6272        // WordPress: Make anchors absolute;
    6373        if (href.charAt(0) == '#')
    64                 href = tinyMCE.settings['document_base_url'] + href;
     74                href = tinyMCE.settings.document_base_url + href;
    6575
    6676        if (target == '_self')
  • trunk/wp-includes/js/tinymce/themes/advanced/langs/en.js

    r5256 r5577  
    8383color_picker_tab : 'Picker',
    8484color_picker : 'Color picker',
    85 web_colors_tab : 'Web safe',
    86 web_colors : 'Web safe colors',
     85web_colors_tab : 'Palette',
     86web_colors : 'Palette colors',
    8787named_colors_tab : 'Named',
    8888named_colors : 'Named colors',
    8989color : 'Color:',
    90 color_name : 'Name:'
     90color_name : 'Name:',
     91is_email : 'The URL you entered seems to be an email address, do you want to add the required mailto: prefix?',
     92is_external : 'The URL you entered seems to external link, do you want to add the required http:// prefix?'
    9193});
  • trunk/wp-includes/js/tinymce/themes/advanced/link.htm

    r3664 r5577  
    55        <script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
    66        <script language="javascript" type="text/javascript" src="../../utils/form_utils.js"></script>
     7        <script language="javascript" type="text/javascript" src="../../utils/validate.js"></script>
    78        <script language="javascript" type="text/javascript" src="jscripts/link.js"></script>
    89        <base target="_self" />
    910</head>
     11<!-- WordPress: onload after the init();'); -->
    1012<body id="link" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('href').focus();" style="display: none">
    1113<form onsubmit="insertLink();return false;" action="#">
     
    2426            <td><table border="0" cellspacing="0" cellpadding="0">
    2527                                  <tr>
    26                                         <td><input id="href" name="href" type="text" value="" style="width: 200px" /></td>
     28                                        <td><input id="href" name="href" type="text" value="" style="width: 200px" onchange="checkPrefix(this);" /></td>
    2729                                        <td id="hrefbrowsercontainer">&nbsp;</td>
    2830                                  </tr>
     
    8890
    8991        <div class="mceActionPanel">
     92                <!-- WordPress: Buttons are reversed! -->
    9093                <div style="float: left">
    9194                        <input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />
  • trunk/wp-includes/js/tinymce/themes/advanced/source_editor.htm

    r4704 r5577  
    77        <base target="_self" />
    88</head>
     9<!-- WordPress: extra onload stuff is WP! -->
    910<body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');document.body.style.display='';document.getElementById('htmlSource').focus();" onresize="resizeInputs();" style="display: none">
    1011        <form name="source" onsubmit="saveContent();" action="#">
     
    1718                <br style="clear: both" />
    1819
    19                 <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>
     20                <textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,monospace; font-size: 12px" dir="ltr" wrap="off"></textarea>
    2021
    2122                <div class="mceActionPanel">
     23                        <!-- WordPress: reversed buttons! -->
    2224                        <div style="float: left">
    2325                                <input type="button" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />
  • trunk/wp-includes/js/tinymce/tiny_mce.js

    r5256 r5577  
    66
    77        this.majorVersion = "2";
    8         this.minorVersion = "1.0";
    9         this.releaseDate = "2007-02-13";
    10 
    11         this.instances = new Array();
    12         this.switchClassCache = new Array();
    13         this.windowArgs = new Array();
    14         this.loadedFiles = new Array();
    15         this.pendingFiles = new Array();
     8        this.minorVersion = "1.1.1";
     9        this.releaseDate = "2007-05-14";
     10
     11        this.instances = [];
     12        this.switchClassCache = [];
     13        this.windowArgs = [];
     14        this.loadedFiles = [];
     15        this.pendingFiles = [];
    1616        this.loadingIndex = 0;
    17         this.configs = new Array();
     17        this.configs = [];
    1818        this.currentConfig = 0;
    19         this.eventHandlers = new Array();
    20         this.log = new Array();
     19        this.eventHandlers = [];
     20        this.log = [];
    2121        this.undoLevels = [];
    2222        this.undoIndex = 0;
    2323        this.typingUndoIndex = -1;
     24        this.settings = [];
    2425
    2526        // Browser check
     
    2930        this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1);
    3031        this.isMSIE7 = this.isMSIE && (ua.indexOf('MSIE 7') != -1);
    31         this.isGecko = ua.indexOf('Gecko') != -1;
     32        this.isGecko = ua.indexOf('Gecko') != -1; // Will also be true on Safari
    3233        this.isSafari = ua.indexOf('Safari') != -1;
    33         this.isOpera = ua.indexOf('Opera') != -1;
     34        this.isOpera = window['opera'] && opera.buildNumber ? true : false;
    3435        this.isMac = ua.indexOf('Mac') != -1;
    3536        this.isNS7 = ua.indexOf('Netscape/7') != -1;
    3637        this.isNS71 = ua.indexOf('Netscape/7.1') != -1;
    3738        this.dialogCounter = 0;
    38         this.plugins = new Array();
    39         this.themes = new Array();
    40         this.menus = new Array();
    41         this.loadedPlugins = new Array();
    42         this.buttonMap = new Array();
     39        this.plugins = [];
     40        this.themes = [];
     41        this.menus = [];
     42        this.loadedPlugins = [];
     43        this.buttonMap = [];
    4344        this.isLoaded = false;
    4445
     
    5960TinyMCE_Engine.prototype = {
    6061        init : function(settings) {
    61                 var theme, nl, baseHREF = "", i;
     62                var theme, nl, baseHREF = "", i, cssPath, entities, h, p, src, elements = [], head;
    6263
    6364                // IE 5.0x is no longer supported since 5.5, 6.0 and 7.0 now exists. We can't support old browsers forever, sorry.
     
    7374                // Get script base path
    7475                if (!tinyMCE.baseURL) {
    75                         var elements = document.getElementsByTagName('script');
     76                        // Search through head
     77                        head = document.getElementsByTagName('head')[0];
     78
     79                        if (head) {
     80                                for (i=0, nl = head.getElementsByTagName('script'); i<nl.length; i++)
     81                                        elements.push(nl[i]);
     82                        }
     83
     84                        // Search through rest of document
     85                        for (i=0, nl = document.getElementsByTagName('script'); i<nl.length; i++)
     86                                elements.push(nl[i]);
    7687
    7788                        // If base element found, add that infront of baseURL
     
    8293                        }
    8394
    84                         for (var i=0; i<elements.length; i++) {
     95                        for (i=0; i<elements.length; i++) {
    8596                                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)) {
    86                                         var src = elements[i].src;
     97                                        src = elements[i].src;
    8798
    8899                                        tinyMCE.srcMode = (src.indexOf('_src') != -1 || src.indexOf('_dev') != -1) ? '_src' : '';
     
    94105
    95106                                        // Force it absolute if page has a base href
    96                                         if (baseHREF != "" && src.indexOf('://') == -1)
     107                                        if (baseHREF !== '' && src.indexOf('://') == -1)
    97108                                                tinyMCE.baseURL = baseHREF + src;
    98109                                        else
     
    122133                this._def("plugins", "", true);
    123134                this._def("language", "en");
    124                 this._def("docs_language", this.settings['language']);
     135                this._def("docs_language", this.settings.language);
    125136                this._def("elements", "");
    126137                this._def("textarea_trigger", "mce_editable");
     
    133144                this._def("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE_Engine.prototype.convertURL"));
    134145                this._def("save_callback", "");
    135                 this._def("debug", false);
    136146                this._def("force_br_newlines", false);
    137147                this._def("force_p_newlines", true);
     
    194204                this._def("gecko_spellcheck", false);
    195205                this._def("hide_selects_on_submit", true);
     206                this._def("forced_root_block", false);
     207                this._def("remove_trailing_nbsp", false);
    196208
    197209                // Force strict loading mode to false on non Gecko browsers
     
    200212
    201213                // Browser check IE
    202                 if (this.isMSIE && this.settings['browsers'].indexOf('msie') == -1)
     214                if (this.isMSIE && this.settings.browsers.indexOf('msie') == -1)
    203215                        return;
    204216
    205217                // Browser check Gecko
    206                 if (this.isGecko && this.settings['browsers'].indexOf('gecko') == -1)
     218                if (this.isGecko && this.settings.browsers.indexOf('gecko') == -1)
    207219                        return;
    208220
    209221                // Browser check Safari
    210                 if (this.isSafari && this.settings['browsers'].indexOf('safari') == -1)
     222                if (this.isSafari && this.settings.browsers.indexOf('safari') == -1)
    211223                        return;
    212224
    213225                // Browser check Opera
    214                 if (this.isOpera && this.settings['browsers'].indexOf('opera') == -1)
     226                if (this.isOpera && this.settings.browsers.indexOf('opera') == -1)
    215227                        return;
    216228
    217229                // If not super absolute make it so
    218                 baseHREF = tinyMCE.settings['document_base_url'];
    219                 var h = document.location.href;
    220                 var p = h.indexOf('://');
     230                baseHREF = tinyMCE.settings.document_base_url;
     231                h = document.location.href;
     232                p = h.indexOf('://');
    221233                if (p > 0 && document.location.protocol != "file:") {
    222234                        p = h.indexOf('/', p + 3);
     
    226238                                baseHREF = h + baseHREF;
    227239
    228                         tinyMCE.settings['document_base_url'] = baseHREF;
    229                         tinyMCE.settings['document_base_prefix'] = h;
     240                        tinyMCE.settings.document_base_url = baseHREF;
     241                        tinyMCE.settings.document_base_prefix = h;
    230242                }
    231243
     
    234246                        baseHREF = baseHREF.substring(0, baseHREF.indexOf('?'));
    235247
    236                 this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";
    237 
    238                 theme = this.settings['theme'];
     248                this.settings.base_href = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";
     249
     250                theme = this.settings.theme;
    239251                this.inlineStrict = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment';
    240252                this.inlineTransitional = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment';
    241                 this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';
     253                this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';
    242254                this.blockRegExp = new RegExp("^(" + this.blockElms + ")$", "i");
    243                 this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40);
     255                this.posKeyCodes = [13,45,36,35,33,34,37,38,39,40];
    244256                this.uniqueURL = 'javascript:void(091039730);'; // Make unique URL non real URL
    245257                this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>';
    246                 this.callbacks = new Array('onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance');
     258                this.callbacks = ['onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance'];
    247259
    248260                // Theme url
    249                 this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme;
     261                this.settings.theme_href = tinyMCE.baseURL + "/themes/" + theme;
    250262
    251263                if (!tinyMCE.isIE || tinyMCE.isOpera)
    252                         this.settings['force_br_newlines'] = false;
     264                        this.settings.force_br_newlines = false;
    253265
    254266                if (tinyMCE.getParam("popups_css", false)) {
    255                         var cssPath = tinyMCE.getParam("popups_css", "");
     267                        cssPath = tinyMCE.getParam("popups_css", "");
    256268
    257269                        // Is relative
    258270                        if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
    259                                 this.settings['popups_css'] = this.documentBasePath + "/" + cssPath;
     271                                this.settings.popups_css = this.documentBasePath + "/" + cssPath;
    260272                        else
    261                                 this.settings['popups_css'] = cssPath;
     273                                this.settings.popups_css = cssPath;
    262274                } else
    263                         this.settings['popups_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css";
     275                        this.settings.popups_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css";
    264276
    265277                if (tinyMCE.getParam("editor_css", false)) {
    266                         var cssPath = tinyMCE.getParam("editor_css", "");
     278                        cssPath = tinyMCE.getParam("editor_css", "");
    267279
    268280                        // Is relative
    269281                        if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
    270                                 this.settings['editor_css'] = this.documentBasePath + "/" + cssPath;
     282                                this.settings.editor_css = this.documentBasePath + "/" + cssPath;
    271283                        else
    272                                 this.settings['editor_css'] = cssPath;
     284                                this.settings.editor_css = cssPath;
    273285                } else {
    274                         if (this.settings.editor_css != '')
    275                                 this.settings['editor_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css";
    276                 }
    277 
    278                 if (tinyMCE.settings['debug']) {
    279                         var msg = "Debug: \n";
    280 
    281                         msg += "baseURL: " + this.baseURL + "\n";
    282                         msg += "documentBasePath: " + this.documentBasePath + "\n";
    283                         msg += "content_css: " + this.settings['content_css'] + "\n";
    284                         msg += "popups_css: " + this.settings['popups_css'] + "\n";
    285                         msg += "editor_css: " + this.settings['editor_css'] + "\n";
    286 
    287                         alert(msg);
     286                        if (this.settings.editor_css !== '')
     287                                this.settings.editor_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css";
    288288                }
    289289
     
    305305                }
    306306
    307                 this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings['theme'] + '/editor_template' + tinyMCE.srcMode + '.js');
    308                 this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings['language'] +  '.js');
    309                 this.loadCSS(this.settings['editor_css']);
     307                this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings.theme + '/editor_template' + tinyMCE.srcMode + '.js');
     308                this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings.language +  '.js');
     309                this.loadCSS(this.settings.editor_css);
    310310
    311311                // Add plugins
    312                 var p = tinyMCE.getParam('plugins', '', true, ',');
     312                p = tinyMCE.getParam('plugins', '', true, ',');
    313313                if (p.length > 0) {
    314                         for (var i=0; i<p.length; i++) {
     314                        for (i=0; i<p.length; i++) {
    315315                                if (p[i].charAt(0) != '-')
    316316                                        this.loadScript(tinyMCE.baseURL + '/plugins/' + p[i] + '/editor_plugin' + tinyMCE.srcMode + '.js');
     
    320320                // Setup entities
    321321                if (tinyMCE.getParam('entity_encoding') == 'named') {
    322                         settings['cleanup_entities'] = new Array();
    323                         var entities = tinyMCE.getParam('entities', '', true, ',');
    324                         for (var i=0; i<entities.length; i+=2)
    325                                 settings['cleanup_entities']['c' + entities[i]] = entities[i+1];
     322                        settings.cleanup_entities = [];
     323                        entities = tinyMCE.getParam('entities', '', true, ',');
     324                        for (i=0; i<entities.length; i+=2)
     325                                settings.cleanup_entities['c' + entities[i]] = entities[i+1];
    326326                }
    327327
    328328                // Save away this config
    329                 settings['index'] = this.configs.length;
     329                settings.index = this.configs.length;
    330330                this.configs[this.configs.length] = settings;
    331331
     
    338338                                document.execCommand('BackgroundImageCache', false, true);
    339339                        } catch (e) {
     340                                // Ignore
    340341                        }
    341342                }
    342343
    343344                // Setup XML encoding regexps
    344                 this.xmlEncodeAposRe = new RegExp('[<>&"\']', 'g');
    345345                this.xmlEncodeRe = new RegExp('[<>&"]', 'g');
    346 //              this.xmlEncodeEnts = {'&':'&amp;','"':'&quot;',"'":'&#39;','<':'&lt;','>':'&gt;'};
    347346        },
    348347
    349348        _addUnloadEvents : function() {
     349                var st = tinyMCE.settings.add_unload_trigger;
     350
    350351                if (tinyMCE.isIE) {
    351                         if (tinyMCE.settings['add_unload_trigger']) {
     352                        if (st) {
    352353                                tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler);
    353354                                tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler);
    354355                        }
    355356                } else {
    356                         if (tinyMCE.settings['add_unload_trigger'])
     357                        if (st)
    357358                                tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);});
    358359                }
     
    450451        loadCSS : function(url) {
    451452                var ar = url.replace(/\s+/, '').split(',');
    452                 var lflen = 0, csslen = 0;
    453                 var skip = false;
     453                var lflen = 0, csslen = 0, skip = false;
    454454                var x = 0, i = 0, nl, le;
    455455
     
    515515                tinyMCE.settings = settings;
    516516
    517                 if (tinyMCE.settings['convert_on_click'] || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm'])))
     517                if (tinyMCE.settings.convert_on_click || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang.lang_edit_confirm)))
    518518                        tinyMCE.addMCEControl(elm, elementId);
    519519
     
    522522
    523523        updateContent : function(form_element_name) {
     524                var formElement, n, inst, doc;
     525
    524526                // Find MCE instance linked to given form element and copy it's value
    525                 var formElement = document.getElementById(form_element_name);
    526                 for (var n in tinyMCE.instances) {
    527                         var inst = tinyMCE.instances[n];
     527                formElement = document.getElementById(form_element_name);
     528                for (n in tinyMCE.instances) {
     529                        inst = tinyMCE.instances[n];
     530
    528531                        if (!tinyMCE.isInstance(inst))
    529532                                continue;
     
    532535
    533536                        if (inst.formElement == formElement) {
    534                                 var doc = inst.getDoc();
    535                
     537                                doc = inst.getDoc();
     538
    536539                                tinyMCE._setHTML(doc, inst.formElement.value);
    537540
     
    682685
    683686        execCommand : function(command, user_interface, value) {
    684                 var inst = tinyMCE.selectedInstance;
     687                var inst = tinyMCE.selectedInstance, n, pe, te;
    685688
    686689                // Default input
     
    722725
    723726                        case 'mceFocus':
    724                                 var inst = tinyMCE.getInstanceById(value);
     727                                inst = tinyMCE.getInstanceById(value);
     728
    725729                                if (inst)
    726730                                        inst.getWin().focus();
     
    733737
    734738                        case "mceAddFrameControl":
    735                                 tinyMCE.addMCEControl(tinyMCE._getElementById(value['element'], value['document']), value['element'], value['document']);
     739                                tinyMCE.addMCEControl(tinyMCE._getElementById(value.element, value.document), value.element, value.document);
    736740                                return;
    737741
     
    742746
    743747                        case "mceToggleEditor":
    744                                 var inst = tinyMCE.getInstanceById(value), pe, te;
     748                                inst = tinyMCE.getInstanceById(value);
    745749
    746750                                if (inst) {
     
    755759                                        if (!inst.enabled) {
    756760                                                pe.style.display = 'none';
    757                                                 te.value = inst.getHTML();
     761
     762                                                if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT')
     763                                                        te.value = inst.getHTML();
     764                                                else
     765                                                        te.innerHTML = inst.getHTML();
     766
    758767                                                te.style.display = inst.oldTargetDisplay;
    759768                                                tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst);
     
    761770                                                pe.style.display = 'block';
    762771                                                te.style.display = 'none';
    763                                                 inst.setHTML(te.value);
     772
     773                                                if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT')
     774                                                        inst.setHTML(te.value);
     775                                                else
     776                                                        inst.setHTML(te.innerHTML);
     777
    764778                                                inst.useCSS = false;
    765779                                                tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst);
     
    772786                        case "mceResetDesignMode":
    773787                                // Resets the designmode state of the editors in Gecko
    774                                 if (!tinyMCE.isIE) {
    775                                         for (var n in tinyMCE.instances) {
     788                                if (tinyMCE.isGecko) {
     789                                        for (n in tinyMCE.instances) {
    776790                                                if (!tinyMCE.isInstance(tinyMCE.instances[n]))
    777791                                                        continue;
    778792
    779793                                                try {
     794                                                        tinyMCE.instances[n].getDoc().designMode = "off";
    780795                                                        tinyMCE.instances[n].getDoc().designMode = "on";
     796                                                        tinyMCE.instances[n].useCSS = false;
    781797                                                } catch (e) {
    782798                                                        // Ignore any errors
     
    790806                if (inst) {
    791807                        inst.execCommand(command, user_interface, value);
    792                 } else if (tinyMCE.settings['focus_alert'])
    793                         alert(tinyMCELang['lang_focus_alert']);
     808                } else if (tinyMCE.settings.focus_alert)
     809                        alert(tinyMCELang.lang_focus_alert);
    794810        },
    795811
     
    806822                iframe = doc.createElement("iframe");
    807823
    808                 aw = "" + tinyMCE.settings['area_width'];
    809                 ah = "" + tinyMCE.settings['area_height'];
     824                aw = "" + tinyMCE.settings.area_width;
     825                ah = "" + tinyMCE.settings.area_height;
    810826
    811827                if (aw.indexOf('%') == -1) {
     
    835851                iframe.className = 'mceEditorIframe';
    836852
    837                 if (tinyMCE.settings["auto_resize"])
     853                if (tinyMCE.settings.auto_resize)
    838854                        iframe.setAttribute("scrolling", "no");
    839855
    840856                // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs
    841857                if (tinyMCE.isRealIE)
    842                         iframe.setAttribute("src", this.settings['default_document']);
     858                        iframe.setAttribute("src", this.settings.default_document);
    843859
    844860                iframe.style.width = aw;
     
    862878
    863879        setupContent : function(editor_id) {
    864                 var inst = tinyMCE.instances[editor_id], i;
    865                 var doc = inst.getDoc();
    866                 var head = doc.getElementsByTagName('head').item(0);
    867                 var content = inst.startContent;
     880                var inst = tinyMCE.instances[editor_id], i, doc = inst.getDoc(), head = doc.getElementsByTagName('head').item(0);
     881                var content = inst.startContent, contentElement, body;
    868882
    869883                // HTML values get XML encoded in strict mode
     
    887901                }
    888902
    889                 if (!head) {
     903                // Wait for it to load
     904                if (!head || !doc.body) {
    890905                        window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10);
    891906                        return;
     
    893908
    894909                // Import theme specific content CSS the user specific
    895                 tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css");
    896                 tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']);
     910                tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings.theme + "/css/editor_content.css");
     911                tinyMCE.importCSS(inst.getDoc(), inst.settings.content_css);
    897912                tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst);
    898913
     
    922937                        inst.getBody().setAttribute('id', 'mceSpanFonts');
    923938
    924                 if (tinyMCE.settings['nowrap'])
     939                if (tinyMCE.settings.nowrap)
    925940                        doc.body.style.whiteSpace = "nowrap";
    926941
    927                 doc.body.dir = this.settings['directionality'];
     942                doc.body.dir = this.settings.directionality;
    928943                doc.editorId = editor_id;
    929944
     
    932947                        doc.documentElement.editorId = editor_id;
    933948
    934                 inst.setBaseHREF(tinyMCE.settings['base_href']);
     949                inst.setBaseHREF(tinyMCE.settings.base_href);
    935950
    936951                // Replace new line characters to BRs
    937                 if (tinyMCE.settings['convert_newlines_to_brs']) {
     952                if (tinyMCE.settings.convert_newlines_to_brs) {
    938953                        content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi");
    939954                        content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi");
     
    952967                        window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500);
    953968
    954                         if (tinyMCE.settings["force_br_newlines"])
     969                        if (tinyMCE.settings.force_br_newlines)
    955970                                doc.styleSheets[0].addRule("p", "margin: 0;");
    956971
    957                         var body = inst.getBody();
     972                        body = inst.getBody();
    958973                        body.editorId = editor_id;
    959974                }
     
    963978                // Fix for bug #958637
    964979                if (!tinyMCE.isIE) {
    965                         var contentElement = inst.getDoc().createElement("body");
    966                         var doc = inst.getDoc();
     980                        contentElement = inst.getDoc().createElement("body");
     981                        doc = inst.getDoc();
    967982
    968983                        contentElement.innerHTML = content;
    969984
    970                         // Remove weridness!
    971                         if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt'])
    972                                 content = content.replace(new RegExp('&lt;&gt;', 'g'), "");
    973 
    974                         if (tinyMCE.settings['cleanup_on_startup'])
     985                        if (tinyMCE.settings.cleanup_on_startup)
    975986                                tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement));
    976987                        else
     
    979990                        tinyMCE.convertAllRelativeURLs(inst.getBody());
    980991                } else {
    981                         if (tinyMCE.settings['cleanup_on_startup']) {
     992                        if (tinyMCE.settings.cleanup_on_startup) {
    982993                                tinyMCE._setHTML(inst.getDoc(), content);
    983994
    984995                                // Produces permission denied error in MSIE 5.5
    985                                 eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}');
     996                                try {
     997                                        tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));
     998                                } catch(e) {
     999                                        // Ignore
     1000                                }
    9861001                        } else
    9871002                                tinyMCE._setHTML(inst.getDoc(), content);
     
    9911006                //inst.getDoc().designMode = inst.getDoc().designMode;
    9921007
    993                 tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst);
     1008                tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings.visual, inst);
    9941009                tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc());
    9951010
     
    11071122
    11081123        handleEvent : function(e) {
    1109                 var inst = tinyMCE.selectedInstance;
     1124                var inst = tinyMCE.selectedInstance, i, elm, keys;
    11101125
    11111126                // Remove odd, error
     
    11501165                                }
    11511166
    1152                                 window.setTimeout("tinyMCE.selectedInstance.setBaseHREF(tinyMCE.settings['base_href']);tinyMCE._resetIframeHeight();", 1);
     1167                                window.setTimeout("tinyMCE.selectedInstance.setBaseHREF(tinyMCE.settings.base_href);tinyMCE._resetIframeHeight();", 1);
    11531168                                return;
    11541169
    11551170                        case "submit":
    1156                                 tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target);
    1157                                 tinyMCE.triggerSave();
    1158                                 tinyMCE.isNotDirty = true;
     1171                                tinyMCE.formSubmit(tinyMCE.isMSIE ? window.event.srcElement : e.target);
    11591172                                return;
    11601173
     
    11621175                                var formObj = tinyMCE.isIE ? window.event.srcElement : e.target;
    11631176
    1164                                 for (var i=0; i<document.forms.length; i++) {
     1177                                for (i=0; i<document.forms.length; i++) {
    11651178                                        if (document.forms[i] == formObj)
    11661179                                                window.setTimeout('tinyMCE.resetForm(' + i + ');', 10);
     
    11841197
    11851198                                // Insert P element
    1186                                 if ((tinyMCE.isGecko || tinyMCE.isOpera || tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && e.keyCode == 13 && !e.shiftKey) {
     1199                                if ((tinyMCE.isGecko || tinyMCE.isOpera || tinyMCE.isSafari) && tinyMCE.settings.force_p_newlines && e.keyCode == 13 && !e.shiftKey) {
    11871200                                        // Insert P element instead of BR
    11881201                                        if (TinyMCE_ForceParagraphs._insertPara(tinyMCE.selectedInstance, e)) {
     
    11941207
    11951208                                // Handle backspace
    1196                                 if ((tinyMCE.isGecko && !tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
     1209                                if ((tinyMCE.isGecko && !tinyMCE.isSafari) && tinyMCE.settings.force_p_newlines && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
    11971210                                        // Insert P element instead of BR
    11981211                                        if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
     
    12041217
    12051218                                // Return key pressed
    1206                                 if (tinyMCE.isIE && tinyMCE.settings['force_br_newlines'] && e.keyCode == 13) {
     1219                                if (tinyMCE.isIE && tinyMCE.settings.force_br_newlines && e.keyCode == 13) {
    12071220                                        if (e.target.editorId)
    12081221                                                tinyMCE.instances[e.target.editorId].select();
     
    12391252
    12401253                                return false;
    1241                         break;
    12421254
    12431255                        case "keyup":
     
    12491261                                        return false;
    12501262
     1263                                inst._fixRootBlocks();
     1264
     1265                                if (inst.settings.remove_trailing_nbsp)
     1266                                        inst._fixTrailingNbsp();
     1267
    12511268                                if (e.target.editorId)
    12521269                                        tinyMCE.instances[e.target.editorId].select();
     
    12551272                                        tinyMCE.selectedInstance.switchSettings();
    12561273
    1257                                 var inst = tinyMCE.selectedInstance;
     1274                                inst = tinyMCE.selectedInstance;
    12581275
    12591276                                // Handle backspace
    1260                                 if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
     1277                                if (tinyMCE.isGecko && tinyMCE.settings.force_p_newlines && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
    12611278                                        // Insert P element instead of BR
    12621279                                        if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
     
    12701287                                tinyMCE.selectedElement = null;
    12711288                                tinyMCE.selectedNode = null;
    1272                                 var elm = tinyMCE.selectedInstance.getFocusElement();
     1289                                elm = tinyMCE.selectedInstance.getFocusElement();
    12731290                                tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a");
    12741291                                tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img");
     
    12771294                                // Update visualaids on tabs
    12781295                                if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9)
    1279                                         tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance);
     1296                                        tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings.visual, tinyMCE.selectedInstance);
    12801297
    12811298                                // Fix empty elements on return/enter, check where enter occured
     
    12851302                                // Fix empty elements on return/enter
    12861303                                if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) {
    1287                                         var elm = tinyMCE.enterKeyElement;
     1304                                        elm = tinyMCE.enterKeyElement;
    12881305                                        if (elm) {
    12891306                                                var re = new RegExp('^HR|IMG|BR$','g'); // Skip these
     
    13001317
    13011318                                // Check if it's a position key
    1302                                 var keys = tinyMCE.posKeyCodes;
     1319                                keys = tinyMCE.posKeyCodes;
    13031320                                var posKey = false;
    1304                                 for (var i=0; i<keys.length; i++) {
     1321                                for (i=0; i<keys.length; i++) {
    13051322                                        if (keys[i] == e.keyCode) {
    13061323                                                posKey = true;
     
    13101327
    13111328                                // MSIE custom key handling
    1312                                 if (tinyMCE.isIE && tinyMCE.settings['custom_undo_redo']) {
    1313                                         var keys = new Array(8,46); // Backspace,Delete
    1314 
    1315                                         for (var i=0; i<keys.length; i++) {
     1329                                if (tinyMCE.isIE && tinyMCE.settings.custom_undo_redo) {
     1330                                        keys = [8, 46]; // Backspace,Delete
     1331
     1332                                        for (i=0; i<keys.length; i++) {
    13161333                                                if (keys[i] == e.keyCode) {
    13171334                                                        if (e.type == "keyup")
     
    13701387                                                continue;
    13711388
    1372                                         var inst = tinyMCE.instances[instanceName];
     1389                                        inst = tinyMCE.instances[instanceName];
    13731390
    13741391                                        // Reset design mode if lost (on everything just in case)
     
    14041421
    14051422                                return false;
    1406                         break;
    14071423                }
    14081424        },
     
    14301446                        x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20);
    14311447                        h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceTiledButton mceButtonNormal" target="_self">';
    1432                         h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" title="{$' + lang + '}" />';
     1448                        h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" alt="{$'+lang+'}" title="{$' + lang + '}" />';
    14331449                        h += '</a>';
    14341450                } else {
    14351451                        // Normal button
    14361452                        h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceButtonNormal" target="_self">';
    1437                         h += '<img src="' + img + '" title="{$' + lang + '}" />';
     1453                        h += '<img src="' + img + '" alt="{$'+lang+'}" title="{$' + lang + '}" />';
    14381454                        h += '</a>';
    14391455                }
     
    15011517        },
    15021518
     1519        formSubmit : function(f, p) {
     1520                var n, inst, found = false;
     1521
     1522                if (f.form)
     1523                        f = f.form;
     1524
     1525                // Is it a form that has a TinyMCE instance
     1526                for (n in tinyMCE.instances) {
     1527                        inst = tinyMCE.instances[n];
     1528
     1529                        if (!tinyMCE.isInstance(inst))
     1530                                continue;
     1531
     1532                        if (inst.formElement) {
     1533                                if (f == inst.formElement.form) {
     1534                                        found = true;
     1535                                        inst.isNotDirty = true;
     1536                                }
     1537                        }
     1538                }
     1539
     1540                // Is valid
     1541                if (found) {
     1542                        tinyMCE.removeTinyMCEFormElements(f);
     1543                        tinyMCE.triggerSave();
     1544                }
     1545
     1546                // Is it patched
     1547                if (f.mceOldSubmit && p)
     1548                        f.mceOldSubmit();
     1549        },
     1550
    15031551        submitPatch : function() {
    1504                 tinyMCE.removeTinyMCEFormElements(this);
    1505                 tinyMCE.triggerSave();
    1506                 tinyMCE.isNotDirty = true;
    1507                 this.mceOldSubmit();
     1552                tinyMCE.formSubmit(this, true);
    15081553        },
    15091554
    15101555        onLoad : function() {
    1511                 var r;
     1556                var r, i, c, mode, trigger, elements, element, settings, elementId, elm;
     1557                var selector, deselector, elementRefAr, form;
    15121558
    15131559                // Wait for everything to be loaded first
     
    15281574                // It seems to have something to do with the selection not beeing
    15291575                // correctly initialized in IE so this hack solves the problem
    1530                 if (tinyMCE.isRealIE && document.body) {
     1576                if (tinyMCE.isRealIE && document.body && window.location.href != window.top.location.href) {
    15311577                        r = document.body.createTextRange();
    15321578                        r.collapse(true);
     
    15361582                tinyMCE.dispatchCallback(null, 'onpageload', 'onPageLoad');
    15371583
    1538                 for (var c=0; c<tinyMCE.configs.length; c++) {
     1584                for (c=0; c<tinyMCE.configs.length; c++) {
    15391585                        tinyMCE.settings = tinyMCE.configs[c];
    15401586
    1541                         var selector = tinyMCE.getParam("editor_selector");
    1542                         var deselector = tinyMCE.getParam("editor_deselector");
    1543                         var elementRefAr = new Array();
     1587                        selector = tinyMCE.getParam("editor_selector");
     1588                        deselector = tinyMCE.getParam("editor_deselector");
     1589                        elementRefAr = [];
    15441590
    15451591                        // Add submit triggers
    1546                         if (document.forms && tinyMCE.settings['add_form_submit_trigger'] && !tinyMCE.submitTriggers) {
    1547                                 for (var i=0; i<document.forms.length; i++) {
    1548                                         var form = document.forms[i];
     1592                        if (document.forms && tinyMCE.settings.add_form_submit_trigger && !tinyMCE.submitTriggers) {
     1593                                for (i=0; i<document.forms.length; i++) {
     1594                                        form = document.forms[i];
    15491595
    15501596                                        tinyMCE.addEvent(form, "submit", TinyMCE_Engine.prototype.handleEvent);
     
    15531599
    15541600                                        // Patch the form.submit function
    1555                                         if (tinyMCE.settings['submit_patch']) {
     1601                                        if (tinyMCE.settings.submit_patch) {
    15561602                                                try {
    15571603                                                        form.mceOldSubmit = form.submit;
     
    15651611
    15661612                        // Add editor instances based on mode
    1567                         var mode = tinyMCE.settings['mode'];
     1613                        mode = tinyMCE.settings.mode;
    15681614                        switch (mode) {
    15691615                                case "exact":
    1570                                         var elements = tinyMCE.getParam('elements', '', true, ',');
    1571 
    1572                                         for (var i=0; i<elements.length; i++) {
    1573                                                 var element = tinyMCE._getElementById(elements[i]);
    1574                                                 var trigger = element ? element.getAttribute(tinyMCE.settings['textarea_trigger']) : "";
     1616                                        elements = tinyMCE.getParam('elements', '', true, ',');
     1617
     1618                                        for (i=0; i<elements.length; i++) {
     1619                                                element = tinyMCE._getElementById(elements[i]);
     1620                                                trigger = element ? element.getAttribute(tinyMCE.settings.textarea_trigger) : "";
    15751621
    15761622                                                if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(element, "class")))
     
    15801626                                                        continue;
    15811627
    1582                                                 if ((tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) && element) {
     1628                                                if ((tinyMCE.settings.ask || tinyMCE.settings.convert_on_click) && element) {
    15831629                                                        elementRefAr[elementRefAr.length] = element;
    15841630                                                        continue;
     
    15871633                                                if (element)
    15881634                                                        tinyMCE.addMCEControl(element, elements[i]);
    1589                                                 else if (tinyMCE.settings['debug'])
    1590                                                         alert("Error: Could not find element by id or name: " + elements[i]);
    15911635                                        }
    15921636                                break;
     
    15941638                                case "specific_textareas":
    15951639                                case "textareas":
    1596                                         var nodeList = document.getElementsByTagName("textarea");
    1597 
    1598                                         for (var i=0; i<nodeList.length; i++) {
    1599                                                 var elm = nodeList.item(i);
    1600                                                 var trigger = elm.getAttribute(tinyMCE.settings['textarea_trigger']);
    1601 
    1602                                                 if (selector != '' && !new RegExp('\\b' + selector + '\\b').test(tinyMCE.getAttrib(elm, "class")))
     1640                                        elements = document.getElementsByTagName("textarea");
     1641
     1642                                        for (i=0; i<elements.length; i++) {
     1643                                                elm = elements.item(i);
     1644                                                trigger = elm.getAttribute(tinyMCE.settings.textarea_trigger);
     1645
     1646                                                if (selector !== '' && !new RegExp('\\b' + selector + '\\b').test(tinyMCE.getAttrib(elm, "class")))
    16031647                                                        continue;
    16041648
    1605                                                 if (selector != '')
    1606                                                         trigger = selector != "" ? "true" : "";
     1649                                                if (selector !== '')
     1650                                                        trigger = selector !== '' ? "true" : "";
    16071651
    16081652                                                if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(elm, "class")))
     
    16151659                        }
    16161660
    1617                         for (var i=0; i<elementRefAr.length; i++) {
    1618                                 var element = elementRefAr[i];
    1619                                 var elementId = element.name ? element.name : element.id;
    1620 
    1621                                 if (tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) {
     1661                        for (i=0; i<elementRefAr.length; i++) {
     1662                                element = elementRefAr[i];
     1663                                elementId = element.name ? element.name : element.id;
     1664
     1665                                if (tinyMCE.settings.ask || tinyMCE.settings.convert_on_click) {
    16221666                                        // Focus breaks in Mozilla
    16231667                                        if (tinyMCE.isGecko) {
    1624                                                 var settings = tinyMCE.settings;
     1668                                                settings = tinyMCE.settings;
    16251669
    16261670                                                tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
     
    16301674                                                // tinyMCE.addEvent(element, "mouseover", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
    16311675                                        } else {
    1632                                                 var settings = tinyMCE.settings;
     1676                                                settings = tinyMCE.settings;
    16331677
    16341678                                                tinyMCE.addEvent(element, "focus", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
     
    16411685
    16421686                        // Handle auto focus
    1643                         if (tinyMCE.settings['auto_focus']) {
     1687                        if (tinyMCE.settings.auto_focus) {
    16441688                                window.setTimeout(function () {
    1645                                         var inst = tinyMCE.getInstanceById(tinyMCE.settings['auto_focus']);
     1689                                        var inst = tinyMCE.getInstanceById(tinyMCE.settings.auto_focus);
    16461690                                        inst.selection.selectNode(inst.getBody(), true, true);
    16471691                                        inst.contentWindow.focus();
     
    16581702
    16591703        getParam : function(name, default_value, strip_whitespace, split_chr) {
    1660                 var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
     1704                var i, outArray, value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
    16611705
    16621706                // Fix bool values
     
    16691713                if (typeof(split_chr) != "undefined" && split_chr != null) {
    16701714                        value = value.split(split_chr);
    1671                         var outArray = new Array();
    1672 
    1673                         for (var i=0; i<value.length; i++) {
    1674                                 if (value[i] && value[i] != "")
     1715                        outArray = [];
     1716
     1717                        for (i=0; i<value.length; i++) {
     1718                                if (value[i] && value[i] !== '')
    16751719                                        outArray[outArray.length] = value[i];
    16761720                        }
     
    17011745                e.innerHTML = s;
    17021746
    1703                 return e.firstChild.nodeValue;
     1747                return !e.firstChild ? s : e.firstChild.nodeValue;
    17041748        },
    17051749
    17061750        addToLang : function(prefix, ar) {
    1707                 for (var key in ar) {
    1708                         if (typeof(ar[key]) == 'function')
     1751                var k;
     1752
     1753                for (k in ar) {
     1754                        if (typeof(ar[k]) == 'function')
    17091755                                continue;
    17101756
    1711                         tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = ar[key];
     1757                        tinyMCELang[(k.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix !== '' ? (prefix + "_") : '') + k] = ar[k];
    17121758                }
    17131759
    17141760                this.loadNextScript();
    1715 
    1716         //      for (var key in ar)
    1717         //              tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = "|" + ar[key] + "|";
    17181761        },
    17191762
     
    17441787                                anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (st && st.length > 0);
    17451788
    1746                         if (tinyMCE.settings['custom_undo_redo']) {
     1789                        if (tinyMCE.settings.custom_undo_redo) {
    17471790                                undoIndex = inst.undoRedo.undoIndex;
    17481791                                undoLevels = inst.undoRedo.undoLevels.length;
     
    17571800
    17581801        _customCleanup : function(inst, type, content) {
    1759                 var pl, po, i;
     1802                var pl, po, i, customCleanup;
    17601803
    17611804                // Call custom cleanup
    1762                 var customCleanup = tinyMCE.settings['cleanup_callback'];
    1763                 if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined")
    1764                         content = eval(customCleanup + "(type, content, inst);");
     1805                customCleanup = tinyMCE.settings.cleanup_callback;
     1806                if (customCleanup != '')
     1807                        content = tinyMCE.resolveDots(tinyMCE.settings.cleanup_callback, window)(type, content, inst);
    17651808
    17661809                // Trigger theme cleanup
    1767                 po = tinyMCE.themes[tinyMCE.settings['theme']];
     1810                po = tinyMCE.themes[tinyMCE.settings.theme];
    17681811                if (po && po.cleanup)
    17691812                        content = po.cleanup(type, content, inst);
     
    17901833        importThemeLanguagePack : function(name) {
    17911834                if (typeof(name) == "undefined")
    1792                         name = tinyMCE.settings['theme'];
    1793 
    1794                 tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings['language'] + '.js');
     1835                        name = tinyMCE.settings.theme;
     1836
     1837                tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings.language + '.js');
    17951838        },
    17961839
     
    18011844                        b = this.plugins[name].baseURL;
    18021845
    1803                 tinyMCE.loadScript(b + '/langs/' + tinyMCE.settings['language'] +  '.js');
    1804         },
    1805 
    1806         applyTemplate : function(h, as) {
     1846                tinyMCE.loadScript(b + '/langs/' + tinyMCE.settings.language +  '.js');
     1847        },
     1848
     1849        applyTemplate : function(h, ag) {
    18071850                return h.replace(new RegExp('\\{\\$([a-z0-9_]+)\\}', 'gi'), function(m, s) {
    18081851                        if (s.indexOf('lang_') == 0 && tinyMCELang[s])
    18091852                                return tinyMCELang[s];
    18101853
    1811                         if (as && as[s])
    1812                                 return as[s];
     1854                        if (ag && ag[s])
     1855                                return ag[s];
    18131856
    18141857                        if (tinyMCE.settings[s])
     
    18271870
    18281871        openWindow : function(template, args) {
    1829                 var html, width, height, x, y, resizable, scrollbars, url;
     1872                var html, width, height, x, y, resizable, scrollbars, url, name, win, modal, features;
    18301873
    18311874                args = !args ? {} : args;
    18321875
    1833                 args['mce_template_file'] = template['file'];
    1834                 args['mce_width'] = template['width'];
    1835                 args['mce_height'] = template['height'];
     1876                args.mce_template_file = template.file;
     1877                args.mce_width = template.width;
     1878                args.mce_height = template.height;
    18361879                tinyMCE.windowArgs = args;
    18371880
    1838                 html = template['html'];
    1839                 if (!(width = parseInt(template['width'])))
     1881                html = template.html;
     1882                if (!(width = parseInt(template.width)))
    18401883                        width = 320;
    18411884
    1842                 if (!(height = parseInt(template['height'])))
     1885                if (!(height = parseInt(template.height)))
    18431886                        height = 200;
    18441887
     
    18521895                y = parseInt(screen.height / 2.0) - (height / 2.0);
    18531896
    1854                 resizable = (args && args['resizable']) ? args['resizable'] : "no";
    1855                 scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
    1856 
    1857                 if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
    1858                         url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
     1897                resizable = (args && args.resizable) ? args.resizable : "no";
     1898                scrollbars = (args && args.scrollbars) ? args.scrollbars : "no";
     1899
     1900                if (template.file.charAt(0) != '/' && template.file.indexOf('://') == -1)
     1901                        url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template.file;
    18591902                else
    1860                         url = template['file'];
     1903                        url = template.file;
    18611904
    18621905                // Replace all args as variables in URL
    1863                 for (var name in args) {
     1906                for (name in args) {
    18641907                        if (typeof(args[name]) == 'function')
    18651908                                continue;
     
    18691912
    18701913                if (html) {
    1871                         html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']);
     1914                        html = tinyMCE.replaceVar(html, "css", this.settings.popups_css);
    18721915                        html = tinyMCE.applyTemplate(html, args);
    18731916
    1874                         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);
     1917                        win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable);
    18751918                        if (win == null) {
    1876                                 alert(tinyMCELang['lang_popup_blocked']);
     1919                                alert(tinyMCELang.lang_popup_blocked);
    18771920                                return;
    18781921                        }
     
    18831926                        win.focus();
    18841927                } else {
    1885                         if ((tinyMCE.isRealIE) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {
     1928                        if ((tinyMCE.isRealIE) && resizable != 'yes' && tinyMCE.settings.dialog_type == "modal") {
    18861929                                height += 10;
    18871930
    1888                                 var features = "resizable:" + resizable
    1889                                         + ";scroll:"
    1890                                         + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:"
    1891                                         + width + "px;dialogHeight:" + height + "px;";
     1931                                features = "resizable:" + resizable + ";scroll:" + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:" + width + "px;dialogHeight:" + height + "px;";
    18921932
    18931933                                window.showModalDialog(url, window, features);
    18941934                        } else {
    1895                                 var modal = (resizable == "yes") ? "no" : "yes";
     1935                                modal = (resizable == "yes") ? "no" : "yes";
    18961936
    18971937                                if (tinyMCE.isGecko && tinyMCE.isMac)
    18981938                                        modal = "no";
    18991939
    1900                                 if (template['close_previous'] != "no")
     1940                                if (template.close_previous != "no")
    19011941                                        try {tinyMCE.lastWindow.close();} catch (ex) {}
    19021942
    1903                                 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);
     1943                                win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable);
    19041944                                if (win == null) {
    1905                                         alert(tinyMCELang['lang_popup_blocked']);
     1945                                        alert(tinyMCELang.lang_popup_blocked);
    19061946                                        return;
    19071947                                }
    19081948
    1909                                 if (template['close_previous'] != "no")
     1949                                if (template.close_previous != "no")
    19101950                                        tinyMCE.lastWindow = win;
    19111951
    1912                                 eval('try { win.resizeTo(width, height); } catch(e) { }');
     1952                                try {
     1953                                        win.resizeTo(width, height);
     1954                                } catch(e) {
     1955                                        // Ignore
     1956                                }
    19131957
    19141958                                // Make it bigger if statusbar is forced
     
    19281972
    19291973        getVisualAidClass : function(class_name, state) {
    1930                 var aidClass = tinyMCE.settings['visual_table_class'];
     1974                var i, classNames, ar, className, aidClass = tinyMCE.settings.visual_table_class;
    19311975
    19321976                if (typeof(state) == "undefined")
    1933                         state = tinyMCE.settings['visual'];
     1977                        state = tinyMCE.settings.visual;
    19341978
    19351979                // Split
    1936                 var classNames = new Array();
    1937                 var ar = class_name.split(' ');
    1938                 for (var i=0; i<ar.length; i++) {
     1980                classNames = [];
     1981                ar = class_name.split(' ');
     1982                for (i=0; i<ar.length; i++) {
    19391983                        if (ar[i] == aidClass)
    19401984                                ar[i] = "";
    19411985
    1942                         if (ar[i] != "")
     1986                        if (ar[i] !== '')
    19431987                                classNames[classNames.length] = ar[i];
    19441988                }
     
    19481992
    19491993                // Glue
    1950                 var className = "";
    1951                 for (var i=0; i<classNames.length; i++) {
     1994                className = "";
     1995                for (i=0; i<classNames.length; i++) {
    19521996                        if (i > 0)
    19531997                                className += " ";
     
    19602004
    19612005        handleVisualAid : function(el, deep, state, inst, skip_dispatch) {
     2006                var i, x, y, tableElement, anchorName, oldW, oldH, bo, cn;
     2007
    19622008                if (!el)
    19632009                        return;
     
    19662012                        tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst);
    19672013
    1968                 var tableElement = null;
     2014                tableElement = null;
    19692015
    19702016                switch (el.nodeName) {
    19712017                        case "TABLE":
    1972                                 var oldW = el.style.width;
    1973                                 var oldH = el.style.height;
    1974                                 var bo = tinyMCE.getAttrib(el, "border");
    1975 
    1976                                 bo = bo == "" || bo == "0" ? true : false;
     2018                                oldW = el.style.width;
     2019                                oldH = el.style.height;
     2020                                bo = tinyMCE.getAttrib(el, "border");
     2021
     2022                                bo = bo == '' || bo == "0" ? true : false;
    19772023
    19782024                                tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo));
     
    19812027                                el.style.height = oldH;
    19822028
    1983                                 for (var y=0; y<el.rows.length; y++) {
    1984                                         for (var x=0; x<el.rows[y].cells.length; x++) {
    1985                                                 var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);
     2029                                for (y=0; y<el.rows.length; y++) {
     2030                                        for (x=0; x<el.rows[y].cells.length; x++) {
     2031                                                cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);
    19862032                                                tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn);
    19872033                                        }
     
    19912037
    19922038                        case "A":
    1993                                 var anchorName = tinyMCE.getAttrib(el, "name");
    1994 
    1995                                 if (anchorName != '' && state) {
     2039                                anchorName = tinyMCE.getAttrib(el, "name");
     2040
     2041                                if (anchorName !== '' && state) {
    19962042                                        el.title = anchorName;
    19972043                                        tinyMCE.addCSSClass(el, 'mceItemAnchor');
    1998                                 } else if (anchorName != '' && !state)
     2044                                } else if (anchorName !== '' && !state)
    19992045                                        el.className = '';
    20002046
     
    20032049
    20042050                if (deep && el.hasChildNodes()) {
    2005                         for (var i=0; i<el.childNodes.length; i++)
     2051                        for (i=0; i<el.childNodes.length; i++)
    20062052                                tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst, true);
    20072053                }
    20082054        },
    2009 
    2010         /*
    2011         applyClassesToFonts : function(doc, size) {
    2012                 var f = doc.getElementsByTagName("font");
    2013                 for (var i=0; i<f.length; i++) {
    2014                         var s = tinyMCE.getAttrib(f[i], "size");
    2015 
    2016                         if (s != "")
    2017                                 tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s);
    2018                 }
    2019 
    2020                 if (typeof(size) != "undefined") {
    2021                         var css = "";
    2022 
    2023                         for (var x=0; x<doc.styleSheets.length; x++) {
    2024                                 for (var i=0; i<doc.styleSheets[x].rules.length; i++) {
    2025                                         if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) {
    2026                                                 css = doc.styleSheets[x].rules[i].style.cssText;
    2027                                                 break;
    2028                                         }
    2029                                 }
    2030 
    2031                                 if (css != "")
    2032                                         break;
    2033                         }
    2034 
    2035                         if (doc.styleSheets[0].rules[0].selectorText == "FONT")
    2036                                 doc.styleSheets[0].removeRule(0);
    2037 
    2038                         doc.styleSheets[0].addRule("FONT", css, 0);
    2039                 }
    2040         },
    2041         */
    20422055
    20432056        fixGeckoBaseHREFBug : function(m, e, h) {
     
    20602073                                        xhref = tinyMCE.getAttrib(n, "mce_thref");
    20612074
    2062                                         if (xsrc != "") {
     2075                                        if (xsrc !== '') {
    20632076                                                try {
    2064                                                         n.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
     2077                                                        n.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, xsrc);
    20652078                                                } catch (e) {
    20662079                                                        // Ignore, Firefox cast exception if local file wasn't found
     
    20702083                                        }
    20712084
    2072                                         if (xhref != "") {
     2085                                        if (xhref !== '') {
    20732086                                                try {
    2074                                                         n.href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref);
     2087                                                        n.href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, xhref);
    20752088                                                } catch (e) {
    20762089                                                        // Ignore, Firefox cast exception if local file wasn't found
     
    20992112
    21002113        _setHTML : function(doc, html_content) {
     2114                var i, html, paras, node;
     2115
    21012116                // Force closed anchors open
    21022117                //html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
     
    21132128
    21142129                // Content duplication bug fix
    2115                 if (tinyMCE.isIE && tinyMCE.settings['fix_content_duplication']) {
     2130                if (tinyMCE.isIE && tinyMCE.settings.fix_content_duplication) {
    21162131                        // Remove P elements in P elements
    2117                         var paras = doc.getElementsByTagName("P");
    2118                         for (var i=0; i<paras.length; i++) {
    2119                                 var node = paras[i];
     2132                        paras = doc.getElementsByTagName("P");
     2133                        for (i=0; i<paras.length; i++) {
     2134                                node = paras[i];
     2135
    21202136                                while ((node = node.parentNode) != null) {
    21212137                                        if (node.nodeName == "P")
     
    21252141
    21262142                        // Content duplication bug fix (Seems to be word crap)
    2127                         var html = doc.body.innerHTML;
    2128 /*
    2129                         if (html.indexOf('="mso') != -1) {
    2130                                 for (var i=0; i<doc.body.all.length; i++) {
    2131                                         var el = doc.body.all[i];
    2132                                         el.removeAttribute("className","",0);
    2133                                         el.removeAttribute("style","",0);
    2134                                 }
    2135 
    2136                                 html = doc.body.innerHTML;
    2137                                 html = tinyMCE.regexpReplace(html, "<o:p><\/o:p>", "<br />");
    2138                                 html = tinyMCE.regexpReplace(html, "<o:p>&nbsp;<\/o:p>", "");
    2139                                 html = tinyMCE.regexpReplace(html, "<st1:.*?>", "");
    2140                                 html = tinyMCE.regexpReplace(html, "<p><\/p>", "");
    2141                                 html = tinyMCE.regexpReplace(html, "<p><\/p>\r\n<p><\/p>", "");
    2142                                 html = tinyMCE.regexpReplace(html, "<p>&nbsp;<\/p>", "<br />");
    2143                                 html = tinyMCE.regexpReplace(html, "<p>\s*(<p>\s*)?", "<p>");
    2144                                 html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "</p>");
    2145                         }*/
     2143                        html = doc.body.innerHTML;
    21462144
    21472145                        // Always set the htmlText output
     
    21572155        getEditorId : function(form_element) {
    21582156                var inst = this.getInstanceById(form_element);
     2157
    21592158                if (!inst)
    21602159                        return null;
     
    21642163
    21652164        getInstanceById : function(editor_id) {
    2166                 var inst = this.instances[editor_id];
     2165                var inst = this.instances[editor_id], n;
     2166
    21672167                if (!inst) {
    2168                         for (var n in tinyMCE.instances) {
    2169                                 var instance = tinyMCE.instances[n];
    2170                                 if (!tinyMCE.isInstance(instance))
     2168                        for (n in tinyMCE.instances) {
     2169                                inst = tinyMCE.instances[n];
     2170
     2171                                if (!tinyMCE.isInstance(inst))
    21712172                                        continue;
    21722173
    2173                                 if (instance.formTargetElementId == editor_id) {
    2174                                         inst = instance;
    2175                                         break;
    2176                                 }
    2177                         }
    2178                 }
    2179 
    2180                 return inst;
     2174                                if (inst.formTargetElementId == editor_id)
     2175                                        return inst;
     2176                        }
     2177                } else
     2178                        return inst;
     2179
     2180                return null;
    21812181        },
    21822182
    21832183        queryInstanceCommandValue : function(editor_id, command) {
    21842184                var inst = tinyMCE.getInstanceById(editor_id);
     2185
    21852186                if (inst)
    21862187                        return inst.queryCommandValue(command);
     
    21912192        queryInstanceCommandState : function(editor_id, command) {
    21922193                var inst = tinyMCE.getInstanceById(editor_id);
     2194
    21932195                if (inst)
    21942196                        return inst.queryCommandState(command);
     
    22062208
    22072209        getCSSClasses : function(editor_id, doc) {
    2208                 var inst = tinyMCE.getInstanceById(editor_id);
     2210                var i, c, x, rule, styles, rules, csses, selectorText, inst = tinyMCE.getInstanceById(editor_id);
     2211                var cssClass, addClass, p;
     2212
     2213                if (!inst)
     2214                        inst = tinyMCE.selectedInstance;
     2215
     2216                if (!inst)
     2217                        return [];
     2218
     2219                if (!doc)
     2220                        doc = inst.getDoc();
    22092221
    22102222                // Is cached, use that
     
    22122224                        return inst.cssClasses;
    22132225
    2214                 if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") {
    2215                         var instance;
    2216 
    2217                         for (var instanceName in tinyMCE.instances) {
    2218                                 instance = tinyMCE.instances[instanceName];
    2219                                 if (!tinyMCE.isInstance(instance))
    2220                                         continue;
    2221 
    2222                                 break;
    2223                         }
    2224 
    2225                         doc = instance.getDoc();
    2226                 }
    2227 
    2228                 if (typeof(doc) == "undefined") {
    2229                         var instance = tinyMCE.getInstanceById(editor_id);
    2230                         doc = instance.getDoc();
    2231                 }
    2232 
    2233                 if (doc) {
    2234                         var styles = doc.styleSheets;
    2235 
    2236                         if (styles && styles.length > 0) {
    2237                                 for (var x=0; x<styles.length; x++) {
    2238                                         var csses = null;
    2239 
    2240                                         // Just ignore any errors
    2241                                         eval("try {var csses = tinyMCE.isIE ? doc.styleSheets(" + x + ").rules : styles[" + x + "].cssRules;} catch(e) {}");
    2242                                         if (!csses)
    2243                                                 return new Array();
    2244 
    2245                                         for (var i=0; i<csses.length; i++) {
    2246                                                 var selectorText = csses[i].selectorText;
    2247 
    2248                                                 // Can be multiple rules per selector
    2249                                                 if (selectorText) {
    2250                                                         var rules = selectorText.split(',');
    2251                                                         for (var c=0; c<rules.length; c++) {
    2252                                                                 var rule = rules[c];
    2253 
    2254                                                                 // Strip spaces between selectors
    2255                                                                 while (rule.indexOf(' ') == 0)
    2256                                                                         rule = rule.substring(1);
    2257 
    2258                                                                 // Invalid rule
    2259                                                                 if (rule.indexOf(' ') != -1 || rule.indexOf(':') != -1 || rule.indexOf('mceItem') != -1)
    2260                                                                         continue;
    2261 
    2262                                                                 if (rule.indexOf(tinyMCE.settings['visual_table_class']) != -1 || rule.indexOf('mceEditable') != -1 || rule.indexOf('mceNonEditable') != -1)
    2263                                                                         continue;
    2264 
    2265                                                                 // Is class rule
    2266                                                                 if (rule.indexOf('.') != -1) {
    2267                                                                         var cssClass = rule.substring(rule.indexOf('.') + 1);
    2268                                                                         var addClass = true;
    2269 
    2270                                                                         for (var p=0; p<inst.cssClasses.length && addClass; p++) {
    2271                                                                                 if (inst.cssClasses[p] == cssClass)
    2272                                                                                         addClass = false;
    2273                                                                         }
    2274 
    2275                                                                         if (addClass)
    2276                                                                                 inst.cssClasses[inst.cssClasses.length] = cssClass;
     2226                if (!doc)
     2227                        return;
     2228
     2229                styles = doc.styleSheets;
     2230
     2231                if (styles && styles.length > 0) {
     2232                        for (x=0; x<styles.length; x++) {
     2233                                csses = null;
     2234
     2235                                try {
     2236                                        csses = tinyMCE.isIE ? doc.styleSheets(x).rules : styles[x].cssRules;
     2237                                } catch(e) {
     2238                                        // Just ignore any errors I know this is ugly!!
     2239                                }
     2240       
     2241                                if (!csses)
     2242                                        return [];
     2243
     2244                                for (i=0; i<csses.length; i++) {
     2245                                        selectorText = csses[i].selectorText;
     2246
     2247                                        // Can be multiple rules per selector
     2248                                        if (selectorText) {
     2249                                                rules = selectorText.split(',');
     2250                                                for (c=0; c<rules.length; c++) {
     2251                                                        rule = rules[c];
     2252
     2253                                                        // Strip spaces between selectors
     2254                                                        while (rule.indexOf(' ') == 0)
     2255                                                                rule = rule.substring(1);
     2256
     2257                                                        // Invalid rule
     2258                                                        if (rule.indexOf(' ') != -1 || rule.indexOf(':') != -1 || rule.indexOf('mceItem') != -1)
     2259                                                                continue;
     2260
     2261                                                        if (rule.indexOf(tinyMCE.settings.visual_table_class) != -1 || rule.indexOf('mceEditable') != -1 || rule.indexOf('mceNonEditable') != -1)
     2262                                                                continue;
     2263
     2264                                                        // Is class rule
     2265                                                        if (rule.indexOf('.') != -1) {
     2266                                                                cssClass = rule.substring(rule.indexOf('.') + 1);
     2267                                                                addClass = true;
     2268
     2269                                                                for (p=0; p<inst.cssClasses.length && addClass; p++) {
     2270                                                                        if (inst.cssClasses[p] == cssClass)
     2271                                                                                addClass = false;
    22772272                                                                }
     2273
     2274                                                                if (addClass)
     2275                                                                        inst.cssClasses[inst.cssClasses.length] = cssClass;
    22782276                                                        }
    22792277                                                }
     
    22872285
    22882286        regexpReplace : function(in_str, reg_exp, replace_str, opts) {
     2287                var re;
     2288
    22892289                if (in_str == null)
    22902290                        return in_str;
     
    22932293                        opts = 'g';
    22942294
    2295                 var re = new RegExp(reg_exp, opts);
     2295                re = new RegExp(reg_exp, opts);
     2296
    22962297                return in_str.replace(re, replace_str);
    22972298        },
     
    23172318                        o = l[n];
    23182319
    2319                         if (o.getControlHTML && (v = o.getControlHTML(c)) != '') {
     2320                        if (o.getControlHTML && (v = o.getControlHTML(c)) !== '') {
    23202321                                if (rtl)
    23212322                                        return '<span dir="rtl">' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + '</span>';
     
    23252326                }
    23262327
    2327                 o = tinyMCE.themes[tinyMCE.settings['theme']];
    2328                 if (o.getControlHTML && (v = o.getControlHTML(c)) != '') {
     2328                o = tinyMCE.themes[tinyMCE.settings.theme];
     2329                if (o.getControlHTML && (v = o.getControlHTML(c)) !== '') {
    23292330                        if (rtl)
    23302331                                return '<span dir="rtl">' + v + '</span>';
     
    23622363                l = tinyMCE.getParam(p, '');
    23632364
    2364                 if (l != '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0)
     2365                if (l !== '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0)
    23652366                        return true;
    23662367
     
    23852386        },
    23862387
    2387         xmlEncode : function(s, skip_apos) {
    2388                 return s ? ('' + s).replace(!skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe, function (c, b) {
     2388        resolveDots : function(s, o) {
     2389                var i;
     2390
     2391                if (typeof(s) == 'string') {
     2392                        for (i=0, s=s.split('.'); i<s.length; i++)
     2393                                o = o[s[i]];
     2394                } else
     2395                        o = s;
     2396
     2397                return o;
     2398        },
     2399
     2400        xmlEncode : function(s) {
     2401                return s ? ('' + s).replace(this.xmlEncodeRe, function (c, b) {
    23892402                        switch (c) {
    23902403                                case '&':
     
    23942407                                        return '&quot;';
    23952408
    2396                                 case '\'':
    2397                                         return '&#39;'; // &apos; is not working in MSIE
    2398 
    23992409                                case '<':
    24002410                                        return '&lt;';
     
    24082418        },
    24092419
     2420        add : function(c, m) {
     2421                var n;
     2422
     2423                for (n in m)
     2424                        c.prototype[n] = m[n];
     2425        },
     2426
    24102427        extend : function(p, np) {
    2411                 var o = {};
     2428                var o = {}, n;
    24122429
    24132430                o.parent = p;
     
    24462463
    24472464function TinyMCE_Control(settings) {
    2448         var t, i, to, fu, p, x, fn, fu, pn, s = settings;
     2465        var t, i, tos, fu, p, x, fn, fu, pn, s = settings;
    24492466
    24502467        this.undoRedoLevel = true;
     
    24522469
    24532470        // Default settings
     2471        this.enabled = true;
    24542472        this.settings = s;
    2455         this.settings['theme'] = tinyMCE.getParam("theme", "default");
    2456         this.settings['width'] = tinyMCE.getParam("width", -1);
    2457         this.settings['height'] = tinyMCE.getParam("height", -1);
     2473        this.settings.theme = tinyMCE.getParam("theme", "default");
     2474        this.settings.width = tinyMCE.getParam("width", -1);
     2475        this.settings.height = tinyMCE.getParam("height", -1);
    24582476        this.selection = new TinyMCE_Selection(this);
    24592477        this.undoRedo = new TinyMCE_UndoRedo(this);
    24602478        this.cleanup = new TinyMCE_Cleanup();
    2461         this.shortcuts = new Array();
     2479        this.shortcuts = [];
    24622480        this.hasMouseMoved = false;
    24632481        this.foreColor = this.backColor = "#999999";
     
    24802498
    24812499        // Wrap old theme
    2482         t = this.settings['theme'];
     2500        t = this.settings.theme;
    24832501        if (!tinyMCE.hasTheme(t)) {
    24842502                fn = tinyMCE.callbacks;
    2485                 to = {};
     2503                tos = {};
    24862504
    24872505                for (i=0; i<fn.length; i++) {
    24882506                        if ((fu = window['TinyMCE_' + t + "_" + fn[i]]))
    2489                                 to[fn[i]] = fu;
    2490                 }
    2491 
    2492                 tinyMCE.addTheme(t, to);
     2507                                tos[fn[i]] = fu;
     2508                }
     2509
     2510                tinyMCE.addTheme(t, tos);
    24932511        }
    24942512
    24952513        // Wrap old plugins
    2496         this.plugins = new Array();
     2514        this.plugins = [];
    24972515        p = tinyMCE.getParam('plugins', '', true, ',');
    24982516        if (p.length > 0) {
     
    25052523                        if (!tinyMCE.hasPlugin(pn)) {
    25062524                                fn = tinyMCE.callbacks;
    2507                                 to = {};
     2525                                tos = {};
    25082526
    25092527                                for (x=0; x<fn.length; x++) {
    25102528                                        if ((fu = window['TinyMCE_' + pn + "_" + fn[x]]))
    2511                                                 to[fn[x]] = fu;
    2512                                 }
    2513 
    2514                                 tinyMCE.addPlugin(pn, to);
     2529                                                tos[fn[x]] = fu;
     2530                                }
     2531
     2532                                tinyMCE.addPlugin(pn, tos);
    25152533                        }
    25162534
     
    25742592
    25752593        switchSettings : function() {
    2576                 if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings['index']) {
     2594                if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings.index) {
    25772595                        tinyMCE.settings = this.settings;
    2578                         tinyMCE.currentConfig = this.settings['index'];
     2596                        tinyMCE.currentConfig = this.settings.index;
    25792597                }
    25802598        },
     
    27102728        isDirty : function() {
    27112729                // Is content modified and not in a submit procedure
    2712                 return tinyMCE.trim(this.startContent) != tinyMCE.trim(this.getBody().innerHTML) && !tinyMCE.isNotDirty;
     2730                return tinyMCE.trim(this.startContent) != tinyMCE.trim(this.getBody().innerHTML) && !this.isNotDirty;
    27132731        },
    27142732
    27152733        _mergeElements : function(scmd, pa, ch, override) {
     2734                var st, stc, className, n;
     2735
    27162736                if (scmd == "removeformat") {
    27172737                        pa.className = "";
     
    27222742                }
    27232743
    2724                 var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style"));
    2725                 var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style"));
    2726                 var className = tinyMCE.getAttrib(pa, "class");
     2744                st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style"));
     2745                stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style"));
     2746                className = tinyMCE.getAttrib(pa, "class");
    27272747
    27282748                // Removed class adding due to bug #1478272
     
    27302750
    27312751                if (override) {
    2732                         for (var n in st) {
     2752                        for (n in st) {
    27332753                                if (typeof(st[n]) == 'function')
    27342754                                        continue;
     
    27372757                        }
    27382758                } else {
    2739                         for (var n in stc) {
     2759                        for (n in stc) {
    27402760                                if (typeof(stc[n]) == 'function')
    27412761                                        continue;
     
    27532773        },
    27542774
     2775        _fixRootBlocks : function() {
     2776                var rb, b, ne, be, nx, bm;
     2777
     2778                rb = tinyMCE.getParam('forced_root_block');
     2779                if (!rb)
     2780                        return;
     2781
     2782                b = this.getBody();
     2783                ne = b.firstChild;
     2784
     2785                while (ne) {
     2786                        nx = ne.nextSibling;
     2787
     2788                        // If text node or inline element wrap it in a block element
     2789                        if (ne.nodeType == 3 || !tinyMCE.blockRegExp.test(ne.nodeName)) {
     2790                                if (!bm)
     2791                                        bm = this.selection.getBookmark();
     2792
     2793                                if (!be) {
     2794                                        be = this.getDoc().createElement(rb);
     2795                                        be.appendChild(ne.cloneNode(true));
     2796                                        b.replaceChild(be, ne);
     2797                                } else {
     2798                                        be.appendChild(ne.cloneNode(true));
     2799                                        b.removeChild(ne);
     2800                                }
     2801                        } else
     2802                                be = null;
     2803
     2804                        ne = nx;
     2805                }
     2806
     2807                if (bm)
     2808                        this.selection.moveToBookmark(bm);
     2809        },
     2810
     2811        _fixTrailingNbsp : function() {
     2812                var s = this.selection, e = s.getFocusElement(), bm, v;
     2813
     2814                if (e && tinyMCE.blockRegExp.test(e.nodeName) && e.firstChild) {
     2815                        v = e.firstChild.nodeValue;
     2816
     2817                        if (v && v.length > 1 && /(^\u00a0|\u00a0$)/.test(v)) {
     2818                                e.firstChild.nodeValue = v.replace(/(^\u00a0|\u00a0$)/, '');
     2819                                s.selectNode(e.firstChild, true, false, false); // Select and collapse
     2820                        }
     2821                }
     2822        },
     2823
    27552824        _setUseCSS : function(b) {
    27562825                var d = this.getDoc();
     
    27672836
    27682837        execCommand : function(command, user_interface, value) {
    2769                 var doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement();
     2838                var i, x, z, align, img, div, doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement();
    27702839
    27712840                // Is not a undo specific command
     
    27902859                // Fix align on images
    27912860                if (focusElm && focusElm.nodeName == "IMG") {
    2792                         var align = focusElm.getAttribute('align');
    2793                         var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm;
     2861                        align = focusElm.getAttribute('align');
     2862                        img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm;
    27942863
    27952864                        switch (command) {
     
    28012870
    28022871                                        // Remove the div
    2803                                         var div = focusElm.parentNode;
     2872                                        div = focusElm.parentNode;
    28042873                                        if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
    28052874                                                div.parentNode.replaceChild(img, div);
     
    28142883
    28152884                                        // Is centered
    2816                                         var div = tinyMCE.getParentElement(focusElm, "div");
     2885                                        div = tinyMCE.getParentElement(focusElm, "div");
    28172886                                        if (div && div.style.textAlign == "center") {
    28182887                                                // Remove div
     
    28212890                                        } else {
    28222891                                                // Add div
    2823                                                 var div = this.getDoc().createElement("div");
     2892                                                div = this.getDoc().createElement("div");
    28242893                                                div.style.textAlign = 'center';
    28252894                                                div.appendChild(img);
     
    28392908
    28402909                                        // Remove the div
    2841                                         var div = focusElm.parentNode;
     2910                                        div = focusElm.parentNode;
    28422911                                        if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
    28432912                                                div.parentNode.replaceChild(img, div);
     
    28502919                }
    28512920
    2852                 if (tinyMCE.settings['force_br_newlines']) {
     2921                if (tinyMCE.settings.force_br_newlines) {
    28532922                        var alignValue = "";
    28542923
     
    28722941                                }
    28732942
    2874                                 if (alignValue != "") {
     2943                                if (alignValue !== '') {
    28752944                                        var rng = doc.selection.createRange();
    28762945
     
    29262995
    29272996                        case "FormatBlock":
    2928                                 if (value == null || value == "") {
     2997                                if (value == null || value == '') {
    29292998                                        var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp");
    29302999
     
    29713040                        case "mceSelectNodeDepth":
    29723041                                var parentNode = this.getFocusElement();
    2973                                 for (var i=0; parentNode; i++) {
     3042                                for (i=0; parentNode; i++) {
    29743043                                        if (parentNode.nodeName.toLowerCase() == "body")
    29753044                                                break;
     
    29973066                                var rng = this.getRng();
    29983067                                var sel = this.getSel();
    2999                                 var scmd = value['command'];
    3000                                 var sname = value['name'];
    3001                                 var svalue = value['value'] == null ? '' : value['value'];
     3068                                var scmd = value.command;
     3069                                var sname = value.name;
     3070                                var svalue = value.value == null ? '' : value.value;
    30023071                                //var svalue = value['value'] == null ? '' : value['value'];
    3003                                 var wrapper = value['wrapper'] ? value['wrapper'] : "span";
     3072                                var wrapper = value.wrapper ? value.wrapper : "span";
    30043073                                var parentElm = null;
    30053074                                var invalidRe = new RegExp("^BODY|HTML$", "g");
    3006                                 var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null;
     3075                                var invalidParentsRe = tinyMCE.settings.merge_styles_invalid_parents !== '' ? new RegExp(tinyMCE.settings.merge_styles_invalid_parents, "gi") : null;
    30073076
    30083077                                // Whole element selected check
     
    30233092                                } else {
    30243093                                        var felm = this.getFocusElement();
    3025                                         if (sel.isCollapsed || (new RegExp('td|tr|tbody|table', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode))
     3094                                        if (sel.isCollapsed || (new RegExp('td|tr|tbody|table|img', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode))
    30263095                                                parentElm = felm;
    30273096                                }
     
    30413110
    30423111                                        // Remove style/attribs from all children
    3043                                         var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1);
    3044                                         for (var z=0; z<ch.length; z++) {
     3112                                        var ch = tinyMCE.getNodeTree(parentElm, [], 1);
     3113                                        for (z=0; z<ch.length; z++) {
    30453114                                                if (ch[z] == parentElm)
    30463115                                                        continue;
     
    30633132
    30643133                                        // Change them all
    3065                                         for (var x=0; x<elementArray.length; x++) {
     3134                                        for (x=0; x<elementArray.length; x++) {
    30663135                                                elm = elementArray[x];
    30673136                                                if (elm) {
     
    30803149
    30813150                                                        if (elm.hasChildNodes()) {
    3082                                                                 for (var i=0; i<elm.childNodes.length; i++)
     3151                                                                for (i=0; i<elm.childNodes.length; i++)
    30833152                                                                        spanElm.appendChild(elm.childNodes[i].cloneNode(true));
    30843153                                                        }
     
    30883157
    30893158                                                        // Remove style/attribs from all children
    3090                                                         var ch = tinyMCE.getNodeTree(spanElm, new Array(), 1);
    3091                                                         for (var z=0; z<ch.length; z++) {
     3159                                                        var ch = tinyMCE.getNodeTree(spanElm, [], 1);
     3160                                                        for (z=0; z<ch.length; z++) {
    30923161                                                                if (ch[z] == spanElm)
    30933162                                                                        continue;
     
    31103179                                // Cleaup wrappers
    31113180                                var nodes = doc.getElementsByTagName(wrapper);
    3112                                 for (var i=nodes.length-1; i>=0; i--) {
     3181                                for (i=nodes.length-1; i>=0; i--) {
    31133182                                        var elm = nodes[i];
    31143183                                        var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true";
     
    31333202                                // Remove empty wrappers
    31343203                                var nodes = doc.getElementsByTagName(wrapper);
    3135                                 for (var i=nodes.length-1; i>=0; i--) {
    3136                                         var elm = nodes[i];
    3137                                         var isEmpty = true;
     3204                                for (i=nodes.length-1; i>=0; i--) {
     3205                                        var elm = nodes[i], isEmpty = true;
    31383206
    31393207                                        // Check if it has any attribs
     
    31453213                                        //tinyMCE.debug(tmp.innerHTML);
    31463214                                        if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) {
    3147                                                 for (var x=0; x<elm.childNodes.length; x++) {
     3215                                                for (x=0; x<elm.childNodes.length; x++) {
    31483216                                                        if (elm.parentNode != null)
    31493217                                                                elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm);
     
    32703338                                tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
    32713339                                tinyMCE._setEventsEnabled(this.getBody(), false);
     3340                                this._addBogusBR();
     3341
    32723342                                return true;
    32733343
     
    32843354                                tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
    32853355                                tinyMCE._setEventsEnabled(this.getBody(), false);
     3356                                this._addBogusBR();
    32863357                                this.repaint();
    32873358                                this.selection.moveToBookmark(b);
     
    33093380                                }
    33103381
     3382                                this._addBogusBR();
    33113383                                tinyMCE.triggerNodeChange();
    33123384                        break;
     
    33143386                        case "mceSetAttribute":
    33153387                                if (typeof(value) == 'object') {
    3316                                         var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets'];
     3388                                        var targetElms = (typeof(value.targets) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value.targets;
    33173389                                        var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms);
    33183390
    33193391                                        if (targetNode) {
    3320                                                 targetNode.setAttribute(value['name'], value['value']);
     3392                                                targetNode.setAttribute(value.name, value.value);
    33213393                                                tinyMCE.triggerNodeChange();
    33223394                                        }
     
    34133485                                        } else {
    34143486                                                // Setup text node
    3415                                                 var el = document.createElement("div");
    3416                                                 el.innerHTML = value;
    3417                                                 value = el.firstChild.nodeValue;
    3418                                                 value = doc.createTextNode(value);
     3487                                                value = doc.createTextNode(tinyMCE.entityDecode(value));
    34193488                                        }
    34203489
     
    34863555
    34873556                        case "mceStartTyping":
    3488                                 if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex == -1) {
     3557                                if (tinyMCE.settings.custom_undo_redo && this.undoRedo.typingUndoIndex == -1) {
    34893558                                        this.undoRedo.typingUndoIndex = this.undoRedo.undoIndex;
    34903559                                        tinyMCE.typingUndoIndex = tinyMCE.undoIndex;
     
    34943563
    34953564                        case "mceEndTyping":
    3496                                 if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex != -1) {
     3565                                if (tinyMCE.settings.custom_undo_redo && this.undoRedo.typingUndoIndex != -1) {
    34973566                                        this.execCommand('mceAddUndoLevel');
    34983567                                        this.undoRedo.typingUndoIndex = -1;
     
    35123581
    35133582                        case "mceAddUndoLevel":
    3514                                 if (tinyMCE.settings['custom_undo_redo'] && this.undoRedoLevel) {
     3583                                if (tinyMCE.settings.custom_undo_redo && this.undoRedoLevel) {
    35153584                                        if (this.undoRedo.add())
    35163585                                                tinyMCE.triggerNodeChange(false);
     
    35193588
    35203589                        case "Undo":
    3521                                 if (tinyMCE.settings['custom_undo_redo']) {
     3590                                if (tinyMCE.settings.custom_undo_redo) {
    35223591                                        tinyMCE.execCommand("mceEndTyping");
    35233592                                        this.undoRedo.undo();
     
    35283597
    35293598                        case "Redo":
    3530                                 if (tinyMCE.settings['custom_undo_redo']) {
     3599                                if (tinyMCE.settings.custom_undo_redo) {
    35313600                                        tinyMCE.execCommand("mceEndTyping");
    35323601                                        this.undoRedo.redo();
     
    36143683        },
    36153684
     3685        _addBogusBR : function() {
     3686                var b = this.getBody();
     3687
     3688                if (tinyMCE.isGecko && !b.hasChildNodes())
     3689                        b.innerHTML = '<br _moz_editor_bogus_node="TRUE" />';
     3690        },
     3691
    36163692        _onAdd : function(replace_element, form_element_name, target_document) {
    3617                 var hc, th, to, editorTemplate;
    3618 
    3619                 th = this.settings['theme'];
    3620                 to = tinyMCE.themes[th];
    3621 
    3622                 var targetDoc = target_document ? target_document : document;
     3693                var hc, th, tos, editorTemplate, targetDoc, deltaWidth, deltaHeight, html, rng, fragment;
     3694                var dynamicIFrame, tElm, doc, parentElm;
     3695
     3696                th = this.settings.theme;
     3697                tos = tinyMCE.themes[th];
     3698
     3699                targetDoc = target_document ? target_document : document;
    36233700
    36243701                this.targetDoc = targetDoc;
    36253702
    3626                 tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme'];
    3627                 this.settings['themeurl'] = tinyMCE.themeURL;
     3703                tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings.theme;
     3704                this.settings.themeurl = tinyMCE.themeURL;
    36283705
    36293706                if (!replace_element) {
     
    36323709                }
    36333710
    3634                 if (to.getEditorTemplate)
    3635                         editorTemplate = to.getEditorTemplate(this.settings, this.editorId);
    3636 
    3637                 var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0;
    3638                 var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0;
    3639                 var html = '<span id="' + this.editorId + '_parent" class="mceEditorContainer">' + editorTemplate['html'];
     3711                if (tos.getEditorTemplate)
     3712                        editorTemplate = tos.getEditorTemplate(this.settings, this.editorId);
     3713
     3714                deltaWidth = editorTemplate.delta_width ? editorTemplate.delta_width : 0;
     3715                deltaHeight = editorTemplate.delta_height ? editorTemplate.delta_height : 0;
     3716                html = '<span id="' + this.editorId + '_parent" class="mceEditorContainer">' + editorTemplate.html;
    36403717
    36413718                html = tinyMCE.replaceVar(html, "editor_id", this.editorId);
    3642                 this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm";
    3643 
    3644                 this.settings['old_width'] = this.settings['width'];
    3645                 this.settings['old_height'] = this.settings['height'];
     3719
     3720                if (!this.settings.default_document)
     3721                        this.settings.default_document = tinyMCE.baseURL + "/blank.htm";
     3722
     3723                this.settings.old_width = this.settings.width;
     3724                this.settings.old_height = this.settings.height;
    36463725
    36473726                // Set default width, height
    3648                 if (this.settings['width'] == -1)
    3649                         this.settings['width'] = replace_element.offsetWidth;
    3650 
    3651                 if (this.settings['height'] == -1)
    3652                         this.settings['height'] = replace_element.offsetHeight;
     3727                if (this.settings.width == -1)
     3728                        this.settings.width = replace_element.offsetWidth;
     3729
     3730                if (this.settings.height == -1)
     3731                        this.settings.height = replace_element.offsetHeight;
    36533732
    36543733                // Try the style width
    3655                 if (this.settings['width'] == 0)
    3656                         this.settings['width'] = replace_element.style.width;
     3734                if (this.settings.width == 0)
     3735                        this.settings.width = replace_element.style.width;
    36573736
    36583737                // Try the style height
    3659                 if (this.settings['height'] == 0)
    3660                         this.settings['height'] = replace_element.style.height;
     3738                if (this.settings.height == 0)
     3739                        this.settings.height = replace_element.style.height;
    36613740
    36623741                // If no width/height then default to 320x240, better than nothing
    3663                 if (this.settings['width'] == 0)
    3664                         this.settings['width'] = 320;
    3665 
    3666                 if (this.settings['height'] == 0)
    3667                         this.settings['height'] = 240;
    3668 
    3669                 this.settings['area_width'] = parseInt(this.settings['width']);
    3670                 this.settings['area_height'] = parseInt(this.settings['height']);
    3671                 this.settings['area_width'] += deltaWidth;
    3672                 this.settings['area_height'] += deltaHeight;
    3673 
    3674                 this.settings['width_style'] = "" + this.settings['width'];
    3675                 this.settings['height_style'] = "" + this.settings['height'];
     3742                if (this.settings.width == 0)
     3743                        this.settings.width = 320;
     3744
     3745                if (this.settings.height == 0)
     3746                        this.settings.height = 240;
     3747
     3748                this.settings.area_width = parseInt(this.settings.width);
     3749                this.settings.area_height = parseInt(this.settings.height);
     3750                this.settings.area_width += deltaWidth;
     3751                this.settings.area_height += deltaHeight;
     3752                this.settings.width_style = "" + this.settings.width;
     3753                this.settings.height_style = "" + this.settings.height;
    36763754
    36773755                // Special % handling
    3678                 if (("" + this.settings['width']).indexOf('%') != -1)
    3679                         this.settings['area_width'] = "100%";
     3756                if (("" + this.settings.width).indexOf('%') != -1)
     3757                        this.settings.area_width = "100%";
    36803758                else
    3681                         this.settings['width_style'] += 'px';
    3682 
    3683                 if (("" + this.settings['height']).indexOf('%') != -1)
    3684                         this.settings['area_height'] = "100%";
     3759                        this.settings.width_style += 'px';
     3760
     3761                if (("" + this.settings.height).indexOf('%') != -1)
     3762                        this.settings.area_height = "100%";
    36853763                else
    3686                         this.settings['height_style'] += 'px';
     3764                        this.settings.height_style += 'px';
    36873765
    36883766                if (("" + replace_element.style.width).indexOf('%') != -1) {
    3689                         this.settings['width'] = replace_element.style.width;
    3690                         this.settings['area_width'] = "100%";
    3691                         this.settings['width_style'] = "100%";
     3767                        this.settings.width = replace_element.style.width;
     3768                        this.settings.area_width = "100%";
     3769                        this.settings.width_style = "100%";
    36923770                }
    36933771
    36943772                if (("" + replace_element.style.height).indexOf('%') != -1) {
    3695                         this.settings['height'] = replace_element.style.height;
    3696                         this.settings['area_height'] = "100%";
    3697                         this.settings['height_style'] = "100%";
     3773                        this.settings.height = replace_element.style.height;
     3774                        this.settings.area_height = "100%";
     3775                        this.settings.height_style = "100%";
    36983776                }
    36993777
    37003778                html = tinyMCE.applyTemplate(html);
    37013779
    3702                 this.settings['width'] = this.settings['old_width'];
    3703                 this.settings['height'] = this.settings['old_height'];
    3704 
    3705                 this.visualAid = this.settings['visual'];
     3780                this.settings.width = this.settings.old_width;
     3781                this.settings.height = this.settings.old_height;
     3782
     3783                this.visualAid = this.settings.visual;
    37063784                this.formTargetElementId = form_element_name;
    37073785
     
    37173795
    37183796                        // Debug mode
    3719                         if (tinyMCE.settings['debug']) {
    3720                                 hc = '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>';
    3721                         } else {
    3722                                 hc = '<input type="hidden" id="' + form_element_name + '" name="' + form_element_name + '" />';
    3723                                 this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
    3724                                 this.oldTargetElement.style.display = "none";
    3725                         }
     3797                        hc = '<input type="hidden" id="' + form_element_name + '" name="' + form_element_name + '" />';
     3798                        this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
     3799                        this.oldTargetElement.style.display = "none";
    37263800
    37273801                        html += '</span>';
     
    37343808                        // Output HTML and set editable
    37353809                        if (tinyMCE.isGecko) {
    3736                                 var rng = replace_element.ownerDocument.createRange();
     3810                                rng = replace_element.ownerDocument.createRange();
    37373811                                rng.setStartBefore(replace_element);
    37383812
    3739                                 var fragment = rng.createContextualFragment(html);
     3813                                fragment = rng.createContextualFragment(html);
    37403814                                tinyMCE.insertAfter(fragment, replace_element);
    37413815                        } else
     
    37473821                        this.oldTargetElement = replace_element;
    37483822
    3749                         if (!tinyMCE.settings['debug']) {
    3750                                 this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
    3751                                 this.oldTargetElement.style.display = "none";
    3752                         }
     3823                        this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
     3824                        this.oldTargetElement.style.display = "none";
    37533825
    37543826                        // Output HTML and set editable
    37553827                        if (tinyMCE.isGecko) {
    3756                                 var rng = replace_element.ownerDocument.createRange();
     3828                                rng = replace_element.ownerDocument.createRange();
    37573829                                rng.setStartBefore(replace_element);
    37583830
    3759                                 var fragment = rng.createContextualFragment(html);
     3831                                fragment = rng.createContextualFragment(html);
    37603832                                tinyMCE.insertAfter(fragment, replace_element);
    37613833                        } else
     
    37643836
    37653837                // Setup iframe
    3766                 var dynamicIFrame = false;
    3767                 var tElm = targetDoc.getElementById(this.editorId);
     3838                dynamicIFrame = false;
     3839                tElm = targetDoc.getElementById(this.editorId);
    37683840
    37693841                if (!tinyMCE.isIE) {
     
    38023874
    38033875                // Setup base HTML
    3804                 var doc = this.contentDocument;
     3876                doc = this.contentDocument;
    38053877                if (dynamicIFrame) {
    3806                         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>';
     3878                        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>';
    38073879
    38083880                        try {
     
    38253897
    38263898                // Setup element references
    3827                 var parentElm = this.targetDoc.getElementById(this.editorId + '_parent');
     3899                parentElm = this.targetDoc.getElementById(this.editorId + '_parent');
    38283900                this.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling;
    38293901
     
    38483920                        h.appendChild(b);
    38493921                } else {
    3850                         if (u == "" || u == null)
     3922                        if (u == '' || u == null)
    38513923                                b.parentNode.removeChild(b);
    38523924                        else
     
    38873959
    38883960        triggerSave : function(skip_cleanup, skip_callback) {
    3889                 var e, nl = [], i, s;
     3961                var e, nl = [], i, s, content, htm;
     3962
     3963                if (!this.enabled)
     3964                        return;
    38903965
    38913966                this.switchSettings();
     
    39093984                }
    39103985
    3911                 tinyMCE.settings['preformatted'] = false;
     3986                tinyMCE.settings.preformatted = false;
    39123987
    39133988                // Default to false
     
    39223997
    39233998                // Remove visual aids when cleanup is disabled
    3924                 if (this.settings['cleanup'] == false) {
     3999                if (this.settings.cleanup == false) {
    39254000                        tinyMCE.handleVisualAid(this.getBody(), true, false, this);
    39264001                        tinyMCE._setEventsEnabled(this.getBody(), true);
     
    39284003
    39294004                tinyMCE._customCleanup(this, "submit_content_dom", this.contentWindow.document.body);
    3930                 var htm = skip_cleanup ? this.getBody().innerHTML : tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true);
     4005                htm = skip_cleanup ? this.getBody().innerHTML : tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true);
    39314006                htm = tinyMCE._customCleanup(this, "submit_content", htm);
    39324007
    3933                 if (!skip_callback && tinyMCE.settings['save_callback'] != "")
    3934                         var content = eval(tinyMCE.settings['save_callback'] + "(this.formTargetElementId,htm,this.getBody());");
     4008                if (!skip_callback && tinyMCE.settings.save_callback !== '')
     4009                        content = tinyMCE.resolveDots(tinyMCE.settings.save_callback, window)(this.formTargetElementId,htm,this.getBody());
    39354010
    39364011                // Use callback content if available
     
    39644039/* file:jscripts/tiny_mce/classes/TinyMCE_Cleanup.class.js */
    39654040
    3966 TinyMCE_Engine.prototype.cleanupHTMLCode = function(s) {
    3967         s = s.replace(new RegExp('<p \\/>', 'gi'), '<p>&nbsp;</p>');
    3968         s = s.replace(new RegExp('<p>\\s*<\\/p>', 'gi'), '<p>&nbsp;</p>');
    3969 
    3970         // Fix close BR elements
    3971         s = s.replace(new RegExp('<br>\\s*<\\/br>', 'gi'), '<br />');
    3972 
    3973         // Open closed tags like <b/> to <b></b>
    3974         s = s.replace(new RegExp('<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|font|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\\\|>]*)\\/>', 'gi'), '<$1$2$3></$1$2>');
    3975 
    3976         // Remove trailing space <b > to <b>
    3977         s = s.replace(new RegExp('\\s+></', 'gi'), '></');
    3978 
    3979         // Close tags <img></img> to <img/>
    3980         s = s.replace(new RegExp('<(img|br|hr)([^>]*)><\\/(img|br|hr)>', 'gi'), '<$1$2 />');
    3981 
    3982         // Weird MSIE bug, <p><hr /></p> breaks runtime?
    3983         if (tinyMCE.isIE)
    3984                 s = s.replace(new RegExp('<p><hr \\/><\\/p>', 'gi'), "<hr>");
    3985 
    3986         // Weird tags will make IE error #bug: 1538495
    3987         if (tinyMCE.isIE)
    3988                 s = s.replace(/<!(\s*)\/>/g, '');
    3989 
    3990         // Convert relative anchors to absolute URLs ex: #something to file.htm#something
    3991         // Removed: Since local document anchors should never be forced absolute example edit.php?id=something
    3992         //if (tinyMCE.getParam('convert_urls'))
    3993         //      s = s.replace(new RegExp('(href=\"{0,1})(\\s*#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#");
    3994 
    3995         return s;
    3996 };
    3997 
    3998 TinyMCE_Engine.prototype.parseStyle = function(str) {
    3999         var ar = new Array();
    4000 
    4001         if (str == null)
     4041tinyMCE.add(TinyMCE_Engine, {
     4042        cleanupHTMLCode : function(s) {
     4043                s = s.replace(new RegExp('<p \\/>', 'gi'), '<p>&nbsp;</p>');
     4044                s = s.replace(new RegExp('<p>\\s*<\\/p>', 'gi'), '<p>&nbsp;</p>');
     4045
     4046                // Fix close BR elements
     4047                s = s.replace(new RegExp('<br>\\s*<\\/br>', 'gi'), '<br />');
     4048
     4049                // Open closed tags like <b/> to <b></b>
     4050                s = s.replace(new RegExp('<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|font|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\\\|>]*)\\/>', 'gi'), '<$1$2$3></$1$2>');
     4051
     4052                // Remove trailing space <b > to <b>
     4053                s = s.replace(new RegExp('\\s+></', 'gi'), '></');
     4054
     4055                // Close tags <img></img> to <img/>
     4056                s = s.replace(new RegExp('<(img|br|hr)([^>]*)><\\/(img|br|hr)>', 'gi'), '<$1$2 />');
     4057
     4058                // Weird MSIE bug, <p><hr /></p> breaks runtime?
     4059                if (tinyMCE.isIE)
     4060                        s = s.replace(new RegExp('<p><hr \\/><\\/p>', 'gi'), "<hr>");
     4061
     4062                // Weird tags will make IE error #bug: 1538495
     4063                if (tinyMCE.isIE)
     4064                        s = s.replace(/<!(\s*)\/>/g, '');
     4065
     4066                // Convert relative anchors to absolute URLs ex: #something to file.htm#something
     4067                // Removed: Since local document anchors should never be forced absolute example edit.php?id=something
     4068                //if (tinyMCE.getParam('convert_urls'))
     4069                //      s = s.replace(new RegExp('(href=\"{0,1})(\\s*#)', 'gi'), '$1' + tinyMCE.settings.document_base_url + "#");
     4070
     4071                return s;
     4072        },
     4073
     4074        parseStyle : function(str) {
     4075                var ar = [], st, i, re, pa;
     4076
     4077                if (str == null)
     4078                        return ar;
     4079
     4080                st = str.split(';');
     4081
     4082                tinyMCE.clearArray(ar);
     4083
     4084                for (i=0; i<st.length; i++) {
     4085                        if (st[i] == '')
     4086                                continue;
     4087
     4088                        re = new RegExp('^\\s*([^:]*):\\s*(.*)\\s*$');
     4089                        pa = st[i].replace(re, '$1||$2').split('||');
     4090        //tinyMCE.debug(str, pa[0] + "=" + pa[1], st[i].replace(re, '$1||$2'));
     4091                        if (pa.length == 2)
     4092                                ar[pa[0].toLowerCase()] = pa[1];
     4093                }
     4094
    40024095                return ar;
    4003 
    4004         var st = str.split(';');
    4005 
    4006         tinyMCE.clearArray(ar);
    4007 
    4008         for (var i=0; i<st.length; i++) {
    4009                 if (st[i] == '')
    4010                         continue;
    4011 
    4012                 var re = new RegExp('^\\s*([^:]*):\\s*(.*)\\s*$');
    4013                 var pa = st[i].replace(re, '$1||$2').split('||');
    4014 //tinyMCE.debug(str, pa[0] + "=" + pa[1], st[i].replace(re, '$1||$2'));
    4015                 if (pa.length == 2)
    4016                         ar[pa[0].toLowerCase()] = pa[1];
    4017         }
    4018 
    4019         return ar;
    4020 };
    4021 
    4022 TinyMCE_Engine.prototype.compressStyle = function(ar, pr, sf, res) {
    4023         var box = new Array();
    4024 
    4025         box[0] = ar[pr + '-top' + sf];
    4026         box[1] = ar[pr + '-left' + sf];
    4027         box[2] = ar[pr + '-right' + sf];
    4028         box[3] = ar[pr + '-bottom' + sf];
    4029 
    4030         for (var i=0; i<box.length; i++) {
    4031                 if (box[i] == null)
    4032                         return;
    4033 
    4034                 for (var a=0; a<box.length; a++) {
    4035                         if (box[a] != box[i])
     4096        },
     4097
     4098        compressStyle : function(ar, pr, sf, res) {
     4099                var box = [], i, a;
     4100
     4101                box[0] = ar[pr + '-top' + sf];
     4102                box[1] = ar[pr + '-left' + sf];
     4103                box[2] = ar[pr + '-right' + sf];
     4104                box[3] = ar[pr + '-bottom' + sf];
     4105
     4106                for (i=0; i<box.length; i++) {
     4107                        if (box[i] == null)
    40364108                                return;
    4037                 }
    4038         }
    4039 
    4040         // They are all the same
    4041         ar[res] = box[0];
    4042         ar[pr + '-top' + sf] = null;
    4043         ar[pr + '-left' + sf] = null;
    4044         ar[pr + '-right' + sf] = null;
    4045         ar[pr + '-bottom' + sf] = null;
    4046 };
    4047 
    4048 TinyMCE_Engine.prototype.serializeStyle = function(ar) {
    4049         var str = "";
    4050 
    4051         // Compress box
    4052         tinyMCE.compressStyle(ar, "border", "", "border");
    4053         tinyMCE.compressStyle(ar, "border", "-width", "border-width");
    4054         tinyMCE.compressStyle(ar, "border", "-color", "border-color");
    4055         tinyMCE.compressStyle(ar, "border", "-style", "border-style");
    4056         tinyMCE.compressStyle(ar, "padding", "", "padding");
    4057         tinyMCE.compressStyle(ar, "margin", "", "margin");
    4058 
    4059         for (var key in ar) {
    4060                 var val = ar[key];
    4061 
    4062                 if (typeof(val) == 'function')
    4063                         continue;
    4064 
    4065                 if (key.indexOf('mso-') == 0)
    4066                         continue;
    4067 
    4068                 if (val != null && val != '') {
    4069                         val = '' + val; // Force string
    4070 
    4071                         // Fix style URL
    4072                         val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')");
    4073 
    4074                         // Convert URL
    4075                         if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) {
    4076                                 var m = new RegExp("url\\('(.*?)'\\)").exec(val);
    4077 
    4078                                 if (m.length > 1)
    4079                                         val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')";
    4080                         }
    4081 
    4082                         // Force HEX colors
    4083                         if (tinyMCE.getParam("force_hex_style_colors"))
    4084                                 val = tinyMCE.convertRGBToHex(val, true);
    4085 
    4086                         val = val.replace(/\"/g, '\'');
    4087 
    4088                         if (val != "url('')")
    4089                                 str += key.toLowerCase() + ": " + val + "; ";
    4090                 }
    4091         }
    4092 
    4093         if (new RegExp('; $').test(str))
    4094                 str = str.substring(0, str.length - 2);
    4095 
    4096         return str;
    4097 };
    4098 
    4099 TinyMCE_Engine.prototype.convertRGBToHex = function(s, k) {
    4100         if (s.toLowerCase().indexOf('rgb') != -1) {
    4101                 var re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
    4102                 var rgb = s.replace(re, "$1,$2,$3,$4,$5").split(',');
    4103                 if (rgb.length == 5) {
    4104                         r = parseInt(rgb[1]).toString(16);
    4105                         g = parseInt(rgb[2]).toString(16);
    4106                         b = parseInt(rgb[3]).toString(16);
    4107 
    4108                         r = r.length == 1 ? '0' + r : r;
    4109                         g = g.length == 1 ? '0' + g : g;
    4110                         b = b.length == 1 ? '0' + b : b;
    4111 
    4112                         s = "#" + r + g + b;
    4113 
    4114                         if (k)
    4115                                 s = rgb[0] + s + rgb[4];
    4116                 }
    4117         }
    4118 
    4119         return s;
    4120 };
    4121 
    4122 TinyMCE_Engine.prototype.convertHexToRGB = function(s) {
    4123         if (s.indexOf('#') != -1) {
    4124                 s = s.replace(new RegExp('[^0-9A-F]', 'gi'), '');
    4125                 return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")";
    4126         }
    4127 
    4128         return s;
    4129 };
    4130 
    4131 TinyMCE_Engine.prototype.convertSpansToFonts = function(doc) {
    4132         var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
    4133 
    4134         /*var h = doc.body.innerHTML;
    4135         h = h.replace(/<span/gi, '<font');
    4136         h = h.replace(/<\/span/gi, '</font');
    4137         tinyMCE.setInnerHTML(doc.body, h);*/
    4138 
    4139         var s = tinyMCE.selectElements(doc, 'span,font');
    4140         for (var i=0; i<s.length; i++) {
    4141                 var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();
    4142                 var fSize = 0;
    4143 
    4144                 for (var x=0; x<sizes.length; x++) {
    4145                         if (sizes[x] == size) {
    4146                                 fSize = x + 1;
    4147                                 break;
    4148                         }
    4149                 }
    4150 
    4151                 if (fSize > 0) {
    4152                         tinyMCE.setAttrib(s[i], 'size', fSize);
    4153                         s[i].style.fontSize = '';
    4154                 }
    4155 
    4156                 var fFace = s[i].style.fontFamily;
    4157                 if (fFace != null && fFace != "") {
    4158                         tinyMCE.setAttrib(s[i], 'face', fFace);
    4159                         s[i].style.fontFamily = '';
    4160                 }
    4161 
    4162                 var fColor = s[i].style.color;
    4163                 if (fColor != null && fColor != "") {
    4164                         tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));
    4165                         s[i].style.color = '';
    4166                 }
    4167         }
    4168 };
    4169 
    4170 TinyMCE_Engine.prototype.convertFontsToSpans = function(doc) {
    4171         var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
    4172 
    4173 /*      var h = doc.body.innerHTML;
    4174         h = h.replace(/<font/gi, '<span');
    4175         h = h.replace(/<\/font/gi, '</span');
    4176         tinyMCE.setInnerHTML(doc.body, h);*/
    4177 
    4178         var fsClasses = tinyMCE.getParam('font_size_classes');
    4179         if (fsClasses != '')
    4180                 fsClasses = fsClasses.replace(/\s+/, '').split(',');
    4181         else
    4182                 fsClasses = null;
    4183 
    4184         var s = tinyMCE.selectElements(doc, 'span,font');
    4185         for (var i=0; i<s.length; i++) {
    4186                 var fSize, fFace, fColor;
    4187 
    4188                 fSize = tinyMCE.getAttrib(s[i], 'size');
    4189                 fFace = tinyMCE.getAttrib(s[i], 'face');
    4190                 fColor = tinyMCE.getAttrib(s[i], 'color');
    4191 
    4192                 if (fSize != "") {
    4193                         fSize = parseInt(fSize);
    4194 
    4195                         if (fSize > 0 && fSize < 8) {
    4196                                 if (fsClasses != null)
    4197                                         tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);
    4198                                 else
    4199                                         s[i].style.fontSize = sizes[fSize-1];
    4200                         }
    4201 
    4202                         s[i].removeAttribute('size');
    4203                 }
    4204 
    4205                 if (fFace != "") {
    4206                         s[i].style.fontFamily = fFace;
    4207                         s[i].removeAttribute('face');
    4208                 }
    4209 
    4210                 if (fColor != "") {
    4211                         s[i].style.color = fColor;
    4212                         s[i].removeAttribute('color');
    4213                 }
    4214         }
    4215 };
    4216 
    4217 TinyMCE_Engine.prototype.cleanupAnchors = function(doc) {
    4218         var i, cn, x, an = doc.getElementsByTagName("a");
    4219 
    4220         // Loops backwards due to bug #1467987
    4221         for (i=an.length-1; i>=0; i--) {
    4222                 if (tinyMCE.getAttrib(an[i], "name") != "" && tinyMCE.getAttrib(an[i], "href") == "") {
    4223                         cn = an[i].childNodes;
    4224 
    4225                         for (x=cn.length-1; x>=0; x--)
    4226                                 tinyMCE.insertAfter(cn[x], an[i]);
    4227                 }
    4228         }
    4229 };
    4230 
    4231 TinyMCE_Engine.prototype.getContent = function(editor_id) {
    4232         if (typeof(editor_id) != "undefined")
    4233                  tinyMCE.getInstanceById(editor_id).select();
    4234 
    4235         if (tinyMCE.selectedInstance)
    4236                 return tinyMCE.selectedInstance.getHTML();
    4237 
    4238         return null;
    4239 };
    4240 
    4241 TinyMCE_Engine.prototype._fixListElements = function(d) {
    4242         var nl, x, a = ['ol', 'ul'], i, n, p, r = new RegExp('^(OL|UL)$'), np;
    4243 
    4244         for (x=0; x<a.length; x++) {
    4245                 nl = d.getElementsByTagName(a[x]);
    4246 
     4109
     4110                        for (a=0; a<box.length; a++) {
     4111                                if (box[a] != box[i])
     4112                                        return;
     4113                        }
     4114                }
     4115
     4116                // They are all the same
     4117                ar[res] = box[0];
     4118                ar[pr + '-top' + sf] = null;
     4119                ar[pr + '-left' + sf] = null;
     4120                ar[pr + '-right' + sf] = null;
     4121                ar[pr + '-bottom' + sf] = null;
     4122        },
     4123
     4124        serializeStyle : function(ar) {
     4125                var str = "", key, val, m;
     4126
     4127                // Compress box
     4128                tinyMCE.compressStyle(ar, "border", "", "border");
     4129                tinyMCE.compressStyle(ar, "border", "-width", "border-width");
     4130                tinyMCE.compressStyle(ar, "border", "-color", "border-color");
     4131                tinyMCE.compressStyle(ar, "border", "-style", "border-style");
     4132                tinyMCE.compressStyle(ar, "padding", "", "padding");
     4133                tinyMCE.compressStyle(ar, "margin", "", "margin");
     4134
     4135                for (key in ar) {
     4136                        val = ar[key];
     4137
     4138                        if (typeof(val) == 'function')
     4139                                continue;
     4140
     4141                        if (key.indexOf('mso-') == 0)
     4142                                continue;
     4143
     4144                        if (val != null && val !== '') {
     4145                                val = '' + val; // Force string
     4146
     4147                                // Fix style URL
     4148                                val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')");
     4149
     4150                                // Convert URL
     4151                                if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) {
     4152                                        m = new RegExp("url\\('(.*?)'\\)").exec(val);
     4153
     4154                                        if (m.length > 1)
     4155                                                val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')";
     4156                                }
     4157
     4158                                // Force HEX colors
     4159                                if (tinyMCE.getParam("force_hex_style_colors"))
     4160                                        val = tinyMCE.convertRGBToHex(val, true);
     4161
     4162                                val = val.replace(/\"/g, '\'');
     4163
     4164                                if (val != "url('')")
     4165                                        str += key.toLowerCase() + ": " + val + "; ";
     4166                        }
     4167                }
     4168
     4169                if (new RegExp('; $').test(str))
     4170                        str = str.substring(0, str.length - 2);
     4171
     4172                return str;
     4173        },
     4174
     4175        convertRGBToHex : function(s, k) {
     4176                var re, rgb;
     4177
     4178                if (s.toLowerCase().indexOf('rgb') != -1) {
     4179                        re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
     4180                        rgb = s.replace(re, "$1,$2,$3,$4,$5").split(',');
     4181
     4182                        if (rgb.length == 5) {
     4183                                r = parseInt(rgb[1]).toString(16);
     4184                                g = parseInt(rgb[2]).toString(16);
     4185                                b = parseInt(rgb[3]).toString(16);
     4186
     4187                                r = r.length == 1 ? '0' + r : r;
     4188                                g = g.length == 1 ? '0' + g : g;
     4189                                b = b.length == 1 ? '0' + b : b;
     4190
     4191                                s = "#" + r + g + b;
     4192
     4193                                if (k)
     4194                                        s = rgb[0] + s + rgb[4];
     4195                        }
     4196                }
     4197
     4198                return s;
     4199        },
     4200
     4201        convertHexToRGB : function(s) {
     4202                if (s.indexOf('#') != -1) {
     4203                        s = s.replace(new RegExp('[^0-9A-F]', 'gi'), '');
     4204                        return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")";
     4205                }
     4206
     4207                return s;
     4208        },
     4209
     4210        convertSpansToFonts : function(doc) {
     4211                var s, i, size, fSize, x, fFace, fColor, sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
     4212
     4213                s = tinyMCE.selectElements(doc, 'span,font');
     4214                for (i=0; i<s.length; i++) {
     4215                        size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();
     4216                        fSize = 0;
     4217
     4218                        for (x=0; x<sizes.length; x++) {
     4219                                if (sizes[x] == size) {
     4220                                        fSize = x + 1;
     4221                                        break;
     4222                                }
     4223                        }
     4224
     4225                        if (fSize > 0) {
     4226                                tinyMCE.setAttrib(s[i], 'size', fSize);
     4227                                s[i].style.fontSize = '';
     4228                        }
     4229
     4230                        fFace = s[i].style.fontFamily;
     4231                        if (fFace != null && fFace !== '') {
     4232                                tinyMCE.setAttrib(s[i], 'face', fFace);
     4233                                s[i].style.fontFamily = '';
     4234                        }
     4235
     4236                        fColor = s[i].style.color;
     4237                        if (fColor != null && fColor !== '') {
     4238                                tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));
     4239                                s[i].style.color = '';
     4240                        }
     4241                }
     4242        },
     4243
     4244        convertFontsToSpans : function(doc) {
     4245                var fsClasses, s, i, fSize, fFace, fColor, sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
     4246
     4247                fsClasses = tinyMCE.getParam('font_size_classes');
     4248                if (fsClasses !== '')
     4249                        fsClasses = fsClasses.replace(/\s+/, '').split(',');
     4250                else
     4251                        fsClasses = null;
     4252
     4253                s = tinyMCE.selectElements(doc, 'span,font');
     4254                for (i=0; i<s.length; i++) {
     4255                        fSize = tinyMCE.getAttrib(s[i], 'size');
     4256                        fFace = tinyMCE.getAttrib(s[i], 'face');
     4257                        fColor = tinyMCE.getAttrib(s[i], 'color');
     4258
     4259                        if (fSize !== '') {
     4260                                fSize = parseInt(fSize);
     4261
     4262                                if (fSize > 0 && fSize < 8) {
     4263                                        if (fsClasses != null)
     4264                                                tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);
     4265                                        else
     4266                                                s[i].style.fontSize = sizes[fSize-1];
     4267                                }
     4268
     4269                                s[i].removeAttribute('size');
     4270                        }
     4271
     4272                        if (fFace !== '') {
     4273                                s[i].style.fontFamily = fFace;
     4274                                s[i].removeAttribute('face');
     4275                        }
     4276
     4277                        if (fColor !== '') {
     4278                                s[i].style.color = fColor;
     4279                                s[i].removeAttribute('color');
     4280                        }
     4281                }
     4282        },
     4283
     4284        cleanupAnchors : function(doc) {
     4285                var i, cn, x, an = doc.getElementsByTagName("a");
     4286
     4287                // Loops backwards due to bug #1467987
     4288                for (i=an.length-1; i>=0; i--) {
     4289                        if (tinyMCE.getAttrib(an[i], "name") !== '' && tinyMCE.getAttrib(an[i], "href") == '') {
     4290                                cn = an[i].childNodes;
     4291
     4292                                for (x=cn.length-1; x>=0; x--)
     4293                                        tinyMCE.insertAfter(cn[x], an[i]);
     4294                        }
     4295                }
     4296        },
     4297
     4298        getContent : function(editor_id) {
     4299                if (typeof(editor_id) != "undefined")
     4300                         tinyMCE.getInstanceById(editor_id).select();
     4301
     4302                if (tinyMCE.selectedInstance)
     4303                        return tinyMCE.selectedInstance.getHTML();
     4304
     4305                return null;
     4306        },
     4307
     4308        _fixListElements : function(d) {
     4309                var nl, x, a = ['ol', 'ul'], i, n, p, r = new RegExp('^(OL|UL)$'), np;
     4310
     4311                for (x=0; x<a.length; x++) {
     4312                        nl = d.getElementsByTagName(a[x]);
     4313
     4314                        for (i=0; i<nl.length; i++) {
     4315                                n = nl[i];
     4316                                p = n.parentNode;
     4317
     4318                                if (r.test(p.nodeName)) {
     4319                                        np = tinyMCE.prevNode(n, 'LI');
     4320
     4321                                        if (!np) {
     4322                                                np = d.createElement('li');
     4323                                                np.innerHTML = '&nbsp;';
     4324                                                np.appendChild(n);
     4325                                                p.insertBefore(np, p.firstChild);
     4326                                        } else
     4327                                                np.appendChild(n);
     4328                                }
     4329                        }
     4330                }
     4331        },
     4332
     4333        _fixTables : function(d) {
     4334                var nl, i, n, p, np, x, t;
     4335
     4336                nl = d.getElementsByTagName('table');
    42474337                for (i=0; i<nl.length; i++) {
    42484338                        n = nl[i];
    4249                         p = n.parentNode;
    4250 
    4251                         if (r.test(p.nodeName)) {
    4252                                 np = tinyMCE.prevNode(n, 'LI');
    4253 
    4254                                 if (!np) {
    4255                                         np = d.createElement('li');
    4256                                         np.innerHTML = '&nbsp;';
     4339
     4340                        if ((p = tinyMCE.getParentElement(n, 'p,h1,h2,h3,h4,h5,h6')) != null) {
     4341                                np = p.cloneNode(false);
     4342                                np.removeAttribute('id');
     4343
     4344                                t = n;
     4345
     4346                                while ((n = n.nextSibling))
    42574347                                        np.appendChild(n);
    4258                                         p.insertBefore(np, p.firstChild);
    4259                                 } else
    4260                                         np.appendChild(n);
    4261                         }
    4262                 }
     4348
     4349                                tinyMCE.insertAfter(np, p);
     4350                                tinyMCE.insertAfter(t, p);
     4351                        }
     4352                }
     4353        },
     4354
     4355        _cleanupHTML : function(inst, doc, config, elm, visual, on_save, on_submit, inn) {
     4356                var h, d, t1, t2, t3, t4, t5, c, s, nb;
     4357
     4358                if (!tinyMCE.getParam('cleanup'))
     4359                        return elm.innerHTML;
     4360
     4361                on_save = typeof(on_save) == 'undefined' ? false : on_save;
     4362
     4363                c = inst.cleanup;
     4364                s = inst.settings;
     4365                d = c.settings.debug;
     4366
     4367                if (d)
     4368                        t1 = new Date().getTime();
     4369
     4370                inst._fixRootBlocks();
     4371
     4372                if (tinyMCE.getParam("convert_fonts_to_spans"))
     4373                        tinyMCE.convertFontsToSpans(doc);
     4374
     4375                if (tinyMCE.getParam("fix_list_elements"))
     4376                        tinyMCE._fixListElements(doc);
     4377
     4378                if (tinyMCE.getParam("fix_table_elements"))
     4379                        tinyMCE._fixTables(doc);
     4380
     4381                // Call custom cleanup code
     4382                tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body);
     4383
     4384                if (d)
     4385                        t2 = new Date().getTime();
     4386
     4387                c.settings.on_save = on_save;
     4388
     4389                c.idCount = 0;
     4390                c.serializationId = new Date().getTime().toString(32); // Unique ID needed for the content duplication bug
     4391                c.serializedNodes = [];
     4392                c.sourceIndex = -1;
     4393
     4394                if (s.cleanup_serializer == "xml")
     4395                        h = c.serializeNodeAsXML(elm, inn);
     4396                else
     4397                        h = c.serializeNodeAsHTML(elm, inn);
     4398
     4399                if (d)
     4400                        t3 = new Date().getTime();
     4401
     4402                // Post processing
     4403                nb = tinyMCE.getParam('entity_encoding') == 'numeric' ? '&#160;' : '&nbsp;';
     4404                h = h.replace(/<\/?(body|head|html)[^>]*>/gi, '');
     4405                h = h.replace(new RegExp(' (rowspan="1"|colspan="1")', 'g'), '');
     4406                h = h.replace(/<p><hr \/><\/p>/g, '<hr />');
     4407                h = h.replace(/<p>(&nbsp;|&#160;)<\/p><hr \/><p>(&nbsp;|&#160;)<\/p>/g, '<hr />');
     4408                h = h.replace(/<td>\s*<br \/>\s*<\/td>/g, '<td>' + nb + '</td>');
     4409                h = h.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
     4410                h = h.replace(/<br \/>$/, ''); // Remove last BR for Gecko
     4411                h = h.replace(/<br \/><\/p>/g, '</p>'); // Remove last BR in P tags for Gecko
     4412                h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*(&nbsp;|&#160;)\s*<\/p>/g, '<p>' + nb + '</p>');
     4413                h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
     4414                h = h.replace(/<p>\s*<br \/>\s*&nbsp;\s*<\/p>/g, '<p>' + nb + '</p>');
     4415                h = h.replace(new RegExp('<a>(.*?)<\\/a>', 'g'), '$1');
     4416                h = h.replace(/<p([^>]*)>\s*<\/p>/g, '<p$1>' + nb + '</p>');
     4417
     4418                // Clean body
     4419                if (/^\s*(<br \/>|<p>&nbsp;<\/p>|<p>&#160;<\/p>|<p><\/p>)\s*$/.test(h))
     4420                        h = '';
     4421
     4422                // If preformatted
     4423                if (s.preformatted) {
     4424                        h = h.replace(/^<pre>/, '');
     4425                        h = h.replace(/<\/pre>$/, '');
     4426                        h = '<pre>' + h + '</pre>';
     4427                }
     4428
     4429                // Gecko specific processing
     4430                if (tinyMCE.isGecko) {
     4431                        // Makes no sence but FF generates it!!
     4432                        h = h.replace(/<br \/>\s*<\/li>/g, '</li>');
     4433                        h = h.replace(/&nbsp;\s*<\/(dd|dt)>/g, '</$1>');
     4434                        h = h.replace(/<o:p _moz-userdefined="" \/>/g, '');
     4435                        h = h.replace(/<td([^>]*)>\s*<br \/>\s*<\/td>/g, '<td$1>' + nb + '</td>');
     4436                }
     4437
     4438                if (s.force_br_newlines)
     4439                        h = h.replace(/<p>(&nbsp;|&#160;)<\/p>/g, '<br />');
     4440
     4441                // Call custom cleanup code
     4442                h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h);
     4443
     4444                // Remove internal classes
     4445                if (on_save) {
     4446                        h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), '');
     4447                        h = h.replace(new RegExp(' ?class=""', 'g'), '');
     4448                }
     4449
     4450                if (s.remove_linebreaks && !c.settings.indent)
     4451                        h = h.replace(/\n|\r/g, ' ');
     4452
     4453                if (d)
     4454                        t4 = new Date().getTime();
     4455
     4456                if (on_save && c.settings.indent)
     4457                        h = c.formatHTML(h);
     4458
     4459                // If encoding (not recommended option)
     4460                if (on_submit && (s.encoding == "xml" || s.encoding == "html"))
     4461                        h = c.xmlEncode(h);
     4462
     4463                if (d)
     4464                        t5 = new Date().getTime();
     4465
     4466                if (c.settings.debug)
     4467                        tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + ".");
     4468
     4469                return h;
    42634470        }
    4264 };
    4265 
    4266 TinyMCE_Engine.prototype._fixTables = function(d) {
    4267         var nl, i, n, p, np, x, t;
    4268 
    4269         nl = d.getElementsByTagName('table');
    4270         for (i=0; i<nl.length; i++) {
    4271                 n = nl[i];
    4272 
    4273                 if ((p = tinyMCE.getParentElement(n, 'p,h1,h2,h3,h4,h5,h6')) != null) {
    4274                         np = p.cloneNode(false);
    4275                         np.removeAttribute('id');
    4276 
    4277                         t = n;
    4278 
    4279                         while ((n = n.nextSibling))
    4280                                 np.appendChild(n);
    4281 
    4282                         tinyMCE.insertAfter(np, p);
    4283                         tinyMCE.insertAfter(t, p);
    4284                 }
    4285         }
    4286 };
    4287 
    4288 TinyMCE_Engine.prototype._cleanupHTML = function(inst, doc, config, elm, visual, on_save, on_submit, inn) {
    4289         var h, d, t1, t2, t3, t4, t5, c, s, nb;
    4290 
    4291         if (!tinyMCE.getParam('cleanup'))
    4292                 return elm.innerHTML;
    4293 
    4294         on_save = typeof(on_save) == 'undefined' ? false : on_save;
    4295 
    4296         c = inst.cleanup;
    4297         s = inst.settings;
    4298         d = c.settings.debug;
    4299 
    4300         if (d)
    4301                 t1 = new Date().getTime();
    4302 
    4303         if (tinyMCE.getParam("convert_fonts_to_spans"))
    4304                 tinyMCE.convertFontsToSpans(doc);
    4305 
    4306         if (tinyMCE.getParam("fix_list_elements"))
    4307                 tinyMCE._fixListElements(doc);
    4308 
    4309         if (tinyMCE.getParam("fix_table_elements"))
    4310                 tinyMCE._fixTables(doc);
    4311 
    4312         // Call custom cleanup code
    4313         tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body);
    4314 
    4315         if (d)
    4316                 t2 = new Date().getTime();
    4317 
    4318         c.settings.on_save = on_save;
    4319         //for (var i=0; i<100; i++)
    4320 
    4321         c.idCount = 0;
    4322         c.serializationId++;
    4323         c.serializedNodes = new Array();
    4324         c.sourceIndex = -1;
    4325 
    4326         if (s.cleanup_serializer == "xml")
    4327                 h = c.serializeNodeAsXML(elm, inn);
    4328         else
    4329                 h = c.serializeNodeAsHTML(elm, inn);
    4330 
    4331         if (d)
    4332                 t3 = new Date().getTime();
    4333 
    4334         // Post processing
    4335         nb = tinyMCE.getParam('entity_encoding') == 'numeric' ? '&#160;' : '&nbsp;';
    4336         h = h.replace(/<\/?(body|head|html)[^>]*>/gi, '');
    4337         h = h.replace(new RegExp(' (rowspan="1"|colspan="1")', 'g'), '');
    4338         h = h.replace(/<p><hr \/><\/p>/g, '<hr />');
    4339         h = h.replace(/<p>(&nbsp;|&#160;)<\/p><hr \/><p>(&nbsp;|&#160;)<\/p>/g, '<hr />');
    4340         h = h.replace(/<td>\s*<br \/>\s*<\/td>/g, '<td>' + nb + '</td>');
    4341         h = h.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
    4342         h = h.replace(/<br \/>$/, ''); // Remove last BR for Gecko
    4343         h = h.replace(/<br \/><\/p>/g, '</p>'); // Remove last BR in P tags for Gecko
    4344         h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*(&nbsp;|&#160;)\s*<\/p>/g, '<p>' + nb + '</p>');
    4345         h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
    4346         h = h.replace(/<p>\s*<br \/>\s*&nbsp;\s*<\/p>/g, '<p>' + nb + '</p>');
    4347         h = h.replace(new RegExp('<a>(.*?)<\\/a>', 'g'), '$1');
    4348         h = h.replace(/<p([^>]*)>\s*<\/p>/g, '<p$1>' + nb + '</p>');
    4349 
    4350         // Clean body
    4351         if (/^\s*(<br \/>|<p>&nbsp;<\/p>|<p>&#160;<\/p>|<p><\/p>)\s*$/.test(h))
    4352                 h = '';
    4353 
    4354         // If preformatted
    4355         if (s.preformatted) {
    4356                 h = h.replace(/^<pre>/, '');
    4357                 h = h.replace(/<\/pre>$/, '');
    4358                 h = '<pre>' + h + '</pre>';
    4359         }
    4360 
    4361         // Gecko specific processing
    4362         if (tinyMCE.isGecko) {
    4363                 h = h.replace(/<o:p _moz-userdefined="" \/>/g, '');
    4364                 h = h.replace(/<td([^>]*)>\s*<br \/>\s*<\/td>/g, '<td$1>' + nb + '</td>');
    4365         }
    4366 
    4367         if (s.force_br_newlines)
    4368                 h = h.replace(/<p>(&nbsp;|&#160;)<\/p>/g, '<br />');
    4369 
    4370         // Call custom cleanup code
    4371         h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h);
    4372 
    4373         // Remove internal classes
    4374         if (on_save) {
    4375                 h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), '');
    4376                 h = h.replace(new RegExp(' ?class=""', 'g'), '');
    4377         }
    4378 
    4379         if (s.remove_linebreaks && !c.settings.indent)
    4380                 h = h.replace(/\n|\r/g, ' ');
    4381 
    4382         if (d)
    4383                 t4 = new Date().getTime();
    4384 
    4385         if (on_save && c.settings.indent)
    4386                 h = c.formatHTML(h);
    4387 
    4388         // If encoding (not recommended option)
    4389         if (on_submit && (s.encoding == "xml" || s.encoding == "html"))
    4390                 h = c.xmlEncode(h);
    4391 
    4392         if (d)
    4393                 t5 = new Date().getTime();
    4394 
    4395         if (c.settings.debug)
    4396                 tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + ".");
    4397 
    4398         return h;
    4399 };
     4471});
    44004472
    44014473function TinyMCE_Cleanup() {
    44024474        this.isIE = (navigator.appName == "Microsoft Internet Explorer");
    4403         this.rules = tinyMCE.clearArray(new Array());
     4475        this.rules = tinyMCE.clearArray([]);
    44044476
    44054477        // Default config
     
    44194491        };
    44204492
    4421         this.vElements = tinyMCE.clearArray(new Array());
     4493        this.vElements = tinyMCE.clearArray([]);
    44224494        this.vElementsRe = '';
    44234495        this.closeElementsRe = /^(IMG|BR|HR|LINK|META|BASE|INPUT|AREA)$/;
     
    44494521                this.serializedNodes = [];
    44504522
    4451                 if (s.invalid_elements != '')
     4523                if (s.invalid_elements !== '')
    44524524                        this.iveRe = this._arrayToRe(s.invalid_elements.toUpperCase().split(','), 'g', '^(', ')$');
    44534525                else
     
    44704542                this.idCount = 0;
    44714543                this.xmlEncodeRe = new RegExp('[\u007F-\uFFFF<>&"]', 'g');
    4472                 this.xmlEncodeAposRe = new RegExp('[\u007F-\uFFFF<>&"\']', 'g');
    44734544        },
    44744545
    44754546        addRuleStr : function(s) {
    4476                 var r = this.parseRuleStr(s);
    4477                 var n;
     4547                var r = this.parseRuleStr(s), n;
    44784548
    44794549                for (n in r) {
     
    44824552                }
    44834553
    4484                 this.vElements = tinyMCE.clearArray(new Array());
     4554                this.vElements = tinyMCE.clearArray([]);
    44854555
    44864556                for (n in this.rules) {
     
    44934563
    44944564        isValid : function(n) {
    4495                 this._setupRules(); // Will initialize cleanup rules
     4565                if (!this.rulesDone)
     4566                        this._setupRules(); // Will initialize cleanup rules
    44964567
    44974568                // Empty is true since it removes formatting
     
    45494620
    45504621                                r += ')$';
    4551 //tinyMCE.debug(t + "=" + r);
     4622
    45524623                                if (this.childRules == null)
    4553                                         this.childRules = tinyMCE.clearArray(new Array());
     4624                                        this.childRules = tinyMCE.clearArray([]);
    45544625
    45554626                                this.childRules[tn[y]] = new RegExp(r);
     
    45624633
    45634634        parseRuleStr : function(s) {
    4564                 var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray(new Array()), dv;
     4635                var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray([]), dv;
    45654636
    45664637                if (s == null || s.length == 0)
     
    46224693                                                        if (av[0].charAt(0) == ':') {
    46234694                                                                if (!r.forceAttribs)
    4624                                                                         r.forceAttribs = tinyMCE.clearArray(new Array());
     4695                                                                        r.forceAttribs = tinyMCE.clearArray([]);
    46254696
    46264697                                                                r.forceAttribs[t.toLowerCase()] = av[0].substring(1);
    46274698                                                        } else if (av[0].charAt(0) == '=') {
    46284699                                                                if (!r.defaultAttribs)
    4629                                                                         r.defaultAttribs = tinyMCE.clearArray(new Array());
     4700                                                                        r.defaultAttribs = tinyMCE.clearArray([]);
    46304701
    46314702                                                                dv = av[0].substring(1);
    46324703
    4633                                                                 r.defaultAttribs[t.toLowerCase()] = dv == "" ? "mce_empty" : dv;
     4704                                                                r.defaultAttribs[t.toLowerCase()] = dv == '' ? "mce_empty" : dv;
    46344705                                                        } else if (av[0].charAt(0) == '<') {
    46354706                                                                if (!r.validAttribValues)
    4636                                                                         r.validAttribValues = tinyMCE.clearArray(new Array());
     4707                                                                        r.validAttribValues = tinyMCE.clearArray([]);
    46374708
    46384709                                                                r.validAttribValues[t.toLowerCase()] = this._arrayToRe(this.split('?', av[0].substring(1)), 'i');
     
    46574728                                } else {
    46584729                                        r.vAttribsRe = '';
    4659                                         r.vAttribs = tinyMCE.clearArray(new Array());
     4730                                        r.vAttribs = tinyMCE.clearArray([]);
    46604731                                        r.vAttribsReIsWild = false;
    46614732                                }
     
    47464817                var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr, nn;
    47474818
    4748                 this._setupRules(); // Will initialize cleanup rules
     4819                if (!this.rulesDone)
     4820                        this._setupRules(); // Will initialize cleanup rules
    47494821
    47504822                if (tinyMCE.isRealIE && this._isDuplicate(n))
     
    47684840                                        break;
    47694841
    4770                                 // MSIE sometimes produces <//tag>
    4771                                 if ((tinyMCE.isRealIE) && n.nodeName.indexOf('/') != -1)
    4772                                         break;
    4773 
    47744842                                nn = n.nodeName;
     4843
     4844                                if (tinyMCE.isRealIE) {
     4845                                        // MSIE sometimes produces <//tag>
     4846                                        if (n.nodeName.indexOf('/') != -1)
     4847                                                break;
     4848
     4849                                        // MSIE has it's NS in a separate attrib
     4850                                        if (n.scopeName && n.scopeName != 'HTML')
     4851                                                nn = n.scopeName.toUpperCase() + ':' + nn.toUpperCase();
     4852                                } else if (tinyMCE.isOpera && nn.indexOf(':') > 0)
     4853                                        nn = nn.toUpperCase();
    47754854
    47764855                                // Convert fonts to spans
     
    49605039        },
    49615040
    4962         xmlEncode : function(s, skip_apos) {
    4963                 var cl = this, re = !skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe;
    4964 
    4965                 this._setupEntities(); // Will intialize lookup table
     5041        xmlEncode : function(s) {
     5042                var cl = this, re = this.xmlEncodeRe;
     5043
     5044                if (!this.entitiesDone)
     5045                        this._setupEntities(); // Will intialize lookup table
    49665046
    49675047                switch (this.settings.entity_encoding) {
    49685048                        case "raw":
    4969                                 return tinyMCE.xmlEncode(s, skip_apos);
     5049                                return tinyMCE.xmlEncode(s);
    49705050
    49715051                        case "named":
    4972                                 return s.replace(re, function (c, b) {
    4973                                         b = cl.entities[c.charCodeAt(0)];
     5052                                return s.replace(re, function (c) {
     5053                                        var b = cl.entities[c.charCodeAt(0)];
    49745054
    49755055                                        return b ? '&' + b + ';' : c;
     
    49775057
    49785058                        case "numeric":
    4979                                 return s.replace(re, function (c, b) {
    4980                                         return b ? '&#' + c.charCodeAt(0) + ';' : c;
     5059                                return s.replace(re, function (c) {
     5060                                        return '&#' + c.charCodeAt(0) + ';';
    49815061                                });
    49825062                }
     
    49865066
    49875067        split : function(re, s) {
    4988                 var c = s.split(re);
    4989                 var i, l, o = new Array();
     5068                var i, l, o = [], c = s.split(re);
    49905069
    49915070                for (i=0, l=c.length; i<l; i++) {
    4992                         if (c[i] != '')
     5071                        if (c[i] !== '')
    49935072                                o[i] = c[i];
    49945073                }
     
    50395118                        if (nn == "INPUT" && n == "maxlength" && v == "2147483647")
    50405119                                v = "";
     5120
     5121                        // Images
     5122                        if (n == "width" || n == "height")
     5123                                v = e.getAttribute(n, 2);
    50415124                }
    50425125
     
    50485131                }
    50495132
    5050                 if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v != "")
     5133                if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v !== '')
    50515134                        v = tinyMCE.cleanupEventStr(v);
    50525135
    5053                 return (v && v != "") ? '' + v : d;
     5136                return (v && v !== '') ? '' + v : d;
    50545137        },
    50555138
     
    50965179
    50975180                // Setup entities
    5098                 if (!this.entitiesDone) {
    5099                         if (s.entity_encoding == "named") {
    5100                                 n = tinyMCE.clearArray(new Array());
    5101                                 a = this.split(',', s.entities);
    5102                                 for (i=0; i<a.length; i+=2)
    5103                                         n[a[i]] = a[i+1];
    5104 
    5105                                 this.entities = n;
    5106                         }
    5107 
    5108                         this.entitiesDone = true;
    5109                 }
     5181                if (s.entity_encoding == "named") {
     5182                        n = tinyMCE.clearArray([]);
     5183                        a = this.split(',', s.entities);
     5184                        for (i=0; i<a.length; i+=2)
     5185                                n[a[i]] = a[i+1];
     5186
     5187                        this.entities = n;
     5188                }
     5189
     5190                this.entitiesDone = true;
    51105191        },
    51115192
     
    51145195
    51155196                // Setup default rule
    5116                 if (!this.rulesDone) {
    5117                         this.addRuleStr(s.valid_elements);
    5118                         this.addRuleStr(s.extended_valid_elements);
    5119                         this.addChildRemoveRuleStr(s.valid_child_elements);
    5120 
    5121                         this.rulesDone = true;
    5122                 }
     5197                this.addRuleStr(s.valid_elements);
     5198                this.addRuleStr(s.extended_valid_elements);
     5199                this.addChildRemoveRuleStr(s.valid_child_elements);
     5200
     5201                this.rulesDone = true;
    51235202        },
    51245203
    51255204        _isDuplicate : function(n) {
    5126                 var i;
     5205                var i, l, sn;
    51275206
    51285207                if (!this.settings.fix_content_duplication)
     
    51365215                        n.setAttribute('mce_serialized', this.serializationId);
    51375216                } else {
     5217                        sn = this.serializedNodes;
     5218
    51385219                        // Search lookup table for text nodes  and comments
    5139                         for (i=0; i<this.serializedNodes.length; i++) {
    5140                                 if (this.serializedNodes[i] == n)
     5220                        for (i=0, l = sn.length; i<l; i++) {
     5221                                if (sn[i] == n)
    51415222                                        return true;
    51425223                        }
    51435224
    5144                         this.serializedNodes[this.serializedNodes.length] = n;
     5225                        sn.push(n);
    51455226                }
    51465227
     
    51525233/* file:jscripts/tiny_mce/classes/TinyMCE_DOMUtils.class.js */
    51535234
    5154 TinyMCE_Engine.prototype.createTagHTML = function(tn, a, h) {
    5155         var o = '', f = tinyMCE.xmlEncode;
    5156 
    5157         o = '<' + tn;
    5158 
    5159         if (a) {
    5160                 for (n in a) {
    5161                         if (typeof(a[n]) != 'function' && a[n] != null)
    5162                                 o += ' ' + f(n) + '="' + f('' + a[n]) + '"';
    5163                 }
     5235tinyMCE.add(TinyMCE_Engine, {
     5236        createTagHTML : function(tn, a, h) {
     5237                var o = '', f = tinyMCE.xmlEncode, n;
     5238
     5239                o = '<' + tn;
     5240
     5241                if (a) {
     5242                        for (n in a) {
     5243                                if (typeof(a[n]) != 'function' && a[n] != null)
     5244                                        o += ' ' + f(n) + '="' + f('' + a[n]) + '"';
     5245                        }
     5246                }
     5247
     5248                o += !h ? ' />' : '>' + h + '</' + tn + '>';
     5249
     5250                return o;
     5251        },
     5252
     5253        createTag : function(d, tn, a, h) {
     5254                var o = d.createElement(tn), n;
     5255
     5256                if (a) {
     5257                        for (n in a) {
     5258                                if (typeof(a[n]) != 'function' && a[n] != null)
     5259                                        tinyMCE.setAttrib(o, n, a[n]);
     5260                        }
     5261                }
     5262
     5263                if (h)
     5264                        o.innerHTML = h;
     5265
     5266                return o;
     5267        },
     5268
     5269        getElementByAttributeValue : function(n, e, a, v) {
     5270                return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
     5271        },
     5272
     5273        getElementsByAttributeValue : function(n, e, a, v) {
     5274                var i, nl = n.getElementsByTagName(e), o = [];
     5275
     5276                for (i=0; i<nl.length; i++) {
     5277                        if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1)
     5278                                o[o.length] = nl[i];
     5279                }
     5280
     5281                return o;
     5282        },
     5283
     5284        isBlockElement : function(n) {
     5285                return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName);
     5286        },
     5287
     5288        getParentBlockElement : function(n, r) {
     5289                return this.getParentNode(n, function(n) {
     5290                        return tinyMCE.isBlockElement(n);
     5291                }, r);
     5292
     5293                return null;
     5294        },
     5295
     5296        insertAfter : function(n, r){
     5297                if (r.nextSibling)
     5298                        r.parentNode.insertBefore(n, r.nextSibling);
     5299                else
     5300                        r.parentNode.appendChild(n);
     5301        },
     5302
     5303        setInnerHTML : function(e, h) {
     5304                var i, nl, n;
     5305
     5306                // Convert all strong/em to b/i in Gecko
     5307                if (tinyMCE.isGecko) {
     5308                        h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>');
     5309                        h = h.replace(/<em([^>]*)>/gi, '<i$1>');
     5310                        h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>');
     5311                        h = h.replace(/<strong([^>]*)>/gi, '<b$1>');
     5312                        h = h.replace(/<\/strong>/gi, '</b>');
     5313                        h = h.replace(/<\/em>/gi, '</i>');
     5314                }
     5315
     5316                if (tinyMCE.isRealIE) {
     5317                        // Since MSIE handles invalid HTML better that valid XHTML we
     5318                        // need to make some things invalid. <hr /> gets converted to <hr>.
     5319                        h = h.replace(/\s\/>/g, '>');
     5320
     5321                        // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
     5322                        h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
     5323                        h = h.replace(/<p([^>]*)>\s*&nbsp;\s*<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
     5324                        h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
     5325
     5326                        // Remove first comment
     5327                        e.innerHTML = tinyMCE.uniqueTag + h;
     5328                        e.firstChild.removeNode(true);
     5329
     5330                        // Remove weird auto generated empty paragraphs unless it's supposed to be there
     5331                        nl = e.getElementsByTagName("p");
     5332                        for (i=nl.length-1; i>=0; i--) {
     5333                                n = nl[i];
     5334
     5335                                if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
     5336                                        n.parentNode.removeChild(n);
     5337                        }
     5338                } else {
     5339                        h = this.fixGeckoBaseHREFBug(1, e, h);
     5340                        e.innerHTML = h;
     5341                        this.fixGeckoBaseHREFBug(2, e, h);
     5342                }
     5343        },
     5344
     5345        getOuterHTML : function(e) {
     5346                var d;
     5347
     5348                if (tinyMCE.isIE)
     5349                        return e.outerHTML;
     5350
     5351                d = e.ownerDocument.createElement("body");
     5352                d.appendChild(e.cloneNode(true));
     5353
     5354                return d.innerHTML;
     5355        },
     5356
     5357        setOuterHTML : function(e, h, d) {
     5358                var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t;
     5359
     5360                if (tinyMCE.isIE && e.nodeType == 1)
     5361                        e.outerHTML = h;
     5362                else {
     5363                        t = d.createElement("body");
     5364                        t.innerHTML = h;
     5365
     5366                        for (i=0, nl=t.childNodes; i<nl.length; i++)
     5367                                e.parentNode.insertBefore(nl[i].cloneNode(true), e);
     5368
     5369                        e.parentNode.removeChild(e);
     5370                }
     5371        },
     5372
     5373        _getElementById : function(id, d) {
     5374                var e, i, j, f;
     5375
     5376                if (typeof(d) == "undefined")
     5377                        d = document;
     5378
     5379                e = d.getElementById(id);
     5380                if (!e) {
     5381                        f = d.forms;
     5382
     5383                        for (i=0; i<f.length; i++) {
     5384                                for (j=0; j<f[i].elements.length; j++) {
     5385                                        if (f[i].elements[j].name == id) {
     5386                                                e = f[i].elements[j];
     5387                                                break;
     5388                                        }
     5389                                }
     5390                        }
     5391                }
     5392
     5393                return e;
     5394        },
     5395
     5396        getNodeTree : function(n, na, t, nn) {
     5397                return this.selectNodes(n, function(n) {
     5398                        return (!t || n.nodeType == t) && (!nn || n.nodeName == nn);
     5399                }, na ? na : []);
     5400        },
     5401
     5402        getParentElement : function(n, na, f, r) {
     5403                var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v;
     5404
     5405                // Compatiblity with old scripts where f param was a attribute string
     5406                if (f && typeof(f) == 'string')
     5407                        return this.getParentElement(n, na, function(no) {return tinyMCE.getAttrib(no, f) !== '';});
     5408
     5409                return this.getParentNode(n, function(n) {
     5410                        return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n));
     5411                }, r);
     5412        },
     5413
     5414        getParentNode : function(n, f, r) {
     5415                while (n) {
     5416                        if (n == r)
     5417                                return null;
     5418
     5419                        if (f(n))
     5420                                return n;
     5421
     5422                        n = n.parentNode;
     5423                }
     5424
     5425                return null;
     5426        },
     5427
     5428        getAttrib : function(elm, name, dv) {
     5429                var v;
     5430
     5431                if (typeof(dv) == "undefined")
     5432                        dv = "";
     5433
     5434                // Not a element
     5435                if (!elm || elm.nodeType != 1)
     5436                        return dv;
     5437
     5438                try {
     5439                        v = elm.getAttribute(name, 0);
     5440                } catch (ex) {
     5441                        // IE 7 may cast exception on invalid attributes
     5442                        v = elm.getAttribute(name, 2);
     5443                }
     5444
     5445                // Try className for class attrib
     5446                if (name == "class" && !v)
     5447                        v = elm.className;
     5448
     5449                // Workaround for a issue with Firefox 1.5rc2+
     5450                if (tinyMCE.isGecko) {
     5451                        if (name == "src" && elm.src != null && elm.src !== '')
     5452                                v = elm.src;
     5453
     5454                        // Workaround for a issue with Firefox 1.5rc2+
     5455                        if (name == "href" && elm.href != null && elm.href !== '')
     5456                                v = elm.href;
     5457                } else if (tinyMCE.isIE) {
     5458                        switch (name) {
     5459                                case "http-equiv":
     5460                                        v = elm.httpEquiv;
     5461                                        break;
     5462
     5463                                case "width":
     5464                                case "height":
     5465                                        v = elm.getAttribute(name, 2);
     5466                                        break;
     5467                        }
     5468                }
     5469
     5470                if (name == "style" && !tinyMCE.isOpera)
     5471                        v = elm.style.cssText;
     5472
     5473                return (v && v !== '') ? v : dv;
     5474        },
     5475
     5476        setAttrib : function(el, name, va, fix) {
     5477                if (typeof(va) == "number" && va != null)
     5478                        va = "" + va;
     5479
     5480                if (fix) {
     5481                        if (va == null)
     5482                                va = "";
     5483
     5484                        va = va.replace(/[^0-9%]/g, '');
     5485                }
     5486
     5487                if (name == "style")
     5488                        el.style.cssText = va;
     5489
     5490                if (name == "class")
     5491                        el.className = va;
     5492
     5493                if (va != null && va !== '' && va != -1)
     5494                        el.setAttribute(name, va);
     5495                else
     5496                        el.removeAttribute(name);
     5497        },
     5498
     5499        setStyleAttrib : function(e, n, v) {
     5500                e.style[n] = v;
     5501
     5502                // Style attrib deleted in IE
     5503                if (tinyMCE.isIE && v == null || v == '') {
     5504                        v = tinyMCE.serializeStyle(tinyMCE.parseStyle(e.style.cssText));
     5505                        e.style.cssText = v;
     5506                        e.setAttribute("style", v);
     5507                }
     5508        },
     5509
     5510        switchClass : function(ei, c) {
     5511                var e;
     5512
     5513                if (tinyMCE.switchClassCache[ei])
     5514                        e = tinyMCE.switchClassCache[ei];
     5515                else
     5516                        e = tinyMCE.switchClassCache[ei] = document.getElementById(ei);
     5517
     5518                if (e) {
     5519                        // Keep tile mode
     5520                        if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0)
     5521                                c = 'mceTiledButton ' + c;
     5522
     5523                        e.className = c;
     5524                }
     5525        },
     5526
     5527        getAbsPosition : function(n, cn) {
     5528                var l = 0, t = 0;
     5529
     5530                while (n && n != cn) {
     5531                        l += n.offsetLeft;
     5532                        t += n.offsetTop;
     5533                        n = n.offsetParent;
     5534                }
     5535
     5536                return {absLeft : l, absTop : t};
     5537        },
     5538
     5539        prevNode : function(e, n) {
     5540                var a = n.split(','), i;
     5541
     5542                while ((e = e.previousSibling) != null) {
     5543                        for (i=0; i<a.length; i++) {
     5544                                if (e.nodeName == a[i])
     5545                                        return e;
     5546                        }
     5547                }
     5548
     5549                return null;
     5550        },
     5551
     5552        nextNode : function(e, n) {
     5553                var a = n.split(','), i;
     5554
     5555                while ((e = e.nextSibling) != null) {
     5556                        for (i=0; i<a.length; i++) {
     5557                                if (e.nodeName == a[i])
     5558                                        return e;
     5559                        }
     5560                }
     5561
     5562                return null;
     5563        },
     5564
     5565        selectElements : function(n, na, f) {
     5566                var i, a = [], nl, x;
     5567
     5568                for (x=0, na = na.split(','); x<na.length; x++)
     5569                        for (i=0, nl = n.getElementsByTagName(na[x]); i<nl.length; i++)
     5570                                (!f || f(nl[i])) && a.push(nl[i]);
     5571
     5572                return a;
     5573        },
     5574
     5575        selectNodes : function(n, f, a) {
     5576                var i;
     5577
     5578                if (!a)
     5579                        a = [];
     5580
     5581                if (f(n))
     5582                        a[a.length] = n;
     5583
     5584                if (n.hasChildNodes()) {
     5585                        for (i=0; i<n.childNodes.length; i++)
     5586                                tinyMCE.selectNodes(n.childNodes[i], f, a);
     5587                }
     5588
     5589                return a;
     5590        },
     5591
     5592        addCSSClass : function(e, c, b) {
     5593                var o = this.removeCSSClass(e, c);
     5594                return e.className = b ? c + (o !== '' ? (' ' + o) : '') : (o !== '' ? (o + ' ') : '') + c;
     5595        },
     5596
     5597        removeCSSClass : function(e, c) {
     5598                c = e.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
     5599                return e.className = c != ' ' ? c : '';
     5600        },
     5601
     5602        hasCSSClass : function(n, c) {
     5603                return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
     5604        },
     5605
     5606        renameElement : function(e, n, d) {
     5607                var ne, i, ar;
     5608
     5609                d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d;
     5610
     5611                if (e) {
     5612                        ne = d.createElement(n);
     5613
     5614                        ar = e.attributes;
     5615                        for (i=ar.length-1; i>-1; i--) {
     5616                                if (ar[i].specified && ar[i].nodeValue)
     5617                                        ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
     5618                        }
     5619
     5620                        ar = e.childNodes;
     5621                        for (i=0; i<ar.length; i++)
     5622                                ne.appendChild(ar[i].cloneNode(true));
     5623
     5624                        e.parentNode.replaceChild(ne, e);
     5625                }
     5626        },
     5627
     5628        getViewPort : function(w) {
     5629                var d = w.document, m = d.compatMode == 'CSS1Compat', b = d.body, de = d.documentElement;
     5630
     5631                return {
     5632                        left : w.pageXOffset || (m ? de.scrollLeft : b.scrollLeft),
     5633                        top : w.pageYOffset || (m ? de.scrollTop : b.scrollTop),
     5634                        width : w.innerWidth || (m ? de.clientWidth : b.clientWidth),
     5635                        height : w.innerHeight || (m ? de.clientHeight : b.clientHeight)
     5636                };
     5637        },
     5638
     5639        getStyle : function(n, na, d) {
     5640                if (!n)
     5641                        return false;
     5642
     5643                // Gecko
     5644                if (tinyMCE.isGecko && n.ownerDocument.defaultView) {
     5645                        try {
     5646                                return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na);
     5647                        } catch (n) {
     5648                                // Old safari might fail
     5649                                return null;
     5650                        }
     5651                }
     5652
     5653                // Camelcase it, if needed
     5654                na = na.replace(/-(\D)/g, function(a, b){
     5655                        return b.toUpperCase();
     5656                });
     5657
     5658                // IE & Opera
     5659                if (n.currentStyle)
     5660                        return n.currentStyle[na];
     5661
     5662                return false;
    51645663        }
    51655664
    5166         o += !h ? ' />' : '>' + h + '</' + tn + '>';
    5167 
    5168         return o;
    5169 };
    5170 
    5171 TinyMCE_Engine.prototype.createTag = function(d, tn, a, h) {
    5172         var o = d.createElement(tn);
    5173 
    5174         if (a) {
    5175                 for (n in a) {
    5176                         if (typeof(a[n]) != 'function' && a[n] != null)
    5177                                 tinyMCE.setAttrib(o, n, a[n]);
     5665        });
     5666
     5667/* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */
     5668
     5669tinyMCE.add(TinyMCE_Engine, {
     5670        parseURL : function(url_str) {
     5671                var urlParts = [], i, pos, lastPos, chr;
     5672
     5673                if (url_str) {
     5674                        // Parse protocol part
     5675                        pos = url_str.indexOf('://');
     5676                        if (pos != -1) {
     5677                                urlParts.protocol = url_str.substring(0, pos);
     5678                                lastPos = pos + 3;
     5679                        }
     5680
     5681                        // Find port or path start
     5682                        for (i=lastPos; i<url_str.length; i++) {
     5683                                chr = url_str.charAt(i);
     5684
     5685                                if (chr == ':')
     5686                                        break;
     5687
     5688                                if (chr == '/')
     5689                                        break;
     5690                        }
     5691                        pos = i;
     5692
     5693                        // Get host
     5694                        urlParts.host = url_str.substring(lastPos, pos);
     5695
     5696                        // Get port
     5697                        urlParts.port = "";
     5698                        lastPos = pos;
     5699                        if (url_str.charAt(pos) == ':') {
     5700                                pos = url_str.indexOf('/', lastPos);
     5701                                urlParts.port = url_str.substring(lastPos+1, pos);
     5702                        }
     5703
     5704                        // Get path
     5705                        lastPos = pos;
     5706                        pos = url_str.indexOf('?', lastPos);
     5707
     5708                        if (pos == -1)
     5709                                pos = url_str.indexOf('#', lastPos);
     5710
     5711                        if (pos == -1)
     5712                                pos = url_str.length;
     5713
     5714                        urlParts.path = url_str.substring(lastPos, pos);
     5715
     5716                        // Get query
     5717                        lastPos = pos;
     5718                        if (url_str.charAt(pos) == '?') {
     5719                                pos = url_str.indexOf('#');
     5720                                pos = (pos == -1) ? url_str.length : pos;
     5721                                urlParts.query = url_str.substring(lastPos+1, pos);
     5722                        }
     5723
     5724                        // Get anchor
     5725                        lastPos = pos;
     5726                        if (url_str.charAt(pos) == '#') {
     5727                                pos = url_str.length;
     5728                                urlParts.anchor = url_str.substring(lastPos+1, pos);
     5729                        }
     5730                }
     5731
     5732                return urlParts;
     5733        },
     5734
     5735        serializeURL : function(up) {
     5736                var o = "";
     5737
     5738                if (up.protocol)
     5739                        o += up.protocol + "://";
     5740
     5741                if (up.host)
     5742                        o += up.host;
     5743
     5744                if (up.port)
     5745                        o += ":" + up.port;
     5746
     5747                if (up.path)
     5748                        o += up.path;
     5749
     5750                if (up.query)
     5751                        o += "?" + up.query;
     5752
     5753                if (up.anchor)
     5754                        o += "#" + up.anchor;
     5755
     5756                return o;
     5757        },
     5758
     5759        convertAbsoluteURLToRelativeURL : function(base_url, url_to_relative) {
     5760                var baseURL = this.parseURL(base_url), targetURL = this.parseURL(url_to_relative);
     5761                var i, strTok1, strTok2, breakPoint = 0, outPath = "", forceSlash = false;
     5762                var fileName, pos;
     5763
     5764                if (targetURL.path == '')
     5765                        targetURL.path = "/";
     5766                else
     5767                        forceSlash = true;
     5768
     5769                // Crop away last path part
     5770                base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/'));
     5771                strTok1 = base_url.split('/');
     5772                strTok2 = targetURL.path.split('/');
     5773
     5774                if (strTok1.length >= strTok2.length) {
     5775                        for (i=0; i<strTok1.length; i++) {
     5776                                if (i >= strTok2.length || strTok1[i] != strTok2[i]) {
     5777                                        breakPoint = i + 1;
     5778                                        break;
     5779                                }
     5780                        }
     5781                }
     5782
     5783                if (strTok1.length < strTok2.length) {
     5784                        for (i=0; i<strTok2.length; i++) {
     5785                                if (i >= strTok1.length || strTok1[i] != strTok2[i]) {
     5786                                        breakPoint = i + 1;
     5787                                        break;
     5788                                }
     5789                        }
     5790                }
     5791
     5792                if (breakPoint == 1)
     5793                        return targetURL.path;
     5794
     5795                for (i=0; i<(strTok1.length-(breakPoint-1)); i++)
     5796                        outPath += "../";
     5797
     5798                for (i=breakPoint-1; i<strTok2.length; i++) {
     5799                        if (i != (breakPoint-1))
     5800                                outPath += "/" + strTok2[i];
     5801                        else
     5802                                outPath += strTok2[i];
     5803                }
     5804
     5805                targetURL.protocol = null;
     5806                targetURL.host = null;
     5807                targetURL.port = null;
     5808                targetURL.path = outPath == '' && forceSlash ? "/" : outPath;
     5809
     5810                // Remove document prefix from local anchors
     5811                fileName = baseURL.path;
     5812
     5813                if ((pos = fileName.lastIndexOf('/')) != -1)
     5814                        fileName = fileName.substring(pos + 1);
     5815
     5816                // Is local anchor
     5817                if (fileName == targetURL.path && targetURL.anchor !== '')
     5818                        targetURL.path = "";
     5819
     5820                // If empty and not local anchor force filename or slash
     5821                if (targetURL.path == '' && !targetURL.anchor)
     5822                        targetURL.path = fileName !== '' ? fileName : "/";
     5823
     5824                return this.serializeURL(targetURL);
     5825        },
     5826
     5827        convertRelativeToAbsoluteURL : function(base_url, relative_url) {
     5828                var baseURL = this.parseURL(base_url), baseURLParts, relURLParts, newRelURLParts, numBack, relURL = this.parseURL(relative_url), i;
     5829                var len, absPath, start, end, newBaseURLParts;
     5830
     5831                if (relative_url == '' || relative_url.indexOf('://') != -1 || /^(mailto:|javascript:|#|\/)/.test(relative_url))
     5832                        return relative_url;
     5833
     5834                // Split parts
     5835                baseURLParts = baseURL.path.split('/');
     5836                relURLParts = relURL.path.split('/');
     5837
     5838                // Remove empty chunks
     5839                newBaseURLParts = [];
     5840                for (i=baseURLParts.length-1; i>=0; i--) {
     5841                        if (baseURLParts[i].length == 0)
     5842                                continue;
     5843
     5844                        newBaseURLParts[newBaseURLParts.length] = baseURLParts[i];
     5845                }
     5846                baseURLParts = newBaseURLParts.reverse();
     5847
     5848                // Merge relURLParts chunks
     5849                newRelURLParts = [];
     5850                numBack = 0;
     5851                for (i=relURLParts.length-1; i>=0; i--) {
     5852                        if (relURLParts[i].length == 0 || relURLParts[i] == ".")
     5853                                continue;
     5854
     5855                        if (relURLParts[i] == '..') {
     5856                                numBack++;
     5857                                continue;
     5858                        }
     5859
     5860                        if (numBack > 0) {
     5861                                numBack--;
     5862                                continue;
     5863                        }
     5864
     5865                        newRelURLParts[newRelURLParts.length] = relURLParts[i];
     5866                }
     5867
     5868                relURLParts = newRelURLParts.reverse();
     5869
     5870                // Remove end from absolute path
     5871                len = baseURLParts.length-numBack;
     5872                absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');
     5873                start = "";
     5874                end = "";
     5875
     5876                // Build output URL
     5877                relURL.protocol = baseURL.protocol;
     5878                relURL.host = baseURL.host;
     5879                relURL.port = baseURL.port;
     5880
     5881                // Re-add trailing slash if it's removed
     5882                if (relURL.path.charAt(relURL.path.length-1) == "/")
     5883                        absPath += "/";
     5884
     5885                relURL.path = absPath;
     5886
     5887                return this.serializeURL(relURL);
     5888        },
     5889
     5890        convertURL : function(url, node, on_save) {
     5891                var dl = document.location, start, portPart, urlParts, baseUrlParts, tmpUrlParts, curl;
     5892                var prot = dl.protocol, host = dl.hostname, port = dl.port;
     5893
     5894                // Pass through file protocol
     5895                if (prot == "file:")
     5896                        return url;
     5897
     5898                // Something is wrong, remove weirdness
     5899                url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
     5900
     5901                // Mailto link or anchor (Pass through)
     5902                if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || /^[ \t\r\n\+]*[#\?]/.test(url))
     5903                        return url;
     5904
     5905                // Fix relative/Mozilla
     5906                if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
     5907                        return tinyMCE.settings.base_href + url;
     5908
     5909                // Handle relative URLs
     5910                if (on_save && tinyMCE.getParam('relative_urls')) {
     5911                        curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url);
     5912                        if (curl.charAt(0) == '/')
     5913                                curl = tinyMCE.settings.document_base_prefix + curl;
     5914
     5915                        urlParts = tinyMCE.parseURL(curl);
     5916                        tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings.document_base_url);
     5917
     5918                        // Force relative
     5919                        if (urlParts.host == tmpUrlParts.host && (urlParts.port == tmpUrlParts.port))
     5920                                return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings.document_base_url, curl);
     5921                }
     5922
     5923                // Handle absolute URLs
     5924                if (!tinyMCE.getParam('relative_urls')) {
     5925                        urlParts = tinyMCE.parseURL(url);
     5926                        baseUrlParts = tinyMCE.parseURL(tinyMCE.settings.base_href);
     5927
     5928                        // Force absolute URLs from relative URLs
     5929                        url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url);
     5930
     5931                        // If anchor and path is the same page
     5932                        if (urlParts.anchor && urlParts.path == baseUrlParts.path)
     5933                                return "#" + urlParts.anchor;
     5934                }
     5935
     5936                // Remove current domain
     5937                if (tinyMCE.getParam('remove_script_host')) {
     5938                        start = "";
     5939                        portPart = "";
     5940
     5941                        if (port !== '')
     5942                                portPart = ":" + port;
     5943
     5944                        start = prot + "//" + host + portPart + "/";
     5945
     5946                        if (url.indexOf(start) == 0)
     5947                                url = url.substring(start.length-1);
     5948                }
     5949
     5950                return url;
     5951        },
     5952
     5953        convertAllRelativeURLs : function(body) {
     5954                var i, elms, src, href, mhref, msrc;
     5955
     5956                // Convert all image URL:s to absolute URL
     5957                elms = body.getElementsByTagName("img");
     5958                for (i=0; i<elms.length; i++) {
     5959                        src = tinyMCE.getAttrib(elms[i], 'src');
     5960
     5961                        msrc = tinyMCE.getAttrib(elms[i], 'mce_src');
     5962                        if (msrc !== '')
     5963                                src = msrc;
     5964
     5965                        if (src !== '') {
     5966                                src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, src);
     5967                                elms[i].setAttribute("src", src);
     5968                        }
     5969                }
     5970
     5971                // Convert all link URL:s to absolute URL
     5972                elms = body.getElementsByTagName("a");
     5973                for (i=0; i<elms.length; i++) {
     5974                        href = tinyMCE.getAttrib(elms[i], 'href');
     5975
     5976                        mhref = tinyMCE.getAttrib(elms[i], 'mce_href');
     5977                        if (mhref !== '')
     5978                                href = mhref;
     5979
     5980                        if (href && href !== '') {
     5981                                href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, href);
     5982                                elms[i].setAttribute("href", href);
     5983                        }
    51785984                }
    51795985        }
    51805986
    5181         if (h)
    5182                 o.innerHTML = h;
    5183 
    5184         return o;
    5185 };
    5186 
    5187 TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) {
    5188         return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
    5189 };
    5190 
    5191 TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) {
    5192         var i, nl = n.getElementsByTagName(e), o = new Array();
    5193 
    5194         for (i=0; i<nl.length; i++) {
    5195                 if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1)
    5196                         o[o.length] = nl[i];
     5987        });
     5988
     5989/* file:jscripts/tiny_mce/classes/TinyMCE_Array.class.js */
     5990
     5991tinyMCE.add(TinyMCE_Engine, {
     5992        clearArray : function(a) {
     5993                var n;
     5994
     5995                for (n in a)
     5996                        a[n] = null;
     5997
     5998                return a;
     5999        },
     6000
     6001        explode : function(d, s) {
     6002                var ar = s.split(d), oar = [], i;
     6003
     6004                for (i = 0; i<ar.length; i++) {
     6005                        if (ar[i] !== '')
     6006                                oar[oar.length] = ar[i];
     6007                }
     6008
     6009                return oar;
    51976010        }
    5198 
    5199         return o;
    5200 };
    5201 
    5202 TinyMCE_Engine.prototype.isBlockElement = function(n) {
    5203         return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName);
    5204 };
    5205 
    5206 TinyMCE_Engine.prototype.getParentBlockElement = function(n, r) {
    5207         return this.getParentNode(n, function(n) {
    5208                 return tinyMCE.isBlockElement(n);
    5209         }, r);
    5210 
    5211         return null;
    5212 };
    5213 
    5214 TinyMCE_Engine.prototype.insertAfter = function(n, r){
    5215         if (r.nextSibling)
    5216                 r.parentNode.insertBefore(n, r.nextSibling);
    5217         else
    5218                 r.parentNode.appendChild(n);
    5219 };
    5220 
    5221 TinyMCE_Engine.prototype.setInnerHTML = function(e, h) {
    5222         var i, nl, n;
    5223 
    5224         // Convert all strong/em to b/i in Gecko
    5225         if (tinyMCE.isGecko) {
    5226                 h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>');
    5227                 h = h.replace(/<em([^>]*)>/gi, '<i$1>');
    5228                 h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>');
    5229                 h = h.replace(/<strong([^>]*)>/gi, '<b$1>');
    5230                 h = h.replace(/<\/strong>/gi, '</b>');
    5231                 h = h.replace(/<\/em>/gi, '</i>');
    5232         }
    5233 
    5234         if (tinyMCE.isRealIE) {
    5235                 // Since MSIE handles invalid HTML better that valid XHTML we
    5236                 // need to make some things invalid. <hr /> gets converted to <hr>.
    5237                 h = h.replace(/\s\/>/g, '>');
    5238 
    5239                 // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
    5240                 h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
    5241                 h = h.replace(/<p([^>]*)>\s*&nbsp;\s*<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
    5242                 h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
    5243 
    5244                 // Remove first comment
    5245                 e.innerHTML = tinyMCE.uniqueTag + h;
    5246                 e.firstChild.removeNode(true);
    5247 
    5248                 // Remove weird auto generated empty paragraphs unless it's supposed to be there
    5249                 nl = e.getElementsByTagName("p");
    5250                 for (i=nl.length-1; i>=0; i--) {
    5251                         n = nl[i];
    5252 
    5253                         if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
    5254                                 n.parentNode.removeChild(n);
    5255                 }
    5256         } else {
    5257                 h = this.fixGeckoBaseHREFBug(1, e, h);
    5258                 e.innerHTML = h;
    5259                 this.fixGeckoBaseHREFBug(2, e, h);
    5260         }
    5261 };
    5262 
    5263 TinyMCE_Engine.prototype.getOuterHTML = function(e) {
    5264         if (tinyMCE.isIE)
    5265                 return e.outerHTML;
    5266 
    5267         var d = e.ownerDocument.createElement("body");
    5268         d.appendChild(e.cloneNode(true));
    5269         return d.innerHTML;
    5270 };
    5271 
    5272 TinyMCE_Engine.prototype.setOuterHTML = function(e, h, d) {
    5273         var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t;
    5274 
    5275         if (tinyMCE.isIE && e.nodeType == 1)
    5276                 e.outerHTML = h;
    5277         else {
    5278                 t = d.createElement("body");
    5279                 t.innerHTML = h;
    5280 
    5281                 for (i=0, nl=t.childNodes; i<nl.length; i++)
    5282                         e.parentNode.insertBefore(nl[i].cloneNode(true), e);
    5283 
    5284                 e.parentNode.removeChild(e);
    5285         }
    5286 };
    5287 
    5288 TinyMCE_Engine.prototype._getElementById = function(id, d) {
    5289         var e, i, j, f;
    5290 
    5291         if (typeof(d) == "undefined")
    5292                 d = document;
    5293 
    5294         e = d.getElementById(id);
    5295         if (!e) {
    5296                 f = d.forms;
    5297 
    5298                 for (i=0; i<f.length; i++) {
    5299                         for (j=0; j<f[i].elements.length; j++) {
    5300                                 if (f[i].elements[j].name == id) {
    5301                                         e = f[i].elements[j];
    5302                                         break;
    5303                                 }
    5304                         }
    5305                 }
    5306         }
    5307 
    5308         return e;
    5309 };
    5310 
    5311 TinyMCE_Engine.prototype.getNodeTree = function(n, na, t, nn) {
    5312         return this.selectNodes(n, function(n) {
    5313                 return (!t || n.nodeType == t) && (!nn || n.nodeName == nn);
    5314         }, na ? na : new Array());
    5315 };
    5316 
    5317 TinyMCE_Engine.prototype.getParentElement = function(n, na, f, r) {
    5318         var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v;
    5319 
    5320         // Compatiblity with old scripts where f param was a attribute string
    5321         if (f && typeof(f) == 'string')
    5322                 return this.getParentElement(n, na, function(no) {return tinyMCE.getAttrib(no, f) != '';});
    5323 
    5324         return this.getParentNode(n, function(n) {
    5325                 return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n));
    5326         }, r);
    5327 };
    5328 
    5329 TinyMCE_Engine.prototype.getParentNode = function(n, f, r) {
    5330         while (n) {
    5331                 if (n == r)
    5332                         return null;
    5333 
    5334                 if (f(n))
    5335                         return n;
    5336 
    5337                 n = n.parentNode;
    5338         }
    5339 
    5340         return null;
    5341 };
    5342 
    5343 TinyMCE_Engine.prototype.getAttrib = function(elm, name, dv) {
    5344         var v;
    5345 
    5346         if (typeof(dv) == "undefined")
    5347                 dv = "";
    5348 
    5349         // Not a element
    5350         if (!elm || elm.nodeType != 1)
    5351                 return dv;
    5352 
    5353         try {
    5354                 v = elm.getAttribute(name, 0);
    5355         } catch (ex) {
    5356                 // IE 7 may cast exception on invalid attributes
    5357                 v = elm.getAttribute(name, 2);
    5358         }
    5359 
    5360         // Try className for class attrib
    5361         if (name == "class" && !v)
    5362                 v = elm.className;
    5363 
    5364         // Workaround for a issue with Firefox 1.5rc2+
    5365         if (tinyMCE.isGecko && name == "src" && elm.src != null && elm.src != "")
    5366                 v = elm.src;
    5367 
    5368         // Workaround for a issue with Firefox 1.5rc2+
    5369         if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "")
    5370                 v = elm.href;
    5371 
    5372         if (name == "http-equiv" && tinyMCE.isIE)
    5373                 v = elm.httpEquiv;
    5374 
    5375         if (name == "style" && !tinyMCE.isOpera)
    5376                 v = elm.style.cssText;
    5377 
    5378         return (v && v != "") ? v : dv;
    5379 };
    5380 
    5381 TinyMCE_Engine.prototype.setAttrib = function(el, name, va, fix) {
    5382         if (typeof(va) == "number" && va != null)
    5383                 va = "" + va;
    5384 
    5385         if (fix) {
    5386                 if (va == null)
    5387                         va = "";
    5388 
    5389                 va = va.replace(/[^0-9%]/g, '');
    5390         }
    5391 
    5392         if (name == "style")
    5393                 el.style.cssText = va;
    5394 
    5395         if (name == "class")
    5396                 el.className = va;
    5397 
    5398         if (va != null && va != "" && va != -1)
    5399                 el.setAttribute(name, va);
    5400         else
    5401                 el.removeAttribute(name);
    5402 };
    5403 
    5404 TinyMCE_Engine.prototype.setStyleAttrib = function(e, n, v) {
    5405         e.style[n] = v;
    5406 
    5407         // Style attrib deleted in IE
    5408         if (tinyMCE.isIE && v == null || v == '') {
    5409                 v = tinyMCE.serializeStyle(tinyMCE.parseStyle(e.style.cssText));
    5410                 e.style.cssText = v;
    5411                 e.setAttribute("style", v);
    5412         }
    5413 };
    5414 
    5415 TinyMCE_Engine.prototype.switchClass = function(ei, c) {
    5416         var e;
    5417 
    5418         if (tinyMCE.switchClassCache[ei])
    5419                 e = tinyMCE.switchClassCache[ei];
    5420         else
    5421                 e = tinyMCE.switchClassCache[ei] = document.getElementById(ei);
    5422 
    5423         if (e) {
    5424                 // Keep tile mode
    5425                 if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0)
    5426                         c = 'mceTiledButton ' + c;
    5427 
    5428                 e.className = c;
    5429         }
    5430 };
    5431 
    5432 TinyMCE_Engine.prototype.getAbsPosition = function(n, cn) {
    5433         var l = 0, t = 0;
    5434 
    5435         while (n && n != cn) {
    5436                 l += n.offsetLeft;
    5437                 t += n.offsetTop;
    5438                 n = n.offsetParent;
    5439         }
    5440 
    5441         return {absLeft : l, absTop : t};
    5442 };
    5443 
    5444 TinyMCE_Engine.prototype.prevNode = function(e, n) {
    5445         var a = n.split(','), i;
    5446 
    5447         while ((e = e.previousSibling) != null) {
    5448                 for (i=0; i<a.length; i++) {
    5449                         if (e.nodeName == a[i])
    5450                                 return e;
    5451                 }
    5452         }
    5453 
    5454         return null;
    5455 };
    5456 
    5457 TinyMCE_Engine.prototype.nextNode = function(e, n) {
    5458         var a = n.split(','), i;
    5459 
    5460         while ((e = e.nextSibling) != null) {
    5461                 for (i=0; i<a.length; i++) {
    5462                         if (e.nodeName == a[i])
    5463                                 return e;
    5464                 }
    5465         }
    5466 
    5467         return null;
    5468 };
    5469 
    5470 TinyMCE_Engine.prototype.selectElements = function(n, na, f) {
    5471         var i, a = [], nl, x;
    5472 
    5473         for (x=0, na = na.split(','); x<na.length; x++)
    5474                 for (i=0, nl = n.getElementsByTagName(na[x]); i<nl.length; i++)
    5475                         (!f || f(nl[i])) && a.push(nl[i]);
    5476 
    5477         return a;
    5478 };
    5479 
    5480 TinyMCE_Engine.prototype.selectNodes = function(n, f, a) {
    5481         var i;
    5482 
    5483         if (!a)
    5484                 a = new Array();
    5485 
    5486         if (f(n))
    5487                 a[a.length] = n;
    5488 
    5489         if (n.hasChildNodes()) {
    5490                 for (i=0; i<n.childNodes.length; i++)
    5491                         tinyMCE.selectNodes(n.childNodes[i], f, a);
    5492         }
    5493 
    5494         return a;
    5495 };
    5496 
    5497 TinyMCE_Engine.prototype.addCSSClass = function(e, c, b) {
    5498         var o = this.removeCSSClass(e, c);
    5499         return e.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
    5500 };
    5501 
    5502 TinyMCE_Engine.prototype.removeCSSClass = function(e, c) {
    5503         c = e.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
    5504         return e.className = c != ' ' ? c : '';
    5505 };
    5506 
    5507 TinyMCE_Engine.prototype.hasCSSClass = function(n, c) {
    5508         return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
    5509 };
    5510 
    5511 TinyMCE_Engine.prototype.renameElement = function(e, n, d) {
    5512         var ne, i, ar;
    5513 
    5514         d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d;
    5515 
    5516         if (e) {
    5517                 ne = d.createElement(n);
    5518 
    5519                 ar = e.attributes;
    5520                 for (i=ar.length-1; i>-1; i--) {
    5521                         if (ar[i].specified && ar[i].nodeValue)
    5522                                 ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
    5523                 }
    5524 
    5525                 ar = e.childNodes;
    5526                 for (i=0; i<ar.length; i++)
    5527                         ne.appendChild(ar[i].cloneNode(true));
    5528 
    5529                 e.parentNode.replaceChild(ne, e);
    5530         }
    5531 };
    5532 
    5533 TinyMCE_Engine.prototype.getViewPort = function(w) {
    5534         var d = w.document, m = d.compatMode == 'CSS1Compat', b = d.body, de = d.documentElement;
    5535 
    5536         return {
    5537                 left : w.pageXOffset || (m ? de.scrollLeft : b.scrollLeft),
    5538                 top : w.pageYOffset || (m ? de.scrollTop : b.scrollTop),
    5539                 width : w.innerWidth || (m ? de.clientWidth : b.clientWidth),
    5540                 height : w.innerHeight || (m ? de.clientHeight : b.clientHeight)
    5541         };
    5542 };
    5543 
    5544 TinyMCE_Engine.prototype.getStyle = function(n, na, d) {
    5545         if (!n)
    5546                 return false;
    5547 
    5548         // Gecko
    5549         if (tinyMCE.isGecko && n.ownerDocument.defaultView) {
     6011});
     6012
     6013/* file:jscripts/tiny_mce/classes/TinyMCE_Event.class.js */
     6014
     6015tinyMCE.add(TinyMCE_Engine, {
     6016        _setEventsEnabled : function(node, state) {
     6017                var evs, x, y, elms, i, event;
     6018                var events = ['onfocus','onblur','onclick','ondblclick',
     6019                                        'onmousedown','onmouseup','onmouseover','onmousemove',
     6020                                        'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup'];
     6021
     6022                evs = tinyMCE.settings.event_elements.split(',');
     6023                for (y=0; y<evs.length; y++){
     6024                        elms = node.getElementsByTagName(evs[y]);
     6025                        for (i=0; i<elms.length; i++) {
     6026                                event = "";
     6027
     6028                                for (x=0; x<events.length; x++) {
     6029                                        if ((event = tinyMCE.getAttrib(elms[i], events[x])) !== '') {
     6030                                                event = tinyMCE.cleanupEventStr("" + event);
     6031
     6032                                                if (!state)
     6033                                                        event = "return true;" + event;
     6034                                                else
     6035                                                        event = event.replace(/^return true;/gi, '');
     6036
     6037                                                elms[i].removeAttribute(events[x]);
     6038                                                elms[i].setAttribute(events[x], event);
     6039                                        }
     6040                                }
     6041                        }
     6042                }
     6043        },
     6044
     6045        _eventPatch : function(editor_id) {
     6046                var n, inst, win, e;
     6047
     6048                // Remove odd, error
     6049                if (typeof(tinyMCE) == "undefined")
     6050                        return true;
     6051
    55506052                try {
    5551                         return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na);
    5552                 } catch (n) {
    5553                         // Old safari might fail
    5554                         return null;
    5555                 }
    5556         }
    5557 
    5558         // Camelcase it, if needed
    5559         na = na.replace(/-(\D)/g, function(a, b){
    5560                 return b.toUpperCase();
    5561         });
    5562 
    5563         // IE & Opera
    5564         if (n.currentStyle)
    5565                 return n.currentStyle[na];
    5566 
    5567         return false;
    5568 };
    5569 
    5570 /* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */
    5571 
    5572 TinyMCE_Engine.prototype.parseURL = function(url_str) {
    5573         var urlParts = new Array();
    5574 
    5575         if (url_str) {
    5576                 var pos, lastPos;
    5577 
    5578                 // Parse protocol part
    5579                 pos = url_str.indexOf('://');
    5580                 if (pos != -1) {
    5581                         urlParts['protocol'] = url_str.substring(0, pos);
    5582                         lastPos = pos + 3;
    5583                 }
    5584 
    5585                 // Find port or path start
    5586                 for (var i=lastPos; i<url_str.length; i++) {
    5587                         var chr = url_str.charAt(i);
    5588 
    5589                         if (chr == ':')
    5590                                 break;
    5591 
    5592                         if (chr == '/')
    5593                                 break;
    5594                 }
    5595                 pos = i;
    5596 
    5597                 // Get host
    5598                 urlParts['host'] = url_str.substring(lastPos, pos);
    5599 
    5600                 // Get port
    5601                 urlParts['port'] = "";
    5602                 lastPos = pos;
    5603                 if (url_str.charAt(pos) == ':') {
    5604                         pos = url_str.indexOf('/', lastPos);
    5605                         urlParts['port'] = url_str.substring(lastPos+1, pos);
    5606                 }
    5607 
    5608                 // Get path
    5609                 lastPos = pos;
    5610                 pos = url_str.indexOf('?', lastPos);
    5611 
    5612                 if (pos == -1)
    5613                         pos = url_str.indexOf('#', lastPos);
    5614 
    5615                 if (pos == -1)
    5616                         pos = url_str.length;
    5617 
    5618                 urlParts['path'] = url_str.substring(lastPos, pos);
    5619 
    5620                 // Get query
    5621                 lastPos = pos;
    5622                 if (url_str.charAt(pos) == '?') {
    5623                         pos = url_str.indexOf('#');
    5624                         pos = (pos == -1) ? url_str.length : pos;
    5625                         urlParts['query'] = url_str.substring(lastPos+1, pos);
    5626                 }
    5627 
    5628                 // Get anchor
    5629                 lastPos = pos;
    5630                 if (url_str.charAt(pos) == '#') {
    5631                         pos = url_str.length;
    5632                         urlParts['anchor'] = url_str.substring(lastPos+1, pos);
    5633                 }
    5634         }
    5635 
    5636         return urlParts;
    5637 };
    5638 
    5639 TinyMCE_Engine.prototype.serializeURL = function(up) {
    5640         var o = "";
    5641 
    5642         if (up['protocol'])
    5643                 o += up['protocol'] + "://";
    5644 
    5645         if (up['host'])
    5646                 o += up['host'];
    5647 
    5648         if (up['port'])
    5649                 o += ":" + up['port'];
    5650 
    5651         if (up['path'])
    5652                 o += up['path'];
    5653 
    5654         if (up['query'])
    5655                 o += "?" + up['query'];
    5656 
    5657         if (up['anchor'])
    5658                 o += "#" + up['anchor'];
    5659 
    5660         return o;
    5661 };
    5662 
    5663 TinyMCE_Engine.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) {
    5664         var baseURL = this.parseURL(base_url);
    5665         var targetURL = this.parseURL(url_to_relative);
    5666         var strTok1;
    5667         var strTok2;
    5668         var breakPoint = 0;
    5669         var outPath = "";
    5670         var forceSlash = false;
    5671 
    5672         if (targetURL.path == "")
    5673                 targetURL.path = "/";
    5674         else
    5675                 forceSlash = true;
    5676 
    5677         // Crop away last path part
    5678         base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/'));
    5679         strTok1 = base_url.split('/');
    5680         strTok2 = targetURL.path.split('/');
    5681 
    5682         if (strTok1.length >= strTok2.length) {
    5683                 for (var i=0; i<strTok1.length; i++) {
    5684                         if (i >= strTok2.length || strTok1[i] != strTok2[i]) {
    5685                                 breakPoint = i + 1;
    5686                                 break;
    5687                         }
    5688                 }
    5689         }
    5690 
    5691         if (strTok1.length < strTok2.length) {
    5692                 for (var i=0; i<strTok2.length; i++) {
    5693                         if (i >= strTok1.length || strTok1[i] != strTok2[i]) {
    5694                                 breakPoint = i + 1;
    5695                                 break;
    5696                         }
    5697                 }
    5698         }
    5699 
    5700         if (breakPoint == 1)
    5701                 return targetURL.path;
    5702 
    5703         for (var i=0; i<(strTok1.length-(breakPoint-1)); i++)
    5704                 outPath += "../";
    5705 
    5706         for (var i=breakPoint-1; i<strTok2.length; i++) {
    5707                 if (i != (breakPoint-1))
    5708                         outPath += "/" + strTok2[i];
    5709                 else
    5710                         outPath += strTok2[i];
    5711         }
    5712 
    5713         targetURL.protocol = null;
    5714         targetURL.host = null;
    5715         targetURL.port = null;
    5716         targetURL.path = outPath == "" && forceSlash ? "/" : outPath;
    5717 
    5718         // Remove document prefix from local anchors
    5719         var fileName = baseURL.path;
    5720         var pos;
    5721 
    5722         if ((pos = fileName.lastIndexOf('/')) != -1)
    5723                 fileName = fileName.substring(pos + 1);
    5724 
    5725         // Is local anchor
    5726         if (fileName == targetURL.path && targetURL.anchor != "")
    5727                 targetURL.path = "";
    5728 
    5729         // If empty and not local anchor force filename or slash
    5730         if (targetURL.path == "" && !targetURL.anchor)
    5731                 targetURL.path = fileName != "" ? fileName : "/";
    5732 
    5733         return this.serializeURL(targetURL);
    5734 };
    5735 
    5736 TinyMCE_Engine.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) {
    5737         var baseURL = this.parseURL(base_url), baseURLParts, relURLParts;
    5738         var relURL = this.parseURL(relative_url);
    5739 
    5740         if (relative_url == "" || relative_url.indexOf('://') != -1 || /^(mailto:|javascript:|#|\/)/.test(relative_url))
    5741                 return relative_url;
    5742 
    5743         // Split parts
    5744         baseURLParts = baseURL['path'].split('/');
    5745         relURLParts = relURL['path'].split('/');
    5746 
    5747         // Remove empty chunks
    5748         var newBaseURLParts = new Array();
    5749         for (var i=baseURLParts.length-1; i>=0; i--) {
    5750                 if (baseURLParts[i].length == 0)
    5751                         continue;
    5752 
    5753                 newBaseURLParts[newBaseURLParts.length] = baseURLParts[i];
    5754         }
    5755         baseURLParts = newBaseURLParts.reverse();
    5756 
    5757         // Merge relURLParts chunks
    5758         var newRelURLParts = new Array();
    5759         var numBack = 0;
    5760         for (var i=relURLParts.length-1; i>=0; i--) {
    5761                 if (relURLParts[i].length == 0 || relURLParts[i] == ".")
    5762                         continue;
    5763 
    5764                 if (relURLParts[i] == '..') {
    5765                         numBack++;
    5766                         continue;
    5767                 }
    5768 
    5769                 if (numBack > 0) {
    5770                         numBack--;
    5771                         continue;
    5772                 }
    5773 
    5774                 newRelURLParts[newRelURLParts.length] = relURLParts[i];
    5775         }
    5776 
    5777         relURLParts = newRelURLParts.reverse();
    5778 
    5779         // Remove end from absolute path
    5780         var len = baseURLParts.length-numBack;
    5781         var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');
    5782         var start = "", end = "";
    5783 
    5784         // Build output URL
    5785         relURL.protocol = baseURL.protocol;
    5786         relURL.host = baseURL.host;
    5787         relURL.port = baseURL.port;
    5788 
    5789         // Re-add trailing slash if it's removed
    5790         if (relURL.path.charAt(relURL.path.length-1) == "/")
    5791                 absPath += "/";
    5792 
    5793         relURL.path = absPath;
    5794 
    5795         return this.serializeURL(relURL);
    5796 };
    5797 
    5798 TinyMCE_Engine.prototype.convertURL = function(url, node, on_save) {
    5799         var prot = document.location.protocol;
    5800         var host = document.location.hostname;
    5801         var port = document.location.port;
    5802 
    5803         // Pass through file protocol
    5804         if (prot == "file:")
    5805                 return url;
    5806 
    5807         // Something is wrong, remove weirdness
    5808         url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
    5809 
    5810         // Mailto link or anchor (Pass through)
    5811         if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#")
    5812                 return url;
    5813 
    5814         // Fix relative/Mozilla
    5815         if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
    5816                 return tinyMCE.settings['base_href'] + url;
    5817 
    5818         // Handle relative URLs
    5819         if (on_save && tinyMCE.getParam('relative_urls')) {
    5820                 var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
    5821                 if (curl.charAt(0) == '/')
    5822                         curl = tinyMCE.settings['document_base_prefix'] + curl;
    5823 
    5824                 var urlParts = tinyMCE.parseURL(curl);
    5825                 var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);
    5826 
    5827                 // Force relative
    5828                 if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))
    5829                         return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);
    5830         }
    5831 
    5832         // Handle absolute URLs
    5833         if (!tinyMCE.getParam('relative_urls')) {
    5834                 var urlParts = tinyMCE.parseURL(url);
    5835                 var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);
    5836 
    5837                 // Force absolute URLs from relative URLs
    5838                 url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
    5839 
    5840                 // If anchor and path is the same page
    5841                 if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])
    5842                         return "#" + urlParts['anchor'];
    5843         }
    5844 
    5845         // Remove current domain
    5846         if (tinyMCE.getParam('remove_script_host')) {
    5847                 var start = "", portPart = "";
    5848 
    5849                 if (port != "")
    5850                         portPart = ":" + port;
    5851 
    5852                 start = prot + "//" + host + portPart + "/";
    5853 
    5854                 if (url.indexOf(start) == 0)
    5855                         url = url.substring(start.length-1);
    5856         }
    5857 
    5858         return url;
    5859 };
    5860 
    5861 TinyMCE_Engine.prototype.convertAllRelativeURLs = function(body) {
    5862         var i, elms, src, href, mhref, msrc;
    5863 
    5864         // Convert all image URL:s to absolute URL
    5865         elms = body.getElementsByTagName("img");
    5866         for (i=0; i<elms.length; i++) {
    5867                 src = tinyMCE.getAttrib(elms[i], 'src');
    5868 
    5869                 msrc = tinyMCE.getAttrib(elms[i], 'mce_src');
    5870                 if (msrc != "")
    5871                         src = msrc;
    5872 
    5873                 if (src != "") {
    5874                         src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src);
    5875                         elms[i].setAttribute("src", src);
    5876                 }
    5877         }
    5878 
    5879         // Convert all link URL:s to absolute URL
    5880         elms = body.getElementsByTagName("a");
    5881         for (i=0; i<elms.length; i++) {
    5882                 href = tinyMCE.getAttrib(elms[i], 'href');
    5883 
    5884                 mhref = tinyMCE.getAttrib(elms[i], 'mce_href');
    5885                 if (mhref != "")
    5886                         href = mhref;
    5887 
    5888                 if (href && href != "") {
    5889                         href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], href);
    5890                         elms[i].setAttribute("href", href);
    5891                 }
    5892         }
    5893 };
    5894 
    5895 /* file:jscripts/tiny_mce/classes/TinyMCE_Array.class.js */
    5896 
    5897 TinyMCE_Engine.prototype.clearArray = function(a) {
    5898         var n;
    5899 
    5900         for (n in a)
    5901                 a[n] = null;
    5902 
    5903         return a;
    5904 };
    5905 
    5906 TinyMCE_Engine.prototype.explode = function(d, s) {
    5907         var ar = s.split(d), oar = new Array(), i;
    5908 
    5909         for (i = 0; i<ar.length; i++) {
    5910                 if (ar[i] != "")
    5911                         oar[oar.length] = ar[i];
    5912         }
    5913 
    5914         return oar;
    5915 };
    5916 
    5917 /* file:jscripts/tiny_mce/classes/TinyMCE_Event.class.js */
    5918 
    5919 TinyMCE_Engine.prototype._setEventsEnabled = function(node, state) {
    5920         var evs, x, y, elms, i, event;
    5921         var events = ['onfocus','onblur','onclick','ondblclick',
    5922                                 'onmousedown','onmouseup','onmouseover','onmousemove',
    5923                                 'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup'];
    5924 
    5925         evs = tinyMCE.settings['event_elements'].split(',');
    5926         for (y=0; y<evs.length; y++){
    5927                 elms = node.getElementsByTagName(evs[y]);
    5928                 for (i=0; i<elms.length; i++) {
    5929                         event = "";
    5930 
    5931                         for (x=0; x<events.length; x++) {
    5932                                 if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {
    5933                                         event = tinyMCE.cleanupEventStr("" + event);
    5934 
    5935                                         if (!state)
    5936                                                 event = "return true;" + event;
    5937                                         else
    5938                                                 event = event.replace(/^return true;/gi, '');
    5939 
    5940                                         elms[i].removeAttribute(events[x]);
    5941                                         elms[i].setAttribute(events[x], event);
    5942                                 }
    5943                         }
    5944                 }
    5945         }
    5946 };
    5947 
    5948 TinyMCE_Engine.prototype._eventPatch = function(editor_id) {
    5949         var n, inst, win, e;
    5950 
    5951         // Remove odd, error
    5952         if (typeof(tinyMCE) == "undefined")
    5953                 return true;
    5954 
    5955         try {
    5956                 // Try selected instance first
    5957                 if (tinyMCE.selectedInstance) {
    5958                         win = tinyMCE.selectedInstance.getWin();
    5959 
    5960                         if (win && win.event) {
    5961                                 e = win.event;
    5962 
    5963                                 if (!e.target)
    5964                                         e.target = e.srcElement;
    5965 
    5966                                 TinyMCE_Engine.prototype.handleEvent(e);
    5967                                 return;
    5968                         }
    5969                 }
    5970 
    5971                 // Search for it
     6053                        // Try selected instance first
     6054                        if (tinyMCE.selectedInstance) {
     6055                                win = tinyMCE.selectedInstance.getWin();
     6056
     6057                                if (win && win.event) {
     6058                                        e = win.event;
     6059
     6060                                        if (!e.target)
     6061                                                e.target = e.srcElement;
     6062
     6063                                        TinyMCE_Engine.prototype.handleEvent(e);
     6064                                        return;
     6065                                }
     6066                        }
     6067
     6068                        // Search for it
     6069                        for (n in tinyMCE.instances) {
     6070                                inst = tinyMCE.instances[n];
     6071
     6072                                if (!tinyMCE.isInstance(inst))
     6073                                        continue;
     6074
     6075                                inst.select();
     6076                                win = inst.getWin();
     6077
     6078                                if (win && win.event) {
     6079                                        e = win.event;
     6080
     6081                                        if (!e.target)
     6082                                                e.target = e.srcElement;
     6083
     6084                                        TinyMCE_Engine.prototype.handleEvent(e);
     6085                                        return;
     6086                                }
     6087                        }
     6088                } catch (ex) {
     6089                        // Ignore error if iframe is pointing to external URL
     6090                }
     6091        },
     6092
     6093        findEvent : function(e) {
     6094                var n, inst;
     6095
     6096                if (e)
     6097                        return e;
     6098
    59726099                for (n in tinyMCE.instances) {
    59736100                        inst = tinyMCE.instances[n];
    59746101
    5975                         if (!tinyMCE.isInstance(inst))
    5976                                 continue;
    5977 
    5978                         inst.select();
    5979                         win = inst.getWin();
    5980 
    5981                         if (win && win.event) {
    5982                                 e = win.event;
    5983 
    5984                                 if (!e.target)
    5985                                         e.target = e.srcElement;
    5986 
    5987                                 TinyMCE_Engine.prototype.handleEvent(e);
    5988                                 return;
    5989                         }
    5990                 }
    5991         } catch (ex) {
    5992                 // Ignore error if iframe is pointing to external URL
     6102                        if (tinyMCE.isInstance(inst) && inst.getWin().event)
     6103                                return inst.getWin().event;
     6104                }
     6105
     6106                return null;
     6107        },
     6108
     6109        unloadHandler : function() {
     6110                tinyMCE.triggerSave(true, true);
     6111        },
     6112
     6113        addEventHandlers : function(inst) {
     6114                this.setEventHandlers(inst, 1);
     6115        },
     6116
     6117        setEventHandlers : function(inst, s) {
     6118                var doc = inst.getDoc(), ie, ot, i, f = s ? tinyMCE.addEvent : tinyMCE.removeEvent;
     6119
     6120                ie = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'controlselect', 'dblclick'];
     6121                ot = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'focus', 'blur', 'dragdrop'];
     6122
     6123                inst.switchSettings();
     6124
     6125                if (tinyMCE.isIE) {
     6126                        for (i=0; i<ie.length; i++)
     6127                                f(doc, ie[i], TinyMCE_Engine.prototype._eventPatch);
     6128                } else {
     6129                        for (i=0; i<ot.length; i++)
     6130                                f(doc, ot[i], tinyMCE.handleEvent);
     6131
     6132                        // Force designmode
     6133                        try {
     6134                                doc.designMode = "On";
     6135                        } catch (e) {
     6136                                // Ignore
     6137                        }
     6138                }
     6139        },
     6140
     6141        onMouseMove : function() {
     6142                var inst, lh;
     6143
     6144                // Fix for IE7 bug where it's not restoring hover on anchors correctly
     6145                if (tinyMCE.lastHover) {
     6146                        lh = tinyMCE.lastHover;
     6147
     6148                        // Call out on menus and refresh class on normal buttons
     6149                        if (lh.className.indexOf('mceMenu') != -1)
     6150                                tinyMCE._menuButtonEvent('out', lh);
     6151                        else
     6152                                lh.className = lh.className;
     6153
     6154                        tinyMCE.lastHover = null;
     6155                }
     6156
     6157                if (!tinyMCE.hasMouseMoved) {
     6158                        inst = tinyMCE.selectedInstance;
     6159
     6160                        // Workaround for bug #1437457 (Odd MSIE bug)
     6161                        if (inst.isFocused) {
     6162                                inst.undoBookmark = inst.selection.getBookmark();
     6163                                tinyMCE.hasMouseMoved = true;
     6164                        }
     6165                }
     6166
     6167        //      tinyMCE.cancelEvent(inst.getWin().event);
     6168        //      return false;
     6169        },
     6170
     6171        cancelEvent : function(e) {
     6172                if (!e)
     6173                        return false;
     6174
     6175                if (tinyMCE.isIE) {
     6176                        e.returnValue = false;
     6177                        e.cancelBubble = true;
     6178                } else {
     6179                        e.preventDefault();
     6180                        e.stopPropagation && e.stopPropagation();
     6181                }
     6182
     6183                return false;
     6184        },
     6185
     6186        addEvent : function(o, n, h) {
     6187                // Add cleanup for all non unload events
     6188                if (n != 'unload') {
     6189                        function clean() {
     6190                                var ex;
     6191
     6192                                try {
     6193                                        tinyMCE.removeEvent(o, n, h);
     6194                                        tinyMCE.removeEvent(window, 'unload', clean);
     6195                                        o = n = h = null;
     6196                                } catch (ex) {
     6197                                        // IE may produce access denied exception on unload
     6198                                }
     6199                        }
     6200
     6201                        // Add memory cleaner
     6202                        tinyMCE.addEvent(window, 'unload', clean);
     6203                }
     6204
     6205                if (o.attachEvent)
     6206                        o.attachEvent("on" + n, h);
     6207                else
     6208                        o.addEventListener(n, h, false);
     6209        },
     6210
     6211        removeEvent : function(o, n, h) {
     6212                if (o.detachEvent)
     6213                        o.detachEvent("on" + n, h);
     6214                else
     6215                        o.removeEventListener(n, h, false);
     6216        },
     6217
     6218        addSelectAccessibility : function(e, s, w) {
     6219                // Add event handlers
     6220                if (!s._isAccessible) {
     6221                        s.onkeydown = tinyMCE.accessibleEventHandler;
     6222                        s.onblur = tinyMCE.accessibleEventHandler;
     6223                        s._isAccessible = true;
     6224                        s._win = w;
     6225                }
     6226
     6227                return false;
     6228        },
     6229
     6230        accessibleEventHandler : function(e) {
     6231                var elm, win = this._win;
     6232
     6233                e = tinyMCE.isIE ? win.event : e;
     6234                elm = tinyMCE.isIE ? e.srcElement : e.target;
     6235
     6236                // Unpiggyback onchange on blur
     6237                if (e.type == "blur") {
     6238                        if (elm.oldonchange) {
     6239                                elm.onchange = elm.oldonchange;
     6240                                elm.oldonchange = null;
     6241                        }
     6242
     6243                        return true;
     6244                }
     6245
     6246                // Piggyback onchange
     6247                if (elm.nodeName == "SELECT" && !elm.oldonchange) {
     6248                        elm.oldonchange = elm.onchange;
     6249                        elm.onchange = null;
     6250                }
     6251
     6252                // Execute onchange and remove piggyback
     6253                if (e.keyCode == 13 || e.keyCode == 32) {
     6254                        elm.onchange = elm.oldonchange;
     6255                        elm.onchange();
     6256                        elm.oldonchange = null;
     6257
     6258                        tinyMCE.cancelEvent(e);
     6259                        return false;
     6260                }
     6261
     6262                return true;
     6263        },
     6264
     6265        _resetIframeHeight : function() {
     6266                var ife;
     6267
     6268                if (tinyMCE.isRealIE) {
     6269                        ife = tinyMCE.selectedInstance.iframeElement;
     6270
     6271        /*              if (ife._oldWidth) {
     6272                                ife.style.width = ife._oldWidth;
     6273                                ife.width = ife._oldWidth;
     6274                        }*/
     6275
     6276                        if (ife._oldHeight) {
     6277                                ife.style.height = ife._oldHeight;
     6278                                ife.height = ife._oldHeight;
     6279                        }
     6280                }
    59936281        }
    5994 };
    5995 
    5996 TinyMCE_Engine.prototype.findEvent = function(e) {
    5997         var n, inst;
    5998 
    5999         if (e)
    6000                 return e;
    6001 
    6002         for (n in tinyMCE.instances) {
    6003                 inst = tinyMCE.instances[n];
    6004 
    6005                 if (tinyMCE.isInstance(inst) && inst.getWin().event)
    6006                         return inst.getWin().event;
    6007         }
    6008 
    6009         return null;
    6010 };
    6011 
    6012 TinyMCE_Engine.prototype.unloadHandler = function() {
    6013         tinyMCE.triggerSave(true, true);
    6014 };
    6015 
    6016 TinyMCE_Engine.prototype.addEventHandlers = function(inst) {
    6017         this.setEventHandlers(inst, 1);
    6018 };
    6019 
    6020 TinyMCE_Engine.prototype.setEventHandlers = function(inst, s) {
    6021         var doc = inst.getDoc(), ie, ot, i, f = s ? tinyMCE.addEvent : tinyMCE.removeEvent;
    6022 
    6023         ie = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'controlselect', 'dblclick'];
    6024         ot = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'focus', 'blur', 'dragdrop'];
    6025 
    6026         inst.switchSettings();
    6027 
    6028         if (tinyMCE.isIE) {
    6029                 for (i=0; i<ie.length; i++)
    6030                         f(doc, ie[i], TinyMCE_Engine.prototype._eventPatch);
    6031         } else {
    6032                 for (i=0; i<ot.length; i++)
    6033                         f(doc, ot[i], tinyMCE.handleEvent);
    6034 
    6035                 // Force designmode
    6036                 try {
    6037                         doc.designMode = "On";
    6038                 } catch (e) {
    6039                         // Ignore
    6040                 }
    6041         }
    6042 };
    6043 
    6044 TinyMCE_Engine.prototype.onMouseMove = function() {
    6045         var inst, lh;
    6046 
    6047         // Fix for IE7 bug where it's not restoring hover on anchors correctly
    6048         if (tinyMCE.lastHover) {
    6049                 lh = tinyMCE.lastHover;
    6050 
    6051                 // Call out on menus and refresh class on normal buttons
    6052                 if (lh.className.indexOf('mceMenu') != -1)
    6053                         tinyMCE._menuButtonEvent('out', lh);
    6054                 else
    6055                         lh.className = lh.className;
    6056 
    6057                 tinyMCE.lastHover = null;
    6058         }
    6059 
    6060         if (!tinyMCE.hasMouseMoved) {
    6061                 inst = tinyMCE.selectedInstance;
    6062 
    6063                 // Workaround for bug #1437457 (Odd MSIE bug)
    6064                 if (inst.isFocused) {
    6065                         inst.undoBookmark = inst.selection.getBookmark();
    6066                         tinyMCE.hasMouseMoved = true;
    6067                 }
    6068         }
    6069 
    6070 //      tinyMCE.cancelEvent(inst.getWin().event);
    6071 //      return false;
    6072 };
    6073 
    6074 TinyMCE_Engine.prototype.cancelEvent = function(e) {
    6075         if (!e)
    6076                 return false;
    6077 
    6078         if (tinyMCE.isIE) {
    6079                 e.returnValue = false;
    6080                 e.cancelBubble = true;
    6081         } else {
    6082                 e.preventDefault();
    6083                 e.stopPropagation && e.stopPropagation();
    6084         }
    6085 
    6086         return false;
    6087 };
    6088 
    6089 TinyMCE_Engine.prototype.addEvent = function(o, n, h) {
    6090         // Add cleanup for all non unload events
    6091         if (n != 'unload') {
    6092                 function clean() {
    6093                         var ex;
    6094 
    6095                         try {
    6096                                 tinyMCE.removeEvent(o, n, h);
    6097                                 tinyMCE.removeEvent(window, 'unload', clean);
    6098                                 o = n = h = null;
    6099                         } catch (ex) {
    6100                                 // IE may produce access denied exception on unload
    6101                         }
    6102                 }
    6103 
    6104                 // Add memory cleaner
    6105                 tinyMCE.addEvent(window, 'unload', clean);
    6106         }
    6107 
    6108         if (o.attachEvent)
    6109                 o.attachEvent("on" + n, h);
    6110         else
    6111                 o.addEventListener(n, h, false);
    6112 };
    6113 
    6114 TinyMCE_Engine.prototype.removeEvent = function(o, n, h) {
    6115         if (o.detachEvent)
    6116                 o.detachEvent("on" + n, h);
    6117         else
    6118                 o.removeEventListener(n, h, false);
    6119 };
    6120 
    6121 TinyMCE_Engine.prototype.addSelectAccessibility = function(e, s, w) {
    6122         // Add event handlers
    6123         if (!s._isAccessible) {
    6124                 s.onkeydown = tinyMCE.accessibleEventHandler;
    6125                 s.onblur = tinyMCE.accessibleEventHandler;
    6126                 s._isAccessible = true;
    6127                 s._win = w;
    6128         }
    6129 
    6130         return false;
    6131 };
    6132 
    6133 TinyMCE_Engine.prototype.accessibleEventHandler = function(e) {
    6134         var win = this._win;
    6135         e = tinyMCE.isIE ? win.event : e;
    6136         var elm = tinyMCE.isIE ? e.srcElement : e.target;
    6137 
    6138         // Unpiggyback onchange on blur
    6139         if (e.type == "blur") {
    6140                 if (elm.oldonchange) {
    6141                         elm.onchange = elm.oldonchange;
    6142                         elm.oldonchange = null;
    6143                 }
    6144 
    6145                 return true;
    6146         }
    6147 
    6148         // Piggyback onchange
    6149         if (elm.nodeName == "SELECT" && !elm.oldonchange) {
    6150                 elm.oldonchange = elm.onchange;
    6151                 elm.onchange = null;
    6152         }
    6153 
    6154         // Execute onchange and remove piggyback
    6155         if (e.keyCode == 13 || e.keyCode == 32) {
    6156                 elm.onchange = elm.oldonchange;
    6157                 elm.onchange();
    6158                 elm.oldonchange = null;
    6159 
    6160                 tinyMCE.cancelEvent(e);
    6161                 return false;
    6162         }
    6163 
    6164         return true;
    6165 };
    6166 
    6167 TinyMCE_Engine.prototype._resetIframeHeight = function() {
    6168         var ife;
    6169 
    6170         if (tinyMCE.isRealIE) {
    6171                 ife = tinyMCE.selectedInstance.iframeElement;
    6172 
    6173 /*              if (ife._oldWidth) {
    6174                         ife.style.width = ife._oldWidth;
    6175                         ife.width = ife._oldWidth;
    6176                 }*/
    6177 
    6178                 if (ife._oldHeight) {
    6179                         ife.style.height = ife._oldHeight;
    6180                         ife.height = ife._oldHeight;
    6181                 }
    6182         }
    6183 };
     6282
     6283        });
    61846284
    61856285/* file:jscripts/tiny_mce/classes/TinyMCE_Selection.class.js */
     
    61916291TinyMCE_Selection.prototype = {
    61926292        getSelectedHTML : function() {
    6193                 var inst = this.instance;
    6194                 var e, r = this.getRng(), h;
     6293                var inst = this.instance, e, r = this.getRng(), h;
    61956294
    61966295                if (!r)
     
    62166315
    62176316        getSelectedText : function() {
    6218                 var inst = this.instance;
    6219                 var d, r, s, t;
     6317                var inst = this.instance, d, r, s, t;
    62206318
    62216319                if (tinyMCE.isIE) {
     
    62406338
    62416339        getBookmark : function(simple) {
    6242                 var inst = this.instance;
    6243                 var rng = this.getRng();
    6244                 var doc = inst.getDoc(), b = inst.getBody();
     6340                var inst = this.instance, rng = this.getRng(), doc = inst.getDoc(), b = inst.getBody();
     6341                var trng, sx, sy, xx = -999999999, vp = inst.getViewPort();
    62456342                var sp, le, s, e, nl, i, si, ei, w;
    6246                 var trng, sx, sy, xx = -999999999, vp = inst.getViewPort();
    62476343
    62486344                sx = vp.left;
    62496345                sy = vp.top;
    62506346
    6251                 if (tinyMCE.isSafari || tinyMCE.isOpera || simple)
     6347                if (simple)
    62526348                        return {rng : rng, scrollX : sx, scrollY : sy};
    62536349
    6254                 if (tinyMCE.isIE) {
     6350                if (tinyMCE.isRealIE) {
    62556351                        if (rng.item) {
    62566352                                e = rng.item(0);
     
    62916387                                };
    62926388                        }
    6293                 }
    6294 
    6295                 if (tinyMCE.isGecko) {
     6389                } else {
    62966390                        s = this.getSel();
    62976391                        e = this.getFocusElement();
     
    63506444
    63516445        moveToBookmark : function(bookmark) {
    6352                 var inst = this.instance;
    6353                 var rng, nl, i, ex, b = inst.getBody(), sd;
    6354                 var doc = inst.getDoc();
    6355                 var win = inst.getWin();
    6356                 var sel = this.getSel();
     6446                var inst = this.instance, rng, nl, i, ex, b = inst.getBody(), sd;
     6447                var doc = inst.getDoc(), win = inst.getWin(), sel = this.getSel();
    63576448
    63586449                if (!bookmark)
    63596450                        return false;
    63606451
    6361                 if (tinyMCE.isSafari) {
     6452                if (tinyMCE.isSafari && bookmark.rng) {
    63626453                        sel.setBaseAndExtent(bookmark.rng.startContainer, bookmark.rng.startOffset, bookmark.rng.endContainer, bookmark.rng.endOffset);
    63636454                        return true;
     
    64296520                                        sel.removeAllRanges();
    64306521                                        sel.addRange(rng);
    6431                                         win.focus();
     6522
     6523                                        if (!tinyMCE.isOpera)
     6524                                                win.focus();
    64326525                                } catch (ex) {
    64336526                                        // Ignore
     
    65506643                        if (select_text_node) {
    65516644                                // Find first textnode in tree
    6552                                 nodes = tinyMCE.getNodeTree(node, new Array(), 3);
     6645                                nodes = tinyMCE.getNodeTree(node, [], 3);
    65536646                                if (nodes.length > 0)
    65546647                                        rng.selectNodeContents(nodes[0]);
     
    67076800function TinyMCE_UndoRedo(inst) {
    67086801        this.instance = inst;
    6709         this.undoLevels = new Array();
     6802        this.undoLevels = [];
    67106803        this.undoIndex = 0;
    67116804        this.typingUndoIndex = -1;
     
    67336826                        //tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content);
    67346827
     6828                        // Is dirty again
     6829                        inst.isNotDirty = false;
     6830
    67356831                        tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst);
    67366832
    67376833                        // Time to compress
    6738                         customUndoLevels = tinyMCE.settings['custom_undo_redo_levels'];
     6834                        customUndoLevels = tinyMCE.settings.custom_undo_redo_levels;
    67396835                        if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) {
    67406836                                for (i=0; i<this.undoLevels.length-1; i++)
     
    68236919                var rootElm = doc.documentElement, blockName = "P", startNode, endNode, startBlock, endBlock;
    68246920                var rngBefore, rngAfter, direct, startNode, startOffset, endNode, endOffset, b = tinyMCE.isOpera ? inst.selection.getBookmark() : null;
    6825                 var paraBefore, paraAfter, startChop, endChop, contents;
     6921                var paraBefore, paraAfter, startChop, endChop, contents, i;
    68266922
    68276923                function isEmpty(para) {
     6924                        var nodes;
     6925
    68286926                        function isEmptyHTML(html) {
    6829                                 return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == "";
     6927                                return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == '';
    68306928                        }
    68316929
     
    68436941
    68446942                        // Check all textnodes
    6845                         var nodes = tinyMCE.getNodeTree(para, new Array(), 3);
    6846                         for (var i=0; i<nodes.length; i++) {
     6943                        nodes = tinyMCE.getNodeTree(para, [], 3);
     6944                        for (i=0; i<nodes.length; i++) {
    68476945                                if (!isEmptyHTML(nodes[i].nodeValue))
    68486946                                        return false;
     
    68826980
    68836981                // If absolute force paragraph generation within
    6884                 if (startBlock && new RegExp('absolute|relative|static', 'gi').test(startBlock.style.position))
     6982                if (startBlock && (startBlock.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(startBlock.style.position)))
    68856983                        startBlock = null;
    68866984
    6887                 if (endBlock && new RegExp('absolute|relative|static', 'gi').test(endBlock.style.position))
     6985                if (endBlock && (endBlock.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(endBlock.style.position)))
    68886986                        endBlock = null;
    68896987
     
    68936991
    68946992                        // Use P instead
    6895                         if (blockName == "TD" || blockName == "TABLE" || (blockName == "DIV" && new RegExp('left|right', 'gi').test(startBlock.style.cssFloat)))
     6993                        if (/(TD|TABLE|TH|CAPTION)/.test(blockName) || (blockName == "DIV" && /left|right/gi.test(startBlock.style.cssFloat)))
    68966994                                blockName = "P";
    68976995                }
     
    70327130                if (contents.firstChild && contents.firstChild.nodeName == blockName) {
    70337131        /*              var nodes = contents.firstChild.childNodes;
    7034                         for (var i=0; i<nodes.length; i++) {
     7132                        for (i=0; i<nodes.length; i++) {
    70357133                                //tinyMCE.debug(nodes[i].nodeName);
    70367134                                if (nodes[i].nodeName != "BODY")
     
    71277225TinyMCE_Layer.prototype = {
    71287226        moveRelativeTo : function(re, p) {
    7129                 var rep = this.getAbsPosition(re);
    7130                 var w = parseInt(re.offsetWidth);
    7131                 var h = parseInt(re.offsetHeight);
    7132                 var e = this.getElement();
    7133                 var ew = parseInt(e.offsetWidth);
    7134                 var eh = parseInt(e.offsetHeight);
    7135                 var x, y;
     7227                var rep = this.getAbsPosition(re), e = this.getElement(), x, y;
     7228                var w = parseInt(re.offsetWidth), h = parseInt(re.offsetHeight);
     7229                var ew = parseInt(e.offsetWidth), eh = parseInt(e.offsetHeight);
    71367230
    71377231                switch (p) {
     
    73437437
    73447438        this.id = id;
    7345         this.items = new Array();
     7439        this.items = [];
    73467440        this.needsUpdate = true;
    73477441};
     
    73677461
    73687462        clear : function() {
    7369                 this.items = new Array();
     7463                this.items = [];
    73707464        },
    73717465
     
    74577551        });
    74587552
    7459 /* file:jscripts/tiny_mce/classes/TinyMCE_Compatibility.class.js */
    7460 
    7461 if (!Function.prototype.call) {
    7462         Function.prototype.call = function() {
    7463                 var a = arguments, s = a[0], i, as = '', r, o;
    7464 
    7465                 for (i=1; i<a.length; i++)
    7466                         as += (i > 1 ? ',' : '') + 'a[' + i + ']';
    7467 
    7468                 o = s._fu;
    7469                 s._fu = this;
    7470                 r = eval('s._fu(' + as + ')');
    7471                 s._fu = o;
    7472 
    7473                 return r;
    7474         };
    7475 };
    7476 
    74777553/* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */
    74787554
    7479 TinyMCE_Engine.prototype.debug = function() {
    7480         var m = "", a, i, l = tinyMCE.log.length;
    7481 
    7482         for (i=0, a = this.debug.arguments; i<a.length; i++) {
    7483                 m += a[i];
    7484 
    7485                 if (i<a.length-1)
    7486                         m += ', ';
     7555tinyMCE.add(TinyMCE_Engine, {
     7556        debug : function() {
     7557                var m = "", a, i, l = tinyMCE.log.length;
     7558
     7559                for (i=0, a = this.debug.arguments; i<a.length; i++) {
     7560                        m += a[i];
     7561
     7562                        if (i<a.length-1)
     7563                                m += ', ';
     7564                }
     7565
     7566                if (l < 1000)
     7567                        tinyMCE.log[l] = "[debug] " + m;
    74877568        }
    74887569
    7489         if (l < 1000)
    7490                 tinyMCE.log[l] = "[debug] " + m;
    7491 };
    7492 
     7570        });
     7571
  • trunk/wp-includes/js/tinymce/tiny_mce_popup.js

    r4506 r5577  
    3232        init : function() {
    3333                var win = window.opener ? window.opener : window.dialogArguments, c;
    34                 var inst;
     34                var inst, re, title, divElm;
    3535
    3636                if (!win)
     
    6262
    6363                // Setup dir
    64                 if (tinyMCELang['lang_dir'])
    65                         document.dir = tinyMCELang['lang_dir'];
     64                if (tinyMCELang.lang_dir)
     65                        document.dir = tinyMCELang.lang_dir;
    6666
    6767                // Setup title
    68                 var re = new RegExp('{|\\\$|}', 'g');
    69                 var title = document.title.replace(re, "");
    70                 if (typeof tinyMCELang[title] != "undefined") {
    71                         var divElm = document.createElement("div");
     68                re = new RegExp('{|\\\$|}', 'g');
     69                title = document.title.replace(re, "");
     70                if (typeof(tinyMCELang[title]) != "undefined") {
     71                        divElm = document.createElement("div");
    7272                        divElm.innerHTML = tinyMCELang[title];
    7373                        document.title = divElm.innerHTML;
    7474
    75                         if (tinyMCE.setWindowTitle != null)
     75                        if (typeof(tinyMCE.setWindowTitle) != 'undefined')
    7676                                tinyMCE.setWindowTitle(window, divElm.innerHTML);
    7777                }
     
    9999                        body.innerHTML = tinyMCE.applyTemplate(body.innerHTML, tinyMCE.windowArgs);
    100100
    101                 dir = tinyMCE.selectedInstance.settings['directionality'];
     101                dir = tinyMCE.selectedInstance.settings.directionality;
    102102                if (dir == "rtl" && document.forms && document.forms.length > 0) {
    103103                        elms = document.forms[0].elements;
     
    112112
    113113                // Execute real onload (Opera fix)
    114                 if (tinyMCEPopup.onLoadEval != "")
     114                if (tinyMCEPopup.onLoadEval !== '')
    115115                        eval(tinyMCEPopup.onLoadEval);
    116116        },
     
    124124
    125125        resizeToInnerSize : function() {
     126                var i, doc, body, oldMargin, wrapper, iframe, nodes, dx, dy;
     127
    126128                // Netscape 7.1 workaround
    127129                if (this.isWindow && tinyMCE.isNS71) {
     
    131133
    132134                if (this.isWindow) {
    133                         var doc = document;
    134                         var body = doc.body;
    135                         var oldMargin, wrapper, iframe, nodes, dx, dy;
     135                        doc = document;
     136                        body = doc.body;
    136137
    137138                        if (body.style.display == 'none')
     
    150151                        // Wrap body elements
    151152                        nodes = doc.body.childNodes;
    152                         for (var i=nodes.length-1; i>=0; i--) {
     153                        for (i=nodes.length-1; i>=0; i--) {
    153154                                if (wrapper.hasChildNodes())
    154155                                        wrapper.insertBefore(nodes[i].cloneNode(true), wrapper.firstChild);
     
    165166                        iframe = document.createElement("iframe");
    166167                        iframe.id = "mcWinIframe";
    167                         iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings['default_document'];
     168                        iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings.default_document;
    168169                        iframe.width = "100%";
    169170                        iframe.height = "100%";
     
    192193                var isMSIE = (navigator.appName == "Microsoft Internet Explorer");
    193194                var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
     195                var elm, width, height, x, y, dx, dy;
    194196
    195197                if (isOpera)
     
    199201                        try { window.resizeTo(10, 10); } catch (e) {}
    200202
    201                         var elm = document.body;
    202                         var width = elm.offsetWidth;
    203                         var height = elm.offsetHeight;
    204                         var dx = (elm.scrollWidth - width) + 4;
    205                         var dy = elm.scrollHeight - height;
     203                        elm = document.body;
     204                        width = elm.offsetWidth;
     205                        height = elm.offsetHeight;
     206                        dx = (elm.scrollWidth - width) + 4;
     207                        dy = elm.scrollHeight - height;
    206208
    207209                        try { window.resizeBy(dx, dy); } catch (e) {}
     
    212214                                window.sizeToContent();
    213215                                window.scrollTo(0, 0);
    214                                 var x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);
    215                                 var y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);
     216                                x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);
     217                                y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);
    216218                                window.moveTo(x, y);
    217219                        }
     
    224226
    225227        restoreSelection : function() {
     228                var inst;
     229
    226230                if (this.storeSelection) {
    227                         var inst = tinyMCE.selectedInstance;
     231                        inst = tinyMCE.selectedInstance;
    228232
    229233                        inst.getWin().focus();
     
    273277
    274278        importClass : function(c) {
     279                var n;
     280
    275281                window[c] = function() {};
    276282
    277                 for (var n in window.opener[c].prototype)
     283                for (n in window.opener[c].prototype)
    278284                        window[c].prototype[n] = window.opener[c].prototype[n];
    279285
  • trunk/wp-includes/script-loader.php

    r5482 r5577  
    3232                $this->add( 'colorpicker', '/wp-includes/js/colorpicker.js', false, '3517' );
    3333               
    34                 $this->add( 'tiny_mce', '/wp-includes/js/tinymce/tiny_mce_gzip.php', false, '20070326' );
     34                $this->add( 'tiny_mce', '/wp-includes/js/tinymce/tiny_mce_gzip.php', false, '20070528' );
    3535                $mce_config = apply_filters('tiny_mce_config_url', '/wp-includes/js/tinymce/tiny_mce_config.php');
    36                 $this->add( 'wp_tiny_mce', $mce_config, array('tiny_mce'), '20070225' );
     36                $this->add( 'wp_tiny_mce', $mce_config, array('tiny_mce'), '20070528' );
    3737               
    3838                $this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.5.1');
Note: See TracChangeset for help on using the changeset viewer.