WordPress.org

Make WordPress Core

Ticket #20055: 20055.1.diff

File 20055.1.diff, 154.0 KB (added by ericlewis, 2 years ago)

As per Nacin's suggestion, remove script_concat_settings(), move logic for compressions and concatenations to the function calls. Still has respect to the globals in case any plugin sets them. Just saw azaozz's comment, this will need to be ammended to use MCE debug mode.

  • wp-includes/js/tinymce/plugins/media/editor_plugin.dev.js

     
     1/** 
     2 * editor_plugin_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function() { 
     12        var rootAttributes = tinymce.explode('id,name,width,height,style,align,class,hspace,vspace,bgcolor,type'), excludedAttrs = tinymce.makeMap(rootAttributes.join(',')), Node = tinymce.html.Node, 
     13                mediaTypes, scriptRegExp, JSON = tinymce.util.JSON, mimeTypes; 
     14 
     15        // Media types supported by this plugin 
     16        mediaTypes = [ 
     17                // Type, clsid:s, mime types, codebase 
     18                ["Flash", "d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"], 
     19                ["ShockWave", "166b1bca-3f9c-11cf-8075-444553540000", "application/x-director", "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"], 
     20                ["WindowsMedia", "6bf52a52-394a-11d3-b153-00c04f79faa6,22d6f312-b0f6-11d0-94ab-0080c74c7e95,05589fa1-c356-11ce-bf01-00aa0055595a", "application/x-mplayer2", "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"], 
     21                ["QuickTime", "02bf25d5-8c17-4b23-bc80-d3488abddc6b", "video/quicktime", "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"], 
     22                ["RealMedia", "cfcdaa03-8be4-11cf-b84b-0020afbbccfa", "audio/x-pn-realaudio-plugin", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"], 
     23                ["Java", "8ad9c840-044e-11d1-b3e9-00805f499d93", "application/x-java-applet", "http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"], 
     24                ["Silverlight", "dfeaf541-f3e1-4c24-acac-99c30715084a", "application/x-silverlight-2"], 
     25                ["Iframe"], 
     26                ["Video"], 
     27                ["EmbeddedAudio"], 
     28                ["Audio"] 
     29        ]; 
     30 
     31        function toArray(obj) { 
     32                var undef, out, i; 
     33 
     34                if (obj && !obj.splice) { 
     35                        out = []; 
     36 
     37                        for (i = 0; true; i++) { 
     38                                if (obj[i]) 
     39                                        out[i] = obj[i]; 
     40                                else 
     41                                        break; 
     42                        } 
     43 
     44                        return out; 
     45                } 
     46 
     47                return obj; 
     48        }; 
     49 
     50        tinymce.create('tinymce.plugins.MediaPlugin', { 
     51                init : function(ed, url) { 
     52                        var self = this, lookup = {}, i, y, item, name; 
     53 
     54                        function isMediaImg(node) { 
     55                                return node && node.nodeName === 'IMG' && ed.dom.hasClass(node, 'mceItemMedia'); 
     56                        }; 
     57 
     58                        self.editor = ed; 
     59                        self.url = url; 
     60 
     61                        // Parse media types into a lookup table 
     62                        scriptRegExp = ''; 
     63                        for (i = 0; i < mediaTypes.length; i++) { 
     64                                name = mediaTypes[i][0]; 
     65 
     66                                item = { 
     67                                        name : name, 
     68                                        clsids : tinymce.explode(mediaTypes[i][1] || ''), 
     69                                        mimes : tinymce.explode(mediaTypes[i][2] || ''), 
     70                                        codebase : mediaTypes[i][3] 
     71                                }; 
     72 
     73                                for (y = 0; y < item.clsids.length; y++) 
     74                                        lookup['clsid:' + item.clsids[y]] = item; 
     75 
     76                                for (y = 0; y < item.mimes.length; y++) 
     77                                        lookup[item.mimes[y]] = item; 
     78 
     79                                lookup['mceItem' + name] = item; 
     80                                lookup[name.toLowerCase()] = item; 
     81 
     82                                scriptRegExp += (scriptRegExp ? '|' : '') + name; 
     83                        } 
     84 
     85                        // Handle the media_types setting 
     86                        tinymce.each(ed.getParam("media_types", 
     87                                "video=mp4,m4v,ogv,webm;" + 
     88                                "silverlight=xap;" + 
     89                                "flash=swf,flv;" + 
     90                                "shockwave=dcr;" + 
     91                                "quicktime=mov,qt,mpg,mpeg;" + 
     92                                "shockwave=dcr;" + 
     93                                "windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;" + 
     94                                "realmedia=rm,ra,ram;" + 
     95                                "java=jar;" + 
     96                                "audio=mp3,ogg" 
     97                        ).split(';'), function(item) { 
     98                                var i, extensions, type; 
     99 
     100                                item = item.split(/=/); 
     101                                extensions = tinymce.explode(item[1].toLowerCase()); 
     102                                for (i = 0; i < extensions.length; i++) { 
     103                                        type = lookup[item[0].toLowerCase()]; 
     104 
     105                                        if (type) 
     106                                                lookup[extensions[i]] = type; 
     107                                } 
     108                        }); 
     109 
     110                        scriptRegExp = new RegExp('write(' + scriptRegExp + ')\\(([^)]+)\\)'); 
     111                        self.lookup = lookup; 
     112 
     113                        ed.onPreInit.add(function() { 
     114                                // Allow video elements 
     115                                ed.schema.addValidElements('object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]'); 
     116 
     117                                // Convert video elements to image placeholder 
     118                                ed.parser.addNodeFilter('object,embed,video,audio,script,iframe', function(nodes) { 
     119                                        var i = nodes.length; 
     120 
     121                                        while (i--) 
     122                                                self.objectToImg(nodes[i]); 
     123                                }); 
     124 
     125                                // Convert image placeholders to video elements 
     126                                ed.serializer.addNodeFilter('img', function(nodes, name, args) { 
     127                                        var i = nodes.length, node; 
     128 
     129                                        while (i--) { 
     130                                                node = nodes[i]; 
     131                                                if ((node.attr('class') || '').indexOf('mceItemMedia') !== -1) 
     132                                                        self.imgToObject(node, args); 
     133                                        } 
     134                                }); 
     135                        }); 
     136 
     137                        ed.onInit.add(function() { 
     138                                // Display "media" instead of "img" in element path 
     139                                if (ed.theme && ed.theme.onResolveName) { 
     140                                        ed.theme.onResolveName.add(function(theme, path_object) { 
     141                                                if (path_object.name === 'img' && ed.dom.hasClass(path_object.node, 'mceItemMedia')) 
     142                                                        path_object.name = 'media'; 
     143                                        }); 
     144                                } 
     145 
     146                                // Add contect menu if it's loaded 
     147                                if (ed && ed.plugins.contextmenu) { 
     148                                        ed.plugins.contextmenu.onContextMenu.add(function(plugin, menu, element) { 
     149                                                if (element.nodeName === 'IMG' && element.className.indexOf('mceItemMedia') !== -1) 
     150                                                        menu.add({title : 'media.edit', icon : 'media', cmd : 'mceMedia'}); 
     151                                        }); 
     152                                } 
     153                        }); 
     154 
     155                        // Register commands 
     156                        ed.addCommand('mceMedia', function() { 
     157                                var data, img; 
     158 
     159                                img = ed.selection.getNode(); 
     160                                if (isMediaImg(img)) { 
     161                                        data = ed.dom.getAttrib(img, 'data-mce-json'); 
     162                                        if (data) { 
     163                                                data = JSON.parse(data); 
     164 
     165                                                // Add some extra properties to the data object 
     166                                                tinymce.each(rootAttributes, function(name) { 
     167                                                        var value = ed.dom.getAttrib(img, name); 
     168 
     169                                                        if (value) 
     170                                                                data[name] = value; 
     171                                                }); 
     172 
     173                                                data.type = self.getType(img.className).name.toLowerCase(); 
     174                                        } 
     175                                } 
     176 
     177                                if (!data) { 
     178                                        data = { 
     179                                                type : 'flash', 
     180                                                video: {sources:[]}, 
     181                                                params: {} 
     182                                        }; 
     183                                } 
     184 
     185                                ed.windowManager.open({ 
     186                                        file : url + '/media.htm', 
     187                                        width : 430 + parseInt(ed.getLang('media.delta_width', 0)), 
     188                                        height : 500 + parseInt(ed.getLang('media.delta_height', 0)), 
     189                                        inline : 1 
     190                                }, { 
     191                                        plugin_url : url, 
     192                                        data : data 
     193                                }); 
     194                        }); 
     195 
     196                        // Register buttons 
     197                        ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'}); 
     198 
     199                        // Update media selection status 
     200                        ed.onNodeChange.add(function(ed, cm, node) { 
     201                                cm.setActive('media', isMediaImg(node)); 
     202                        }); 
     203                }, 
     204 
     205                convertUrl : function(url, force_absolute) { 
     206                        var self = this, editor = self.editor, settings = editor.settings, 
     207                                urlConverter = settings.url_converter, 
     208                                urlConverterScope = settings.url_converter_scope || self; 
     209 
     210                        if (!url) 
     211                                return url; 
     212 
     213                        if (force_absolute) 
     214                                return editor.documentBaseURI.toAbsolute(url); 
     215 
     216                        return urlConverter.call(urlConverterScope, url, 'src', 'object'); 
     217                }, 
     218 
     219                getInfo : function() { 
     220                        return { 
     221                                longname : 'Media', 
     222                                author : 'Moxiecode Systems AB', 
     223                                authorurl : 'http://tinymce.moxiecode.com', 
     224                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media', 
     225                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     226                        }; 
     227                }, 
     228 
     229                /** 
     230                 * Converts the JSON data object to an img node. 
     231                 */ 
     232                dataToImg : function(data, force_absolute) { 
     233                        var self = this, editor = self.editor, baseUri = editor.documentBaseURI, sources, attrs, img, i; 
     234 
     235                        data.params.src = self.convertUrl(data.params.src, force_absolute); 
     236 
     237                        attrs = data.video.attrs; 
     238                        if (attrs) 
     239                                attrs.src = self.convertUrl(attrs.src, force_absolute); 
     240 
     241                        if (attrs) 
     242                                attrs.poster = self.convertUrl(attrs.poster, force_absolute); 
     243 
     244                        sources = toArray(data.video.sources); 
     245                        if (sources) { 
     246                                for (i = 0; i < sources.length; i++) 
     247                                        sources[i].src = self.convertUrl(sources[i].src, force_absolute); 
     248                        } 
     249 
     250                        img = self.editor.dom.create('img', { 
     251                                id : data.id, 
     252                                style : data.style, 
     253                                align : data.align, 
     254                                hspace : data.hspace, 
     255                                vspace : data.vspace, 
     256                                src : self.editor.theme.url + '/img/trans.gif', 
     257                                'class' : 'mceItemMedia mceItem' + self.getType(data.type).name, 
     258                                'data-mce-json' : JSON.serialize(data, "'") 
     259                        }); 
     260 
     261                        img.width = data.width || (data.type == 'audio' ? "300" : "320"); 
     262                        img.height = data.height || (data.type == 'audio' ? "32" : "240"); 
     263 
     264                        return img; 
     265                }, 
     266 
     267                /** 
     268                 * Converts the JSON data object to a HTML string. 
     269                 */ 
     270                dataToHtml : function(data, force_absolute) { 
     271                        return this.editor.serializer.serialize(this.dataToImg(data, force_absolute), {forced_root_block : '', force_absolute : force_absolute}); 
     272                }, 
     273 
     274                /** 
     275                 * Converts the JSON data object to a HTML string. 
     276                 */ 
     277                htmlToData : function(html) { 
     278                        var fragment, img, data; 
     279 
     280                        data = { 
     281                                type : 'flash', 
     282                                video: {sources:[]}, 
     283                                params: {} 
     284                        }; 
     285 
     286                        fragment = this.editor.parser.parse(html); 
     287                        img = fragment.getAll('img')[0]; 
     288 
     289                        if (img) { 
     290                                data = JSON.parse(img.attr('data-mce-json')); 
     291                                data.type = this.getType(img.attr('class')).name.toLowerCase(); 
     292 
     293                                // Add some extra properties to the data object 
     294                                tinymce.each(rootAttributes, function(name) { 
     295                                        var value = img.attr(name); 
     296 
     297                                        if (value) 
     298                                                data[name] = value; 
     299                                }); 
     300                        } 
     301 
     302                        return data; 
     303                }, 
     304 
     305                /** 
     306                 * Get type item by extension, class, clsid or mime type. 
     307                 * 
     308                 * @method getType 
     309                 * @param {String} value Value to get type item by. 
     310                 * @return {Object} Type item object or undefined. 
     311                 */ 
     312                getType : function(value) { 
     313                        var i, values, typeItem; 
     314 
     315                        // Find type by checking the classes 
     316                        values = tinymce.explode(value, ' '); 
     317                        for (i = 0; i < values.length; i++) { 
     318                                typeItem = this.lookup[values[i]]; 
     319 
     320                                if (typeItem) 
     321                                        return typeItem; 
     322                        } 
     323                }, 
     324 
     325                /** 
     326                 * Converts a tinymce.html.Node image element to video/object/embed. 
     327                 */ 
     328                imgToObject : function(node, args) { 
     329                        var self = this, editor = self.editor, video, object, embed, iframe, name, value, data, 
     330                                source, sources, params, param, typeItem, i, item, mp4Source, replacement, 
     331                                posterSrc, style, audio; 
     332 
     333                        // Adds the flash player 
     334                        function addPlayer(video_src, poster_src) { 
     335                                var baseUri, flashVars, flashVarsOutput, params, flashPlayer; 
     336 
     337                                flashPlayer = editor.getParam('flash_video_player_url', self.convertUrl(self.url + '/moxieplayer.swf')); 
     338                                if (flashPlayer) { 
     339                                        baseUri = editor.documentBaseURI; 
     340                                        data.params.src = flashPlayer; 
     341 
     342                                        // Convert the movie url to absolute urls 
     343                                        if (editor.getParam('flash_video_player_absvideourl', true)) { 
     344                                                video_src = baseUri.toAbsolute(video_src || '', true); 
     345                                                poster_src = baseUri.toAbsolute(poster_src || '', true); 
     346                                        } 
     347 
     348                                        // Generate flash vars 
     349                                        flashVarsOutput = ''; 
     350                                        flashVars = editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}); 
     351                                        tinymce.each(flashVars, function(value, name) { 
     352                                                // Replace $url and $poster variables in flashvars value 
     353                                                value = value.replace(/\$url/, video_src || ''); 
     354                                                value = value.replace(/\$poster/, poster_src || ''); 
     355 
     356                                                if (value.length > 0) 
     357                                                        flashVarsOutput += (flashVarsOutput ? '&' : '') + name + '=' + escape(value); 
     358                                        }); 
     359 
     360                                        if (flashVarsOutput.length) 
     361                                                data.params.flashvars = flashVarsOutput; 
     362 
     363                                        params = editor.getParam('flash_video_player_params', { 
     364                                                allowfullscreen: true, 
     365                                                allowscriptaccess: true 
     366                                        }); 
     367 
     368                                        tinymce.each(params, function(value, name) { 
     369                                                data.params[name] = "" + value; 
     370                                        }); 
     371                                } 
     372                        }; 
     373 
     374                        data = node.attr('data-mce-json'); 
     375                        if (!data) 
     376                                return; 
     377 
     378                        data = JSON.parse(data); 
     379                        typeItem = this.getType(node.attr('class')); 
     380 
     381                        style = node.attr('data-mce-style') 
     382                        if (!style) { 
     383                                style = node.attr('style'); 
     384 
     385                                if (style) 
     386                                        style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img')); 
     387                        } 
     388 
     389                        // Handle iframe 
     390                        if (typeItem.name === 'Iframe') { 
     391                                replacement = new Node('iframe', 1); 
     392 
     393                                tinymce.each(rootAttributes, function(name) { 
     394                                        var value = node.attr(name); 
     395 
     396                                        if (name == 'class' && value) 
     397                                                value = value.replace(/mceItem.+ ?/g, ''); 
     398 
     399                                        if (value && value.length > 0) 
     400                                                replacement.attr(name, value); 
     401                                }); 
     402 
     403                                for (name in data.params) 
     404                                        replacement.attr(name, data.params[name]); 
     405 
     406                                replacement.attr({ 
     407                                        style: style, 
     408                                        src: data.params.src 
     409                                }); 
     410 
     411                                node.replace(replacement); 
     412 
     413                                return; 
     414                        } 
     415 
     416                        // Handle scripts 
     417                        if (this.editor.settings.media_use_script) { 
     418                                replacement = new Node('script', 1).attr('type', 'text/javascript'); 
     419 
     420                                value = new Node('#text', 3); 
     421                                value.value = 'write' + typeItem.name + '(' + JSON.serialize(tinymce.extend(data.params, { 
     422                                        width: node.attr('width'), 
     423                                        height: node.attr('height') 
     424                                })) + ');'; 
     425 
     426                                replacement.append(value); 
     427                                node.replace(replacement); 
     428 
     429                                return; 
     430                        } 
     431 
     432                        // Add HTML5 video element 
     433                        if (typeItem.name === 'Video' && data.video.sources[0]) { 
     434                                // Create new object element 
     435                                video = new Node('video', 1).attr(tinymce.extend({ 
     436                                        id : node.attr('id'), 
     437                                        width: node.attr('width'), 
     438                                        height: node.attr('height'), 
     439                                        style : style 
     440                                }, data.video.attrs)); 
     441 
     442                                // Get poster source and use that for flash fallback 
     443                                if (data.video.attrs) 
     444                                        posterSrc = data.video.attrs.poster; 
     445 
     446                                sources = data.video.sources = toArray(data.video.sources); 
     447                                for (i = 0; i < sources.length; i++) { 
     448                                        if (/\.mp4$/.test(sources[i].src)) 
     449                                                mp4Source = sources[i].src; 
     450                                } 
     451 
     452                                if (!sources[0].type) { 
     453                                        video.attr('src', sources[0].src); 
     454                                        sources.splice(0, 1); 
     455                                } 
     456 
     457                                for (i = 0; i < sources.length; i++) { 
     458                                        source = new Node('source', 1).attr(sources[i]); 
     459                                        source.shortEnded = true; 
     460                                        video.append(source); 
     461                                } 
     462 
     463                                // Create flash fallback for video if we have a mp4 source 
     464                                if (mp4Source) { 
     465                                        addPlayer(mp4Source, posterSrc); 
     466                                        typeItem = self.getType('flash'); 
     467                                } else 
     468                                        data.params.src = ''; 
     469                        } 
     470 
     471                        // Add HTML5 audio element 
     472                        if (typeItem.name === 'Audio' && data.video.sources[0]) { 
     473                                // Create new object element 
     474                                audio = new Node('audio', 1).attr(tinymce.extend({ 
     475                                        id : node.attr('id'), 
     476                                        width: node.attr('width'), 
     477                                        height: node.attr('height'), 
     478                                        style : style 
     479                                }, data.video.attrs)); 
     480 
     481                                // Get poster source and use that for flash fallback 
     482                                if (data.video.attrs) 
     483                                        posterSrc = data.video.attrs.poster; 
     484 
     485                                sources = data.video.sources = toArray(data.video.sources); 
     486                                if (!sources[0].type) { 
     487                                        audio.attr('src', sources[0].src); 
     488                                        sources.splice(0, 1); 
     489                                } 
     490 
     491                                for (i = 0; i < sources.length; i++) { 
     492                                        source = new Node('source', 1).attr(sources[i]); 
     493                                        source.shortEnded = true; 
     494                                        audio.append(source); 
     495                                } 
     496 
     497                                data.params.src = ''; 
     498                        } 
     499 
     500                        if (typeItem.name === 'EmbeddedAudio') { 
     501                                embed = new Node('embed', 1); 
     502                                embed.shortEnded = true; 
     503                                embed.attr({ 
     504                                        id: node.attr('id'), 
     505                                        width: node.attr('width'), 
     506                                        height: node.attr('height'), 
     507                                        style : style, 
     508                                        type: node.attr('type') 
     509                                }); 
     510 
     511                                for (name in data.params) 
     512                                        embed.attr(name, data.params[name]); 
     513 
     514                                tinymce.each(rootAttributes, function(name) { 
     515                                        if (data[name] && name != 'type') 
     516                                                embed.attr(name, data[name]); 
     517                                }); 
     518 
     519                                data.params.src = ''; 
     520                        } 
     521 
     522                        // Do we have a params src then we can generate object 
     523                        if (data.params.src) { 
     524                                // Is flv movie add player for it 
     525                                if (/\.flv$/i.test(data.params.src)) 
     526                                        addPlayer(data.params.src, ''); 
     527 
     528                                if (args && args.force_absolute) 
     529                                        data.params.src = editor.documentBaseURI.toAbsolute(data.params.src); 
     530 
     531                                // Create new object element 
     532                                object = new Node('object', 1).attr({ 
     533                                        id : node.attr('id'), 
     534                                        width: node.attr('width'), 
     535                                        height: node.attr('height'), 
     536                                        style : style 
     537                                }); 
     538 
     539                                tinymce.each(rootAttributes, function(name) { 
     540                                        var value = data[name]; 
     541 
     542                                        if (name == 'class' && value) 
     543                                                value = value.replace(/mceItem.+ ?/g, ''); 
     544 
     545                                        if (value && name != 'type') 
     546                                                object.attr(name, value); 
     547                                }); 
     548 
     549                                // Add params 
     550                                for (name in data.params) { 
     551                                        param = new Node('param', 1); 
     552                                        param.shortEnded = true; 
     553                                        value = data.params[name]; 
     554 
     555                                        // Windows media needs to use url instead of src for the media URL 
     556                                        if (name === 'src' && typeItem.name === 'WindowsMedia') 
     557                                                name = 'url'; 
     558 
     559                                        param.attr({name: name, value: value}); 
     560                                        object.append(param); 
     561                                } 
     562 
     563                                // Setup add type and classid if strict is disabled 
     564                                if (this.editor.getParam('media_strict', true)) { 
     565                                        object.attr({ 
     566                                                data: data.params.src, 
     567                                                type: typeItem.mimes[0] 
     568                                        }); 
     569                                } else { 
     570                                        object.attr({ 
     571                                                classid: "clsid:" + typeItem.clsids[0], 
     572                                                codebase: typeItem.codebase 
     573                                        }); 
     574 
     575                                        embed = new Node('embed', 1); 
     576                                        embed.shortEnded = true; 
     577                                        embed.attr({ 
     578                                                id: node.attr('id'), 
     579                                                width: node.attr('width'), 
     580                                                height: node.attr('height'), 
     581                                                style : style, 
     582                                                type: typeItem.mimes[0] 
     583                                        }); 
     584 
     585                                        for (name in data.params) 
     586                                                embed.attr(name, data.params[name]); 
     587 
     588                                        tinymce.each(rootAttributes, function(name) { 
     589                                                if (data[name] && name != 'type') 
     590                                                        embed.attr(name, data[name]); 
     591                                        }); 
     592 
     593                                        object.append(embed); 
     594                                } 
     595 
     596                                // Insert raw HTML 
     597                                if (data.object_html) { 
     598                                        value = new Node('#text', 3); 
     599                                        value.raw = true; 
     600                                        value.value = data.object_html; 
     601                                        object.append(value); 
     602                                } 
     603 
     604                                // Append object to video element if it exists 
     605                                if (video) 
     606                                        video.append(object); 
     607                        } 
     608 
     609                        if (video) { 
     610                                // Insert raw HTML 
     611                                if (data.video_html) { 
     612                                        value = new Node('#text', 3); 
     613                                        value.raw = true; 
     614                                        value.value = data.video_html; 
     615                                        video.append(value); 
     616                                } 
     617                        } 
     618 
     619                        if (audio) { 
     620                                // Insert raw HTML 
     621                                if (data.video_html) { 
     622                                        value = new Node('#text', 3); 
     623                                        value.raw = true; 
     624                                        value.value = data.video_html; 
     625                                        audio.append(value); 
     626                                } 
     627                        } 
     628 
     629                        var n = video || audio || object || embed; 
     630                        if (n) 
     631                                node.replace(n); 
     632                        else 
     633                                node.remove(); 
     634                }, 
     635 
     636                /** 
     637                 * Converts a tinymce.html.Node video/object/embed to an img element. 
     638                 * 
     639                 * The video/object/embed will be converted into an image placeholder with a JSON data attribute like this: 
     640                 * <img class="mceItemMedia mceItemFlash" width="100" height="100" data-mce-json="{..}" /> 
     641                 * 
     642                 * The JSON structure will be like this: 
     643                 * {'params':{'flashvars':'something','quality':'high','src':'someurl'}, 'video':{'sources':[{src: 'someurl', type: 'video/mp4'}]}} 
     644                 */ 
     645                objectToImg : function(node) { 
     646                        var object, embed, video, iframe, img, name, id, width, height, style, i, html, 
     647                                param, params, source, sources, data, type, lookup = this.lookup, 
     648                                matches, attrs, urlConverter = this.editor.settings.url_converter, 
     649                                urlConverterScope = this.editor.settings.url_converter_scope, 
     650                                hspace, vspace, align, bgcolor; 
     651 
     652                        function getInnerHTML(node) { 
     653                                return new tinymce.html.Serializer({ 
     654                                        inner: true, 
     655                                        validate: false 
     656                                }).serialize(node); 
     657                        }; 
     658 
     659                        function lookupAttribute(o, attr) { 
     660                                return lookup[(o.attr(attr) || '').toLowerCase()]; 
     661                        } 
     662 
     663                        function lookupExtension(src) { 
     664                                var ext = src.replace(/^.*\.([^.]+)$/, '$1'); 
     665                                return lookup[ext.toLowerCase() || '']; 
     666                        } 
     667 
     668                        // If node isn't in document 
     669                        if (!node.parent) 
     670                                return; 
     671 
     672                        // Handle media scripts 
     673                        if (node.name === 'script') { 
     674                                if (node.firstChild) 
     675                                        matches = scriptRegExp.exec(node.firstChild.value); 
     676 
     677                                if (!matches) 
     678                                        return; 
     679 
     680                                type = matches[1]; 
     681                                data = {video : {}, params : JSON.parse(matches[2])}; 
     682                                width = data.params.width; 
     683                                height = data.params.height; 
     684                        } 
     685 
     686                        // Setup data objects 
     687                        data = data || { 
     688                                video : {}, 
     689                                params : {} 
     690                        }; 
     691 
     692                        // Setup new image object 
     693                        img = new Node('img', 1); 
     694                        img.attr({ 
     695                                src : this.editor.theme.url + '/img/trans.gif' 
     696                        }); 
     697 
     698                        // Video element 
     699                        name = node.name; 
     700                        if (name === 'video' || name == 'audio') { 
     701                                video = node; 
     702                                object = node.getAll('object')[0]; 
     703                                embed = node.getAll('embed')[0]; 
     704                                width = video.attr('width'); 
     705                                height = video.attr('height'); 
     706                                id = video.attr('id'); 
     707                                data.video = {attrs : {}, sources : []}; 
     708 
     709                                // Get all video attributes 
     710                                attrs = data.video.attrs; 
     711                                for (name in video.attributes.map) 
     712                                        attrs[name] = video.attributes.map[name]; 
     713 
     714                                source = node.attr('src'); 
     715                                if (source) 
     716                                        data.video.sources.push({src : urlConverter.call(urlConverterScope, source, 'src', node.name)}); 
     717 
     718                                // Get all sources 
     719                                sources = video.getAll("source"); 
     720                                for (i = 0; i < sources.length; i++) { 
     721                                        source = sources[i].remove(); 
     722 
     723                                        data.video.sources.push({ 
     724                                                src: urlConverter.call(urlConverterScope, source.attr('src'), 'src', 'source'), 
     725                                                type: source.attr('type'), 
     726                                                media: source.attr('media') 
     727                                        }); 
     728                                } 
     729 
     730                                // Convert the poster URL 
     731                                if (attrs.poster) 
     732                                        attrs.poster = urlConverter.call(urlConverterScope, attrs.poster, 'poster', node.name); 
     733                        } 
     734 
     735                        // Object element 
     736                        if (node.name === 'object') { 
     737                                object = node; 
     738                                embed = node.getAll('embed')[0]; 
     739                        } 
     740 
     741                        // Embed element 
     742                        if (node.name === 'embed') 
     743                                embed = node; 
     744 
     745                        // Iframe element 
     746                        if (node.name === 'iframe') { 
     747                                iframe = node; 
     748                                type = 'Iframe'; 
     749                        } 
     750 
     751                        if (object) { 
     752                                // Get width/height 
     753                                width = width || object.attr('width'); 
     754                                height = height || object.attr('height'); 
     755                                style = style || object.attr('style'); 
     756                                id = id || object.attr('id'); 
     757                                hspace = hspace || object.attr('hspace'); 
     758                                vspace = vspace || object.attr('vspace'); 
     759                                align = align || object.attr('align'); 
     760                                bgcolor = bgcolor || object.attr('bgcolor'); 
     761                                data.name = object.attr('name'); 
     762 
     763                                // Get all object params 
     764                                params = object.getAll("param"); 
     765                                for (i = 0; i < params.length; i++) { 
     766                                        param = params[i]; 
     767                                        name = param.remove().attr('name'); 
     768 
     769                                        if (!excludedAttrs[name]) 
     770                                                data.params[name] = param.attr('value'); 
     771                                } 
     772 
     773                                data.params.src = data.params.src || object.attr('data'); 
     774                        } 
     775 
     776                        if (embed) { 
     777                                // Get width/height 
     778                                width = width || embed.attr('width'); 
     779                                height = height || embed.attr('height'); 
     780                                style = style || embed.attr('style'); 
     781                                id = id || embed.attr('id'); 
     782                                hspace = hspace || embed.attr('hspace'); 
     783                                vspace = vspace || embed.attr('vspace'); 
     784                                align = align || embed.attr('align'); 
     785                                bgcolor = bgcolor || embed.attr('bgcolor'); 
     786 
     787                                // Get all embed attributes 
     788                                for (name in embed.attributes.map) { 
     789                                        if (!excludedAttrs[name] && !data.params[name]) 
     790                                                data.params[name] = embed.attributes.map[name]; 
     791                                } 
     792                        } 
     793 
     794                        if (iframe) { 
     795                                // Get width/height 
     796                                width = iframe.attr('width'); 
     797                                height = iframe.attr('height'); 
     798                                style = style || iframe.attr('style'); 
     799                                id = iframe.attr('id'); 
     800                                hspace = iframe.attr('hspace'); 
     801                                vspace = iframe.attr('vspace'); 
     802                                align = iframe.attr('align'); 
     803                                bgcolor = iframe.attr('bgcolor'); 
     804 
     805                                tinymce.each(rootAttributes, function(name) { 
     806                                        img.attr(name, iframe.attr(name)); 
     807                                }); 
     808 
     809                                // Get all iframe attributes 
     810                                for (name in iframe.attributes.map) { 
     811                                        if (!excludedAttrs[name] && !data.params[name]) 
     812                                                data.params[name] = iframe.attributes.map[name]; 
     813                                } 
     814                        } 
     815 
     816                        // Use src not movie 
     817                        if (data.params.movie) { 
     818                                data.params.src = data.params.src || data.params.movie; 
     819                                delete data.params.movie; 
     820                        } 
     821 
     822                        // Convert the URL to relative/absolute depending on configuration 
     823                        if (data.params.src) 
     824                                data.params.src = urlConverter.call(urlConverterScope, data.params.src, 'src', 'object'); 
     825 
     826                        if (video) { 
     827                                if (node.name === 'video') 
     828                                        type = lookup.video.name; 
     829                                else if (node.name === 'audio') 
     830                                        type = lookup.audio.name; 
     831                        } 
     832 
     833                        if (object && !type) 
     834                                type = (lookupAttribute(object, 'clsid') || lookupAttribute(object, 'classid') || lookupAttribute(object, 'type') || {}).name; 
     835 
     836                        if (embed && !type) 
     837                                type = (lookupAttribute(embed, 'type') || lookupExtension(data.params.src) || {}).name; 
     838 
     839                        // for embedded audio we preserve the original specified type 
     840                        if (embed && type == 'EmbeddedAudio') { 
     841                                data.params.type = embed.attr('type'); 
     842                        } 
     843 
     844                        // Replace the video/object/embed element with a placeholder image containing the data 
     845                        node.replace(img); 
     846 
     847                        // Remove embed 
     848                        if (embed) 
     849                                embed.remove(); 
     850 
     851                        // Serialize the inner HTML of the object element 
     852                        if (object) { 
     853                                html = getInnerHTML(object.remove()); 
     854 
     855                                if (html) 
     856                                        data.object_html = html; 
     857                        } 
     858 
     859                        // Serialize the inner HTML of the video element 
     860                        if (video) { 
     861                                html = getInnerHTML(video.remove()); 
     862 
     863                                if (html) 
     864                                        data.video_html = html; 
     865                        } 
     866 
     867                        data.hspace = hspace; 
     868                        data.vspace = vspace; 
     869                        data.align = align; 
     870                        data.bgcolor = bgcolor; 
     871 
     872                        // Set width/height of placeholder 
     873                        img.attr({ 
     874                                id : id, 
     875                                'class' : 'mceItemMedia mceItem' + (type || 'Flash'), 
     876                                style : style, 
     877                                width : width || (node.name == 'audio' ? "300" : "320"), 
     878                                height : height || (node.name == 'audio' ? "32" : "240"), 
     879                                hspace : hspace, 
     880                                vspace : vspace, 
     881                                align : align, 
     882                                bgcolor : bgcolor, 
     883                                "data-mce-json" : JSON.serialize(data, "'") 
     884                        }); 
     885                } 
     886        }); 
     887 
     888        // Register plugin 
     889        tinymce.PluginManager.add('media', tinymce.plugins.MediaPlugin); 
     890})(); 
  • wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.js

     
     1 
    12(function(){tinymce.create("tinymce.plugins.wpEditImage",{init:function(a,c){var d=this,b={};d.url=c;d._createButtons();a.addCommand("WP_EditImage",function(){var i=a.selection.getNode(),g=tinymce.DOM.getViewPort(),h=g.h,e=(720<g.w)?720:g.w,f=a.dom.getAttrib(i,"class");if(f.indexOf("mceItem")!=-1||f.indexOf("wpGallery")!=-1||i.nodeName!="IMG"){return}tb_show("",c+"/editimage.html?ver=321&TB_iframe=true");tinymce.DOM.setStyles("TB_window",{width:(e-50)+"px",height:(h-45)+"px","margin-left":"-"+parseInt(((e-50)/2),10)+"px"});if(!tinymce.isIE6){tinymce.DOM.setStyles("TB_window",{top:"20px",marginTop:"0"})}tinymce.DOM.setStyles("TB_iframeContent",{width:(e-50)+"px",height:(h-75)+"px"});tinymce.DOM.setStyle(["TB_overlay","TB_window","TB_load"],"z-index","999999")});a.onInit.add(function(e){tinymce.dom.Event.add(e.getBody(),"dragstart",function(f){if(!tinymce.isGecko&&f.target.nodeName=="IMG"&&e.dom.getParent(f.target,"dl.wp-caption")){return tinymce.dom.Event.cancel(f)}})});a.onMouseUp.add(function(f,g){if(tinymce.isWebKit||tinymce.isOpera){return}if(b.x&&(g.clientX!=b.x||g.clientY!=b.y)){var h=f.selection.getNode();if("IMG"==h.nodeName){window.setTimeout(function(){var e,i;if(h.width!=b.img_w||h.height!=b.img_h){h.className=h.className.replace(/size-[^ "']+/,"")}if(f.dom.getParent(h,"div.mceTemp")){e=f.dom.getParent(h,"dl.wp-caption");if(e){i=f.dom.getAttrib(h,"width")||h.width;i=parseInt(i,10);f.dom.setStyle(e,"width",10+i);f.execCommand("mceRepaint")}}},100)}}b={}});a.onMouseDown.add(function(f,g){if(g.target&&(g.target.nodeName=="IMG"||(g.target.firstChild&&g.target.firstChild.nodeName=="IMG"))){b={x:g.clientX,y:g.clientY,img_w:g.target.clientWidth,img_h:g.target.clientHeight};if(f.dom.getAttrib(g.target,"class").indexOf("mceItem")==-1){f.plugins.wordpress._showButtons(g.target,"wp_editbtns")}}});a.onKeyPress.add(function(f,j){var k,g,i,h;if(j.keyCode==13){k=f.selection.getNode();g=f.dom.getParent(k,"dl.wp-caption");i=f.dom.getParent(g,"div.mceTemp");if(g&&i){h=f.dom.create("p",{},"&nbsp;");f.dom.insertAfter(h,i);if(h.firstChild){f.selection.select(h.firstChild)}else{f.selection.select(h)}tinymce.dom.Event.cancel(j);return false}}});a.onBeforeSetContent.add(function(e,f){f.content=d._do_shcode(f.content)});a.onPostProcess.add(function(e,f){if(f.get){f.content=d._get_shcode(f.content)}})},_do_shcode:function(a){return a.replace(/(?:<p>)?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?[\s\u00a0]*/g,function(g,d,k){var j,f,e,h,i;d=d.replace(/\\'|\\&#39;|\\&#039;/g,"&#39;").replace(/\\"|\\&quot;/g,"&quot;");k=k.replace(/\\&#39;|\\&#039;/g,"&#39;").replace(/\\&quot;/g,"&quot;");j=d.match(/id=['"]([^'"]+)/i);f=d.match(/align=['"]([^'"]+)/i);e=d.match(/width=['"]([0-9]+)/);h=d.match(/caption=['"]([^'"]+)/i);j=(j&&j[1])?j[1]:"";f=(f&&f[1])?f[1]:"alignnone";e=(e&&e[1])?e[1]:"";h=(h&&h[1])?h[1]:"";if(!e||!h){return k}i=(f=="aligncenter")?"mceTemp mceIEcenter":"mceTemp";return'<div class="'+i+'" draggable><dl id="'+j+'" class="wp-caption '+f+'" style="width: '+(10+parseInt(e))+'px"><dt class="wp-caption-dt">'+k+'</dt><dd class="wp-caption-dd">'+h+"</dd></dl></div>"})},_get_shcode:function(a){return a.replace(/<div class="mceTemp[^"]*">\s*<dl([^>]+)>\s*<dt[^>]+>([\s\S]+?)<\/dt>\s*<dd[^>]+>(.+?)<\/dd>\s*<\/dl>\s*<\/div>\s*/gi,function(g,d,j,h){var i,f,e;i=d.match(/id=['"]([^'"]+)/i);f=d.match(/class=['"]([^'"]+)/i);e=j.match(/width=['"]([0-9]+)/);i=(i&&i[1])?i[1]:"";f=(f&&f[1])?f[1]:"alignnone";e=(e&&e[1])?e[1]:"";if(!e||!h){return j}f=f.match(/align[^ '"]+/)||"alignnone";h=h.replace(/<\S[^<>]*>/gi,"").replace(/'/g,"&#39;").replace(/"/g,"&quot;");return'[caption id="'+i+'" align="'+f+'" width="'+e+'" caption="'+h+'"]'+j+"[/caption]"})},_createButtons:function(){var b=this,a=tinyMCE.activeEditor,d=tinymce.DOM,e,c;d.remove("wp_editbtns");d.add(document.body,"div",{id:"wp_editbtns",style:"display:none;"});e=d.add("wp_editbtns","img",{src:b.url+"/img/image.png",id:"wp_editimgbtn",width:"24",height:"24",title:a.getLang("wpeditimage.edit_img")});tinymce.dom.Event.add(e,"mousedown",function(g){var f=tinyMCE.activeEditor;f.windowManager.bookmark=f.selection.getBookmark("simple");f.execCommand("WP_EditImage")});c=d.add("wp_editbtns","img",{src:b.url+"/img/delete.png",id:"wp_delimgbtn",width:"24",height:"24",title:a.getLang("wpeditimage.del_img")});tinymce.dom.Event.add(c,"mousedown",function(i){var f=tinyMCE.activeEditor,g=f.selection.getNode(),h;if(g.nodeName=="IMG"&&f.dom.getAttrib(g,"class").indexOf("mceItem")==-1){if((h=f.dom.getParent(g,"div"))&&f.dom.hasClass(h,"mceTemp")){f.dom.remove(h)}else{if((h=f.dom.getParent(g,"A"))&&h.childNodes.length==1){f.dom.remove(h)}else{f.dom.remove(g)}}f.execCommand("mceRepaint");return false}})},getInfo:function(){return{longname:"Edit Image",author:"WordPress",authorurl:"http://wordpress.org",infourl:"",version:"1.0"}}});tinymce.PluginManager.add("wpeditimage",tinymce.plugins.wpEditImage)})(); 
     3 No newline at end of file 
  • wp-includes/js/tinymce/plugins/fullscreen/editor_plugin.dev.js

     
     1/** 
     2 * editor_plugin_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function() { 
     12        var DOM = tinymce.DOM; 
     13 
     14        tinymce.create('tinymce.plugins.FullScreenPlugin', { 
     15                init : function(ed, url) { 
     16                        var t = this, s = {}, vp, posCss; 
     17 
     18                        t.editor = ed; 
     19 
     20                        // Register commands 
     21                        ed.addCommand('mceFullScreen', function() { 
     22                                var win, de = DOM.doc.documentElement; 
     23 
     24                                if (ed.getParam('fullscreen_is_enabled')) { 
     25                                        if (ed.getParam('fullscreen_new_window')) 
     26                                                closeFullscreen(); // Call to close in new window 
     27                                        else { 
     28                                                DOM.win.setTimeout(function() { 
     29                                                        tinymce.dom.Event.remove(DOM.win, 'resize', t.resizeFunc); 
     30                                                        tinyMCE.get(ed.getParam('fullscreen_editor_id')).setContent(ed.getContent()); 
     31                                                        tinyMCE.remove(ed); 
     32                                                        DOM.remove('mce_fullscreen_container'); 
     33                                                        de.style.overflow = ed.getParam('fullscreen_html_overflow'); 
     34                                                        DOM.setStyle(DOM.doc.body, 'overflow', ed.getParam('fullscreen_overflow')); 
     35                                                        DOM.win.scrollTo(ed.getParam('fullscreen_scrollx'), ed.getParam('fullscreen_scrolly')); 
     36                                                        tinyMCE.settings = tinyMCE.oldSettings; // Restore old settings 
     37                                                }, 10); 
     38                                        } 
     39 
     40                                        return; 
     41                                } 
     42 
     43                                if (ed.getParam('fullscreen_new_window')) { 
     44                                        win = DOM.win.open(url + "/fullscreen.htm", "mceFullScreenPopup", "fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width=" + screen.availWidth + ",height=" + screen.availHeight); 
     45                                        try { 
     46                                                win.resizeTo(screen.availWidth, screen.availHeight); 
     47                                        } catch (e) { 
     48                                                // Ignore 
     49                                        } 
     50                                } else { 
     51                                        tinyMCE.oldSettings = tinyMCE.settings; // Store old settings 
     52                                        s.fullscreen_overflow = DOM.getStyle(DOM.doc.body, 'overflow', 1) || 'auto'; 
     53                                        s.fullscreen_html_overflow = DOM.getStyle(de, 'overflow', 1); 
     54                                        vp = DOM.getViewPort(); 
     55                                        s.fullscreen_scrollx = vp.x; 
     56                                        s.fullscreen_scrolly = vp.y; 
     57 
     58                                        // Fixes an Opera bug where the scrollbars doesn't reappear 
     59                                        if (tinymce.isOpera && s.fullscreen_overflow == 'visible') 
     60                                                s.fullscreen_overflow = 'auto'; 
     61 
     62                                        // Fixes an IE bug where horizontal scrollbars would appear 
     63                                        if (tinymce.isIE && s.fullscreen_overflow == 'scroll') 
     64                                                s.fullscreen_overflow = 'auto'; 
     65 
     66                                        // Fixes an IE bug where the scrollbars doesn't reappear 
     67                                        if (tinymce.isIE && (s.fullscreen_html_overflow == 'visible' || s.fullscreen_html_overflow == 'scroll')) 
     68                                                s.fullscreen_html_overflow = 'auto';  
     69 
     70                                        if (s.fullscreen_overflow == '0px') 
     71                                                s.fullscreen_overflow = ''; 
     72 
     73                                        DOM.setStyle(DOM.doc.body, 'overflow', 'hidden'); 
     74                                        de.style.overflow = 'hidden'; //Fix for IE6/7 
     75                                        vp = DOM.getViewPort(); 
     76                                        DOM.win.scrollTo(0, 0); 
     77 
     78                                        if (tinymce.isIE) 
     79                                                vp.h -= 1; 
     80 
     81                                        // Use fixed position if it exists 
     82                                        if (tinymce.isIE6) 
     83                                                posCss = 'absolute;top:' + vp.y; 
     84                                        else 
     85                                                posCss = 'fixed;top:0'; 
     86 
     87                                        n = DOM.add(DOM.doc.body, 'div', { 
     88                                                id : 'mce_fullscreen_container',  
     89                                                style : 'position:' + posCss + ';left:0;width:' + vp.w + 'px;height:' + vp.h + 'px;z-index:200000;'}); 
     90                                        DOM.add(n, 'div', {id : 'mce_fullscreen'}); 
     91 
     92                                        tinymce.each(ed.settings, function(v, n) { 
     93                                                s[n] = v; 
     94                                        }); 
     95 
     96                                        s.id = 'mce_fullscreen'; 
     97                                        s.width = n.clientWidth; 
     98                                        s.height = n.clientHeight - 15; 
     99                                        s.fullscreen_is_enabled = true; 
     100                                        s.fullscreen_editor_id = ed.id; 
     101                                        s.theme_advanced_resizing = false; 
     102                                        s.save_onsavecallback = function() { 
     103                                                ed.setContent(tinyMCE.get(s.id).getContent()); 
     104                                                ed.execCommand('mceSave'); 
     105                                        }; 
     106 
     107                                        tinymce.each(ed.getParam('fullscreen_settings'), function(v, k) { 
     108                                                s[k] = v; 
     109                                        }); 
     110 
     111                                        if (s.theme_advanced_toolbar_location === 'external') 
     112                                                s.theme_advanced_toolbar_location = 'top'; 
     113 
     114                                        t.fullscreenEditor = new tinymce.Editor('mce_fullscreen', s); 
     115                                        t.fullscreenEditor.onInit.add(function() { 
     116                                                t.fullscreenEditor.setContent(ed.getContent()); 
     117                                                t.fullscreenEditor.focus(); 
     118                                        }); 
     119 
     120                                        t.fullscreenEditor.render(); 
     121 
     122                                        t.fullscreenElement = new tinymce.dom.Element('mce_fullscreen_container'); 
     123                                        t.fullscreenElement.update(); 
     124                                        //document.body.overflow = 'hidden'; 
     125 
     126                                        t.resizeFunc = tinymce.dom.Event.add(DOM.win, 'resize', function() { 
     127                                                var vp = tinymce.DOM.getViewPort(), fed = t.fullscreenEditor, outerSize, innerSize; 
     128 
     129                                                // Get outer/inner size to get a delta size that can be used to calc the new iframe size 
     130                                                outerSize = fed.dom.getSize(fed.getContainer().firstChild); 
     131                                                innerSize = fed.dom.getSize(fed.getContainer().getElementsByTagName('iframe')[0]); 
     132 
     133                                                fed.theme.resizeTo(vp.w - outerSize.w + innerSize.w, vp.h - outerSize.h + innerSize.h); 
     134                                        }); 
     135                                } 
     136                        }); 
     137 
     138                        // Register buttons 
     139                        ed.addButton('fullscreen', {title : 'fullscreen.desc', cmd : 'mceFullScreen'}); 
     140 
     141                        ed.onNodeChange.add(function(ed, cm) { 
     142                                cm.setActive('fullscreen', ed.getParam('fullscreen_is_enabled')); 
     143                        }); 
     144                }, 
     145 
     146                getInfo : function() { 
     147                        return { 
     148                                longname : 'Fullscreen', 
     149                                author : 'Moxiecode Systems AB', 
     150                                authorurl : 'http://tinymce.moxiecode.com', 
     151                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen', 
     152                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     153                        }; 
     154                } 
     155        }); 
     156 
     157        // Register plugin 
     158        tinymce.PluginManager.add('fullscreen', tinymce.plugins.FullScreenPlugin); 
     159})(); 
     160 No newline at end of file 
  • wp-includes/js/tinymce/plugins/directionality/editor_plugin.dev.js

     
     1/** 
     2 * editor_plugin_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function() { 
     12        tinymce.create('tinymce.plugins.Directionality', { 
     13                init : function(ed, url) { 
     14                        var t = this; 
     15 
     16                        t.editor = ed; 
     17 
     18                        ed.addCommand('mceDirectionLTR', function() { 
     19                                var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); 
     20 
     21                                if (e) { 
     22                                        if (ed.dom.getAttrib(e, "dir") != "ltr") 
     23                                                ed.dom.setAttrib(e, "dir", "ltr"); 
     24                                        else 
     25                                                ed.dom.setAttrib(e, "dir", ""); 
     26                                } 
     27 
     28                                ed.nodeChanged(); 
     29                        }); 
     30 
     31                        ed.addCommand('mceDirectionRTL', function() { 
     32                                var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); 
     33 
     34                                if (e) { 
     35                                        if (ed.dom.getAttrib(e, "dir") != "rtl") 
     36                                                ed.dom.setAttrib(e, "dir", "rtl"); 
     37                                        else 
     38                                                ed.dom.setAttrib(e, "dir", ""); 
     39                                } 
     40 
     41                                ed.nodeChanged(); 
     42                        }); 
     43 
     44                        ed.addButton('ltr', {title : 'directionality.ltr_desc', cmd : 'mceDirectionLTR'}); 
     45                        ed.addButton('rtl', {title : 'directionality.rtl_desc', cmd : 'mceDirectionRTL'}); 
     46 
     47                        ed.onNodeChange.add(t._nodeChange, t); 
     48                }, 
     49 
     50                getInfo : function() { 
     51                        return { 
     52                                longname : 'Directionality', 
     53                                author : 'Moxiecode Systems AB', 
     54                                authorurl : 'http://tinymce.moxiecode.com', 
     55                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality', 
     56                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     57                        }; 
     58                }, 
     59 
     60                // Private methods 
     61 
     62                _nodeChange : function(ed, cm, n) { 
     63                        var dom = ed.dom, dir; 
     64 
     65                        n = dom.getParent(n, dom.isBlock); 
     66                        if (!n) { 
     67                                cm.setDisabled('ltr', 1); 
     68                                cm.setDisabled('rtl', 1); 
     69                                return; 
     70                        } 
     71 
     72                        dir = dom.getAttrib(n, 'dir'); 
     73                        cm.setActive('ltr', dir == "ltr"); 
     74                        cm.setDisabled('ltr', 0); 
     75                        cm.setActive('rtl', dir == "rtl"); 
     76                        cm.setDisabled('rtl', 0); 
     77                } 
     78        }); 
     79 
     80        // Register plugin 
     81        tinymce.PluginManager.add('directionality', tinymce.plugins.Directionality); 
     82})(); 
     83 No newline at end of file 
  • wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.dev.js

     
     1/** 
     2 * editor_plugin_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function() { 
     12        var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM; 
     13 
     14        tinymce.create('tinymce.plugins.SpellcheckerPlugin', { 
     15                getInfo : function() { 
     16                        return { 
     17                                longname : 'Spellchecker', 
     18                                author : 'Moxiecode Systems AB', 
     19                                authorurl : 'http://tinymce.moxiecode.com', 
     20                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker', 
     21                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     22                        }; 
     23                }, 
     24 
     25                init : function(ed, url) { 
     26                        var t = this, cm; 
     27 
     28                        t.url = url; 
     29                        t.editor = ed; 
     30                        t.rpcUrl = ed.getParam("spellchecker_rpc_url", "{backend}"); 
     31 
     32                        if (t.rpcUrl == '{backend}') { 
     33                                // Sniff if the browser supports native spellchecking (Don't know of a better way) 
     34                                if (tinymce.isIE) 
     35                                        return; 
     36 
     37                                t.hasSupport = true; 
     38 
     39                                // Disable the context menu when spellchecking is active 
     40                                ed.onContextMenu.addToTop(function(ed, e) { 
     41                                        if (t.active) 
     42                                                return false; 
     43                                }); 
     44                        } 
     45 
     46                        // Register commands 
     47                        ed.addCommand('mceSpellCheck', function() { 
     48                                if (t.rpcUrl == '{backend}') { 
     49                                        // Enable/disable native spellchecker 
     50                                        t.editor.getBody().spellcheck = t.active = !t.active; 
     51                                        return; 
     52                                } 
     53 
     54                                if (!t.active) { 
     55                                        ed.setProgressState(1); 
     56                                        t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) { 
     57                                                if (r.length > 0) { 
     58                                                        t.active = 1; 
     59                                                        t._markWords(r); 
     60                                                        ed.setProgressState(0); 
     61                                                        ed.nodeChanged(); 
     62                                                } else { 
     63                                                        ed.setProgressState(0); 
     64 
     65                                                        if (ed.getParam('spellchecker_report_no_misspellings', true)) 
     66                                                                ed.windowManager.alert('spellchecker.no_mpell'); 
     67                                                } 
     68                                        }); 
     69                                } else 
     70                                        t._done(); 
     71                        }); 
     72 
     73                        if (ed.settings.content_css !== false) 
     74                                ed.contentCSS.push(url + '/css/content.css'); 
     75 
     76                        ed.onClick.add(t._showMenu, t); 
     77                        ed.onContextMenu.add(t._showMenu, t); 
     78                        ed.onBeforeGetContent.add(function() { 
     79                                if (t.active) 
     80                                        t._removeWords(); 
     81                        }); 
     82 
     83                        ed.onNodeChange.add(function(ed, cm) { 
     84                                cm.setActive('spellchecker', t.active); 
     85                        }); 
     86 
     87                        ed.onSetContent.add(function() { 
     88                                t._done(); 
     89                        }); 
     90 
     91                        ed.onBeforeGetContent.add(function() { 
     92                                t._done(); 
     93                        }); 
     94 
     95                        ed.onBeforeExecCommand.add(function(ed, cmd) { 
     96                                if (cmd == 'mceFullScreen') 
     97                                        t._done(); 
     98                        }); 
     99 
     100                        // Find selected language 
     101                        t.languages = {}; 
     102                        each(ed.getParam('spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv', 'hash'), function(v, k) { 
     103                                if (k.indexOf('+') === 0) { 
     104                                        k = k.substring(1); 
     105                                        t.selectedLang = v; 
     106                                } 
     107 
     108                                t.languages[k] = v; 
     109                        }); 
     110                }, 
     111 
     112                createControl : function(n, cm) { 
     113                        var t = this, c, ed = t.editor; 
     114 
     115                        if (n == 'spellchecker') { 
     116                                // Use basic button if we use the native spellchecker 
     117                                if (t.rpcUrl == '{backend}') { 
     118                                        // Create simple toggle button if we have native support 
     119                                        if (t.hasSupport) 
     120                                                c = cm.createButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); 
     121 
     122                                        return c; 
     123                                } 
     124 
     125                                c = cm.createSplitButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); 
     126 
     127                                c.onRenderMenu.add(function(c, m) { 
     128                                        m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 
     129                                        each(t.languages, function(v, k) { 
     130                                                var o = {icon : 1}, mi; 
     131 
     132                                                o.onclick = function() { 
     133                                                        if (v == t.selectedLang) { 
     134                                                                return; 
     135                                                        } 
     136                                                        mi.setSelected(1); 
     137                                                        t.selectedItem.setSelected(0); 
     138                                                        t.selectedItem = mi; 
     139                                                        t.selectedLang = v; 
     140                                                }; 
     141 
     142                                                o.title = k; 
     143                                                mi = m.add(o); 
     144                                                mi.setSelected(v == t.selectedLang); 
     145 
     146                                                if (v == t.selectedLang) 
     147                                                        t.selectedItem = mi; 
     148                                        }) 
     149                                }); 
     150 
     151                                return c; 
     152                        } 
     153                }, 
     154 
     155                // Internal functions 
     156 
     157                _walk : function(n, f) { 
     158                        var d = this.editor.getDoc(), w; 
     159 
     160                        if (d.createTreeWalker) { 
     161                                w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); 
     162 
     163                                while ((n = w.nextNode()) != null) 
     164                                        f.call(this, n); 
     165                        } else 
     166                                tinymce.walk(n, f, 'childNodes'); 
     167                }, 
     168 
     169                _getSeparators : function() { 
     170                        var re = '', i, str = this.editor.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}§©«®±¶·¸»¼½¾¿×÷¤\u201d\u201c'); 
     171 
     172                        // Build word separator regexp 
     173                        for (i=0; i<str.length; i++) 
     174                                re += '\\' + str.charAt(i); 
     175 
     176                        return re; 
     177                }, 
     178 
     179                _getWords : function() { 
     180                        var ed = this.editor, wl = [], tx = '', lo = {}, rawWords = []; 
     181 
     182                        // Get area text 
     183                        this._walk(ed.getBody(), function(n) { 
     184                                if (n.nodeType == 3) 
     185                                        tx += n.nodeValue + ' '; 
     186                        }); 
     187 
     188                        // split the text up into individual words 
     189                        if (ed.getParam('spellchecker_word_pattern')) { 
     190                                // look for words that match the pattern 
     191                                rawWords = tx.match('(' + ed.getParam('spellchecker_word_pattern') + ')', 'gi'); 
     192                        } else { 
     193                                // Split words by separator 
     194                                tx = tx.replace(new RegExp('([0-9]|[' + this._getSeparators() + '])', 'g'), ' '); 
     195                                tx = tinymce.trim(tx.replace(/(\s+)/g, ' ')); 
     196                                rawWords = tx.split(' '); 
     197                        } 
     198 
     199                        // Build word array and remove duplicates 
     200                        each(rawWords, function(v) { 
     201                                if (!lo[v]) { 
     202                                        wl.push(v); 
     203                                        lo[v] = 1; 
     204                                } 
     205                        }); 
     206 
     207                        return wl; 
     208                }, 
     209 
     210                _removeWords : function(w) { 
     211                        var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark(); 
     212 
     213                        each(dom.select('span').reverse(), function(n) { 
     214                                if (n && (dom.hasClass(n, 'mceItemHiddenSpellWord') || dom.hasClass(n, 'mceItemHidden'))) { 
     215                                        if (!w || dom.decode(n.innerHTML) == w) 
     216                                                dom.remove(n, 1); 
     217                                } 
     218                        }); 
     219 
     220                        se.moveToBookmark(b); 
     221                }, 
     222 
     223                _markWords : function(wl) { 
     224                        var ed = this.editor, dom = ed.dom, doc = ed.getDoc(), se = ed.selection, b = se.getBookmark(), nl = [], 
     225                                w = wl.join('|'), re = this._getSeparators(), rx = new RegExp('(^|[' + re + '])(' + w + ')(?=[' + re + ']|$)', 'g'); 
     226 
     227                        // Collect all text nodes 
     228                        this._walk(ed.getBody(), function(n) { 
     229                                if (n.nodeType == 3) { 
     230                                        nl.push(n); 
     231                                } 
     232                        }); 
     233 
     234                        // Wrap incorrect words in spans 
     235                        each(nl, function(n) { 
     236                                var node, elem, txt, pos, v = n.nodeValue; 
     237 
     238                                if (rx.test(v)) { 
     239                                        // Encode the content 
     240                                        v = dom.encode(v); 
     241                                        // Create container element 
     242                                        elem = dom.create('span', {'class' : 'mceItemHidden'}); 
     243 
     244                                        // Following code fixes IE issues by creating text nodes 
     245                                        // using DOM methods instead of innerHTML. 
     246                                        // Bug #3124: <PRE> elements content is broken after spellchecking. 
     247                                        // Bug #1408: Preceding whitespace characters are removed 
     248                                        // @TODO: I'm not sure that both are still issues on IE9. 
     249                                        if (tinymce.isIE) { 
     250                                                // Enclose mispelled words with temporal tag 
     251                                                v = v.replace(rx, '$1<mcespell>$2</mcespell>'); 
     252                                                // Loop over the content finding mispelled words 
     253                                                while ((pos = v.indexOf('<mcespell>')) != -1) { 
     254                                                        // Add text node for the content before the word 
     255                                                        txt = v.substring(0, pos); 
     256                                                        if (txt.length) { 
     257                                                                node = doc.createTextNode(dom.decode(txt)); 
     258                                                                elem.appendChild(node); 
     259                                                        } 
     260                                                        v = v.substring(pos+10); 
     261                                                        pos = v.indexOf('</mcespell>'); 
     262                                                        txt = v.substring(0, pos); 
     263                                                        v = v.substring(pos+11); 
     264                                                        // Add span element for the word 
     265                                                        elem.appendChild(dom.create('span', {'class' : 'mceItemHiddenSpellWord'}, txt)); 
     266                                                } 
     267                                                // Add text node for the rest of the content 
     268                                                if (v.length) { 
     269                                                        node = doc.createTextNode(dom.decode(v)); 
     270                                                        elem.appendChild(node); 
     271                                                } 
     272                                        } else { 
     273                                                // Other browsers preserve whitespace characters on innerHTML usage 
     274                                                elem.innerHTML = v.replace(rx, '$1<span class="mceItemHiddenSpellWord">$2</span>'); 
     275                                        } 
     276 
     277                                        // Finally, replace the node with the container 
     278                                        dom.replace(elem, n); 
     279                                } 
     280                        }); 
     281 
     282                        se.moveToBookmark(b); 
     283                }, 
     284 
     285                _showMenu : function(ed, e) { 
     286                        var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()), wordSpan = e.target; 
     287 
     288                        e = 0; // Fixes IE memory leak 
     289 
     290                        if (!m) { 
     291                                m = ed.controlManager.createDropMenu('spellcheckermenu', {'class' : 'mceNoIcons'}); 
     292                                t._menu = m; 
     293                        } 
     294 
     295                        if (dom.hasClass(wordSpan, 'mceItemHiddenSpellWord')) { 
     296                                m.removeAll(); 
     297                                m.add({title : 'spellchecker.wait', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 
     298 
     299                                t._sendRPC('getSuggestions', [t.selectedLang, dom.decode(wordSpan.innerHTML)], function(r) { 
     300                                        var ignoreRpc; 
     301 
     302                                        m.removeAll(); 
     303 
     304                                        if (r.length > 0) { 
     305                                                m.add({title : 'spellchecker.sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 
     306                                                each(r, function(v) { 
     307                                                        m.add({title : v, onclick : function() { 
     308                                                                dom.replace(ed.getDoc().createTextNode(v), wordSpan); 
     309                                                                t._checkDone(); 
     310                                                        }}); 
     311                                                }); 
     312 
     313                                                m.addSeparator(); 
     314                                        } else 
     315                                                m.add({title : 'spellchecker.no_sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 
     316 
     317                                        if (ed.getParam('show_ignore_words', true)) { 
     318                                                ignoreRpc = t.editor.getParam("spellchecker_enable_ignore_rpc", ''); 
     319                                                m.add({ 
     320                                                        title : 'spellchecker.ignore_word', 
     321                                                        onclick : function() { 
     322                                                                var word = wordSpan.innerHTML; 
     323 
     324                                                                dom.remove(wordSpan, 1); 
     325                                                                t._checkDone(); 
     326 
     327                                                                // tell the server if we need to 
     328                                                                if (ignoreRpc) { 
     329                                                                        ed.setProgressState(1); 
     330                                                                        t._sendRPC('ignoreWord', [t.selectedLang, word], function(r) { 
     331                                                                                ed.setProgressState(0); 
     332                                                                        }); 
     333                                                                } 
     334                                                        } 
     335                                                }); 
     336 
     337                                                m.add({ 
     338                                                        title : 'spellchecker.ignore_words', 
     339                                                        onclick : function() { 
     340                                                                var word = wordSpan.innerHTML; 
     341 
     342                                                                t._removeWords(dom.decode(word)); 
     343                                                                t._checkDone(); 
     344 
     345                                                                // tell the server if we need to 
     346                                                                if (ignoreRpc) { 
     347                                                                        ed.setProgressState(1); 
     348                                                                        t._sendRPC('ignoreWords', [t.selectedLang, word], function(r) { 
     349                                                                                ed.setProgressState(0); 
     350                                                                        }); 
     351                                                                } 
     352                                                        } 
     353                                                }); 
     354                                        } 
     355 
     356                                        if (t.editor.getParam("spellchecker_enable_learn_rpc")) { 
     357                                                m.add({ 
     358                                                        title : 'spellchecker.learn_word', 
     359                                                        onclick : function() { 
     360                                                                var word = wordSpan.innerHTML; 
     361 
     362                                                                dom.remove(wordSpan, 1); 
     363                                                                t._checkDone(); 
     364 
     365                                                                ed.setProgressState(1); 
     366                                                                t._sendRPC('learnWord', [t.selectedLang, word], function(r) { 
     367                                                                        ed.setProgressState(0); 
     368                                                                }); 
     369                                                        } 
     370                                                }); 
     371                                        } 
     372 
     373                                        m.update(); 
     374                                }); 
     375 
     376                                p1 = DOM.getPos(ed.getContentAreaContainer()); 
     377                                m.settings.offset_x = p1.x; 
     378                                m.settings.offset_y = p1.y; 
     379 
     380                                ed.selection.select(wordSpan); 
     381                                p1 = dom.getPos(wordSpan); 
     382                                m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y); 
     383 
     384                                return tinymce.dom.Event.cancel(e); 
     385                        } else 
     386                                m.hideMenu(); 
     387                }, 
     388 
     389                _checkDone : function() { 
     390                        var t = this, ed = t.editor, dom = ed.dom, o; 
     391 
     392                        each(dom.select('span'), function(n) { 
     393                                if (n && dom.hasClass(n, 'mceItemHiddenSpellWord')) { 
     394                                        o = true; 
     395                                        return false; 
     396                                } 
     397                        }); 
     398 
     399                        if (!o) 
     400                                t._done(); 
     401                }, 
     402 
     403                _done : function() { 
     404                        var t = this, la = t.active; 
     405 
     406                        if (t.active) { 
     407                                t.active = 0; 
     408                                t._removeWords(); 
     409 
     410                                if (t._menu) 
     411                                        t._menu.hideMenu(); 
     412 
     413                                if (la) 
     414                                        t.editor.nodeChanged(); 
     415                        } 
     416                }, 
     417 
     418                _sendRPC : function(m, p, cb) { 
     419                        var t = this; 
     420 
     421                        JSONRequest.sendRPC({ 
     422                                url : t.rpcUrl, 
     423                                method : m, 
     424                                params : p, 
     425                                success : cb, 
     426                                error : function(e, x) { 
     427                                        t.editor.setProgressState(0); 
     428                                        t.editor.windowManager.alert(e.errstr || ('Error response: ' + x.responseText)); 
     429                                } 
     430                        }); 
     431                } 
     432        }); 
     433 
     434        // Register plugin 
     435        tinymce.PluginManager.add('spellchecker', tinymce.plugins.SpellcheckerPlugin); 
     436})(); 
  • wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.dev.js

     
     1/** 
     2 * editor_plugin_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function() { 
     12        var DOM = tinymce.DOM, Element = tinymce.dom.Element, Event = tinymce.dom.Event, each = tinymce.each, is = tinymce.is; 
     13 
     14        tinymce.create('tinymce.plugins.InlinePopups', { 
     15                init : function(ed, url) { 
     16                        // Replace window manager 
     17                        ed.onBeforeRenderUI.add(function() { 
     18                                ed.windowManager = new tinymce.InlineWindowManager(ed); 
     19                                DOM.loadCSS(url + '/skins/' + (ed.settings.inlinepopups_skin || 'clearlooks2') + "/window.css"); 
     20                        }); 
     21                }, 
     22 
     23                getInfo : function() { 
     24                        return { 
     25                                longname : 'InlinePopups', 
     26                                author : 'Moxiecode Systems AB', 
     27                                authorurl : 'http://tinymce.moxiecode.com', 
     28                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups', 
     29                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     30                        }; 
     31                } 
     32        }); 
     33 
     34        tinymce.create('tinymce.InlineWindowManager:tinymce.WindowManager', { 
     35                InlineWindowManager : function(ed) { 
     36                        var t = this; 
     37 
     38                        t.parent(ed); 
     39                        t.zIndex = 300000; 
     40                        t.count = 0; 
     41                        t.windows = {}; 
     42                }, 
     43 
     44                open : function(f, p) { 
     45                        var t = this, id, opt = '', ed = t.editor, dw = 0, dh = 0, vp, po, mdf, clf, we, w, u, parentWindow; 
     46 
     47                        f = f || {}; 
     48                        p = p || {}; 
     49 
     50                        // Run native windows 
     51                        if (!f.inline) 
     52                                return t.parent(f, p); 
     53 
     54                        parentWindow = t._frontWindow(); 
     55                        if (parentWindow && DOM.get(parentWindow.id + '_ifr')) { 
     56                                parentWindow.focussedElement = DOM.get(parentWindow.id + '_ifr').contentWindow.document.activeElement; 
     57                        } 
     58                         
     59                        // Only store selection if the type is a normal window 
     60                        if (!f.type) 
     61                                t.bookmark = ed.selection.getBookmark(1); 
     62 
     63                        id = DOM.uniqueId(); 
     64                        vp = DOM.getViewPort(); 
     65                        f.width = parseInt(f.width || 320); 
     66                        f.height = parseInt(f.height || 240) + (tinymce.isIE ? 8 : 0); 
     67                        f.min_width = parseInt(f.min_width || 150); 
     68                        f.min_height = parseInt(f.min_height || 100); 
     69                        f.max_width = parseInt(f.max_width || 2000); 
     70                        f.max_height = parseInt(f.max_height || 2000); 
     71                        f.left = f.left || Math.round(Math.max(vp.x, vp.x + (vp.w / 2.0) - (f.width / 2.0))); 
     72                        f.top = f.top || Math.round(Math.max(vp.y, vp.y + (vp.h / 2.0) - (f.height / 2.0))); 
     73                        f.movable = f.resizable = true; 
     74                        p.mce_width = f.width; 
     75                        p.mce_height = f.height; 
     76                        p.mce_inline = true; 
     77                        p.mce_window_id = id; 
     78                        p.mce_auto_focus = f.auto_focus; 
     79 
     80                        // Transpose 
     81//                      po = DOM.getPos(ed.getContainer()); 
     82//                      f.left -= po.x; 
     83//                      f.top -= po.y; 
     84 
     85                        t.features = f; 
     86                        t.params = p; 
     87                        t.onOpen.dispatch(t, f, p); 
     88 
     89                        if (f.type) { 
     90                                opt += ' mceModal'; 
     91 
     92                                if (f.type) 
     93                                        opt += ' mce' + f.type.substring(0, 1).toUpperCase() + f.type.substring(1); 
     94 
     95                                f.resizable = false; 
     96                        } 
     97 
     98                        if (f.statusbar) 
     99                                opt += ' mceStatusbar'; 
     100 
     101                        if (f.resizable) 
     102                                opt += ' mceResizable'; 
     103 
     104                        if (f.minimizable) 
     105                                opt += ' mceMinimizable'; 
     106 
     107                        if (f.maximizable) 
     108                                opt += ' mceMaximizable'; 
     109 
     110                        if (f.movable) 
     111                                opt += ' mceMovable'; 
     112 
     113                        // Create DOM objects 
     114                        t._addAll(DOM.doc.body,  
     115                                ['div', {id : id, role : 'dialog', 'aria-labelledby': f.type ? id + '_content' : id + '_title', 'class' : (ed.settings.inlinepopups_skin || 'clearlooks2') + (tinymce.isIE && window.getSelection ? ' ie9' : ''), style : 'width:100px;height:100px'},  
     116                                        ['div', {id : id + '_wrapper', 'class' : 'mceWrapper' + opt}, 
     117                                                ['div', {id : id + '_top', 'class' : 'mceTop'},  
     118                                                        ['div', {'class' : 'mceLeft'}], 
     119                                                        ['div', {'class' : 'mceCenter'}], 
     120                                                        ['div', {'class' : 'mceRight'}], 
     121                                                        ['span', {id : id + '_title'}, f.title || ''] 
     122                                                ], 
     123 
     124                                                ['div', {id : id + '_middle', 'class' : 'mceMiddle'},  
     125                                                        ['div', {id : id + '_left', 'class' : 'mceLeft', tabindex : '0'}], 
     126                                                        ['span', {id : id + '_content'}], 
     127                                                        ['div', {id : id + '_right', 'class' : 'mceRight', tabindex : '0'}] 
     128                                                ], 
     129 
     130                                                ['div', {id : id + '_bottom', 'class' : 'mceBottom'}, 
     131                                                        ['div', {'class' : 'mceLeft'}], 
     132                                                        ['div', {'class' : 'mceCenter'}], 
     133                                                        ['div', {'class' : 'mceRight'}], 
     134                                                        ['span', {id : id + '_status'}, 'Content'] 
     135                                                ], 
     136 
     137                                                ['a', {'class' : 'mceMove', tabindex : '-1', href : 'javascript:;'}], 
     138                                                ['a', {'class' : 'mceMin', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], 
     139                                                ['a', {'class' : 'mceMax', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], 
     140                                                ['a', {'class' : 'mceMed', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], 
     141                                                ['a', {'class' : 'mceClose', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], 
     142                                                ['a', {id : id + '_resize_n', 'class' : 'mceResize mceResizeN', tabindex : '-1', href : 'javascript:;'}], 
     143                                                ['a', {id : id + '_resize_s', 'class' : 'mceResize mceResizeS', tabindex : '-1', href : 'javascript:;'}], 
     144                                                ['a', {id : id + '_resize_w', 'class' : 'mceResize mceResizeW', tabindex : '-1', href : 'javascript:;'}], 
     145                                                ['a', {id : id + '_resize_e', 'class' : 'mceResize mceResizeE', tabindex : '-1', href : 'javascript:;'}], 
     146                                                ['a', {id : id + '_resize_nw', 'class' : 'mceResize mceResizeNW', tabindex : '-1', href : 'javascript:;'}], 
     147                                                ['a', {id : id + '_resize_ne', 'class' : 'mceResize mceResizeNE', tabindex : '-1', href : 'javascript:;'}], 
     148                                                ['a', {id : id + '_resize_sw', 'class' : 'mceResize mceResizeSW', tabindex : '-1', href : 'javascript:;'}], 
     149                                                ['a', {id : id + '_resize_se', 'class' : 'mceResize mceResizeSE', tabindex : '-1', href : 'javascript:;'}] 
     150                                        ] 
     151                                ] 
     152                        ); 
     153 
     154                        DOM.setStyles(id, {top : -10000, left : -10000}); 
     155 
     156                        // Fix gecko rendering bug, where the editors iframe messed with window contents 
     157                        if (tinymce.isGecko) 
     158                                DOM.setStyle(id, 'overflow', 'auto'); 
     159 
     160                        // Measure borders 
     161                        if (!f.type) { 
     162                                dw += DOM.get(id + '_left').clientWidth; 
     163                                dw += DOM.get(id + '_right').clientWidth; 
     164                                dh += DOM.get(id + '_top').clientHeight; 
     165                                dh += DOM.get(id + '_bottom').clientHeight; 
     166                        } 
     167 
     168                        // Resize window 
     169                        DOM.setStyles(id, {top : f.top, left : f.left, width : f.width + dw, height : f.height + dh}); 
     170 
     171                        u = f.url || f.file; 
     172                        if (u) { 
     173                                if (tinymce.relaxedDomain) 
     174                                        u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain; 
     175 
     176                                u = tinymce._addVer(u); 
     177                        } 
     178 
     179                        if (!f.type) { 
     180                                DOM.add(id + '_content', 'iframe', {id : id + '_ifr', src : 'javascript:""', frameBorder : 0, style : 'border:0;width:10px;height:10px'}); 
     181                                DOM.setStyles(id + '_ifr', {width : f.width, height : f.height}); 
     182                                DOM.setAttrib(id + '_ifr', 'src', u); 
     183                        } else { 
     184                                DOM.add(id + '_wrapper', 'a', {id : id + '_ok', 'class' : 'mceButton mceOk', href : 'javascript:;', onmousedown : 'return false;'}, 'Ok'); 
     185 
     186                                if (f.type == 'confirm') 
     187                                        DOM.add(id + '_wrapper', 'a', {'class' : 'mceButton mceCancel', href : 'javascript:;', onmousedown : 'return false;'}, 'Cancel'); 
     188 
     189                                DOM.add(id + '_middle', 'div', {'class' : 'mceIcon'}); 
     190                                DOM.setHTML(id + '_content', f.content.replace('\n', '<br />')); 
     191                                 
     192                                Event.add(id, 'keyup', function(evt) { 
     193                                        var VK_ESCAPE = 27; 
     194                                        if (evt.keyCode === VK_ESCAPE) { 
     195                                                f.button_func(false); 
     196                                                return Event.cancel(evt); 
     197                                        } 
     198                                }); 
     199 
     200                                Event.add(id, 'keydown', function(evt) { 
     201                                        var cancelButton, VK_TAB = 9; 
     202                                        if (evt.keyCode === VK_TAB) { 
     203                                                cancelButton = DOM.select('a.mceCancel', id + '_wrapper')[0]; 
     204                                                if (cancelButton && cancelButton !== evt.target) { 
     205                                                        cancelButton.focus(); 
     206                                                } else { 
     207                                                        DOM.get(id + '_ok').focus(); 
     208                                                } 
     209                                                return Event.cancel(evt); 
     210                                        } 
     211                                }); 
     212                        } 
     213 
     214                        // Register events 
     215                        mdf = Event.add(id, 'mousedown', function(e) { 
     216                                var n = e.target, w, vp; 
     217 
     218                                w = t.windows[id]; 
     219                                t.focus(id); 
     220 
     221                                if (n.nodeName == 'A' || n.nodeName == 'a') { 
     222                                        if (n.className == 'mceClose') { 
     223                                                t.close(null, id); 
     224                                                return Event.cancel(e); 
     225                                        } else if (n.className == 'mceMax') { 
     226                                                w.oldPos = w.element.getXY(); 
     227                                                w.oldSize = w.element.getSize(); 
     228 
     229                                                vp = DOM.getViewPort(); 
     230 
     231                                                // Reduce viewport size to avoid scrollbars 
     232                                                vp.w -= 2; 
     233                                                vp.h -= 2; 
     234 
     235                                                w.element.moveTo(vp.x, vp.y); 
     236                                                w.element.resizeTo(vp.w, vp.h); 
     237                                                DOM.setStyles(id + '_ifr', {width : vp.w - w.deltaWidth, height : vp.h - w.deltaHeight}); 
     238                                                DOM.addClass(id + '_wrapper', 'mceMaximized'); 
     239                                        } else if (n.className == 'mceMed') { 
     240                                                // Reset to old size 
     241                                                w.element.moveTo(w.oldPos.x, w.oldPos.y); 
     242                                                w.element.resizeTo(w.oldSize.w, w.oldSize.h); 
     243                                                w.iframeElement.resizeTo(w.oldSize.w - w.deltaWidth, w.oldSize.h - w.deltaHeight); 
     244 
     245                                                DOM.removeClass(id + '_wrapper', 'mceMaximized'); 
     246                                        } else if (n.className == 'mceMove') 
     247                                                return t._startDrag(id, e, n.className); 
     248                                        else if (DOM.hasClass(n, 'mceResize')) 
     249                                                return t._startDrag(id, e, n.className.substring(13)); 
     250                                } 
     251                        }); 
     252 
     253                        clf = Event.add(id, 'click', function(e) { 
     254                                var n = e.target; 
     255 
     256                                t.focus(id); 
     257 
     258                                if (n.nodeName == 'A' || n.nodeName == 'a') { 
     259                                        switch (n.className) { 
     260                                                case 'mceClose': 
     261                                                        t.close(null, id); 
     262                                                        return Event.cancel(e); 
     263 
     264                                                case 'mceButton mceOk': 
     265                                                case 'mceButton mceCancel': 
     266                                                        f.button_func(n.className == 'mceButton mceOk'); 
     267                                                        return Event.cancel(e); 
     268                                        } 
     269                                } 
     270                        }); 
     271                         
     272                        // Make sure the tab order loops within the dialog. 
     273                        Event.add([id + '_left', id + '_right'], 'focus', function(evt) { 
     274                                var iframe = DOM.get(id + '_ifr'); 
     275                                if (iframe) { 
     276                                        var body = iframe.contentWindow.document.body; 
     277                                        var focusable = DOM.select(':input:enabled,*[tabindex=0]', body); 
     278                                        if (evt.target.id === (id + '_left')) { 
     279                                                focusable[focusable.length - 1].focus(); 
     280                                        } else { 
     281                                                focusable[0].focus(); 
     282                                        } 
     283                                } else { 
     284                                        DOM.get(id + '_ok').focus(); 
     285                                } 
     286                        }); 
     287                         
     288                        // Add window 
     289                        w = t.windows[id] = { 
     290                                id : id, 
     291                                mousedown_func : mdf, 
     292                                click_func : clf, 
     293                                element : new Element(id, {blocker : 1, container : ed.getContainer()}), 
     294                                iframeElement : new Element(id + '_ifr'), 
     295                                features : f, 
     296                                deltaWidth : dw, 
     297                                deltaHeight : dh 
     298                        }; 
     299 
     300                        w.iframeElement.on('focus', function() { 
     301                                t.focus(id); 
     302                        }); 
     303 
     304                        // Setup blocker 
     305                        if (t.count == 0 && t.editor.getParam('dialog_type', 'modal') == 'modal') { 
     306                                DOM.add(DOM.doc.body, 'div', { 
     307                                        id : 'mceModalBlocker', 
     308                                        'class' : (t.editor.settings.inlinepopups_skin || 'clearlooks2') + '_modalBlocker', 
     309                                        style : {zIndex : t.zIndex - 1} 
     310                                }); 
     311 
     312                                DOM.show('mceModalBlocker'); // Reduces flicker in IE 
     313                                DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'true'); 
     314                        } else 
     315                                DOM.setStyle('mceModalBlocker', 'z-index', t.zIndex - 1); 
     316 
     317                        if (tinymce.isIE6 || /Firefox\/2\./.test(navigator.userAgent) || (tinymce.isIE && !DOM.boxModel)) 
     318                                DOM.setStyles('mceModalBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2}); 
     319 
     320                        DOM.setAttrib(id, 'aria-hidden', 'false'); 
     321                        t.focus(id); 
     322                        t._fixIELayout(id, 1); 
     323 
     324                        // Focus ok button 
     325                        if (DOM.get(id + '_ok')) 
     326                                DOM.get(id + '_ok').focus(); 
     327                        t.count++; 
     328 
     329                        return w; 
     330                }, 
     331 
     332                focus : function(id) { 
     333                        var t = this, w; 
     334 
     335                        if (w = t.windows[id]) { 
     336                                w.zIndex = this.zIndex++; 
     337                                w.element.setStyle('zIndex', w.zIndex); 
     338                                w.element.update(); 
     339 
     340                                id = id + '_wrapper'; 
     341                                DOM.removeClass(t.lastId, 'mceFocus'); 
     342                                DOM.addClass(id, 'mceFocus'); 
     343                                t.lastId = id; 
     344                                 
     345                                if (w.focussedElement) { 
     346                                        w.focussedElement.focus(); 
     347                                } else if (DOM.get(id + '_ok')) { 
     348                                        DOM.get(w.id + '_ok').focus(); 
     349                                } else if (DOM.get(w.id + '_ifr')) { 
     350                                        DOM.get(w.id + '_ifr').focus(); 
     351                                } 
     352                        } 
     353                }, 
     354 
     355                _addAll : function(te, ne) { 
     356                        var i, n, t = this, dom = tinymce.DOM; 
     357 
     358                        if (is(ne, 'string')) 
     359                                te.appendChild(dom.doc.createTextNode(ne)); 
     360                        else if (ne.length) { 
     361                                te = te.appendChild(dom.create(ne[0], ne[1])); 
     362 
     363                                for (i=2; i<ne.length; i++) 
     364                                        t._addAll(te, ne[i]); 
     365                        } 
     366                }, 
     367 
     368                _startDrag : function(id, se, ac) { 
     369                        var t = this, mu, mm, d = DOM.doc, eb, w = t.windows[id], we = w.element, sp = we.getXY(), p, sz, ph, cp, vp, sx, sy, sex, sey, dx, dy, dw, dh; 
     370 
     371                        // Get positons and sizes 
     372//                      cp = DOM.getPos(t.editor.getContainer()); 
     373                        cp = {x : 0, y : 0}; 
     374                        vp = DOM.getViewPort(); 
     375 
     376                        // Reduce viewport size to avoid scrollbars while dragging 
     377                        vp.w -= 2; 
     378                        vp.h -= 2; 
     379 
     380                        sex = se.screenX; 
     381                        sey = se.screenY; 
     382                        dx = dy = dw = dh = 0; 
     383 
     384                        // Handle mouse up 
     385                        mu = Event.add(d, 'mouseup', function(e) { 
     386                                Event.remove(d, 'mouseup', mu); 
     387                                Event.remove(d, 'mousemove', mm); 
     388 
     389                                if (eb) 
     390                                        eb.remove(); 
     391 
     392                                we.moveBy(dx, dy); 
     393                                we.resizeBy(dw, dh); 
     394                                sz = we.getSize(); 
     395                                DOM.setStyles(id + '_ifr', {width : sz.w - w.deltaWidth, height : sz.h - w.deltaHeight}); 
     396                                t._fixIELayout(id, 1); 
     397 
     398                                return Event.cancel(e); 
     399                        }); 
     400 
     401                        if (ac != 'Move') 
     402                                startMove(); 
     403 
     404                        function startMove() { 
     405                                if (eb) 
     406                                        return; 
     407 
     408                                t._fixIELayout(id, 0); 
     409 
     410                                // Setup event blocker 
     411                                DOM.add(d.body, 'div', { 
     412                                        id : 'mceEventBlocker', 
     413                                        'class' : 'mceEventBlocker ' + (t.editor.settings.inlinepopups_skin || 'clearlooks2'), 
     414                                        style : {zIndex : t.zIndex + 1} 
     415                                }); 
     416 
     417                                if (tinymce.isIE6 || (tinymce.isIE && !DOM.boxModel)) 
     418                                        DOM.setStyles('mceEventBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2}); 
     419 
     420                                eb = new Element('mceEventBlocker'); 
     421                                eb.update(); 
     422 
     423                                // Setup placeholder 
     424                                p = we.getXY(); 
     425                                sz = we.getSize(); 
     426                                sx = cp.x + p.x - vp.x; 
     427                                sy = cp.y + p.y - vp.y; 
     428                                DOM.add(eb.get(), 'div', {id : 'mcePlaceHolder', 'class' : 'mcePlaceHolder', style : {left : sx, top : sy, width : sz.w, height : sz.h}}); 
     429                                ph = new Element('mcePlaceHolder'); 
     430                        }; 
     431 
     432                        // Handle mouse move/drag 
     433                        mm = Event.add(d, 'mousemove', function(e) { 
     434                                var x, y, v; 
     435 
     436                                startMove(); 
     437 
     438                                x = e.screenX - sex; 
     439                                y = e.screenY - sey; 
     440 
     441                                switch (ac) { 
     442                                        case 'ResizeW': 
     443                                                dx = x; 
     444                                                dw = 0 - x; 
     445                                                break; 
     446 
     447                                        case 'ResizeE': 
     448                                                dw = x; 
     449                                                break; 
     450 
     451                                        case 'ResizeN': 
     452                                        case 'ResizeNW': 
     453                                        case 'ResizeNE': 
     454                                                if (ac == "ResizeNW") { 
     455                                                        dx = x; 
     456                                                        dw = 0 - x; 
     457                                                } else if (ac == "ResizeNE") 
     458                                                        dw = x; 
     459 
     460                                                dy = y; 
     461                                                dh = 0 - y; 
     462                                                break; 
     463 
     464                                        case 'ResizeS': 
     465                                        case 'ResizeSW': 
     466                                        case 'ResizeSE': 
     467                                                if (ac == "ResizeSW") { 
     468                                                        dx = x; 
     469                                                        dw = 0 - x; 
     470                                                } else if (ac == "ResizeSE") 
     471                                                        dw = x; 
     472 
     473                                                dh = y; 
     474                                                break; 
     475 
     476                                        case 'mceMove': 
     477                                                dx = x; 
     478                                                dy = y; 
     479                                                break; 
     480                                } 
     481 
     482                                // Boundary check 
     483                                if (dw < (v = w.features.min_width - sz.w)) { 
     484                                        if (dx !== 0) 
     485                                                dx += dw - v; 
     486 
     487                                        dw = v; 
     488                                } 
     489         
     490                                if (dh < (v = w.features.min_height - sz.h)) { 
     491                                        if (dy !== 0) 
     492                                                dy += dh - v; 
     493 
     494                                        dh = v; 
     495                                } 
     496 
     497                                dw = Math.min(dw, w.features.max_width - sz.w); 
     498                                dh = Math.min(dh, w.features.max_height - sz.h); 
     499                                dx = Math.max(dx, vp.x - (sx + vp.x)); 
     500                                dy = Math.max(dy, vp.y - (sy + vp.y)); 
     501                                dx = Math.min(dx, (vp.w + vp.x) - (sx + sz.w + vp.x)); 
     502                                dy = Math.min(dy, (vp.h + vp.y) - (sy + sz.h + vp.y)); 
     503 
     504                                // Move if needed 
     505                                if (dx + dy !== 0) { 
     506                                        if (sx + dx < 0) 
     507                                                dx = 0; 
     508         
     509                                        if (sy + dy < 0) 
     510                                                dy = 0; 
     511 
     512                                        ph.moveTo(sx + dx, sy + dy); 
     513                                } 
     514 
     515                                // Resize if needed 
     516                                if (dw + dh !== 0) 
     517                                        ph.resizeTo(sz.w + dw, sz.h + dh); 
     518 
     519                                return Event.cancel(e); 
     520                        }); 
     521 
     522                        return Event.cancel(se); 
     523                }, 
     524 
     525                resizeBy : function(dw, dh, id) { 
     526                        var w = this.windows[id]; 
     527 
     528                        if (w) { 
     529                                w.element.resizeBy(dw, dh); 
     530                                w.iframeElement.resizeBy(dw, dh); 
     531                        } 
     532                }, 
     533 
     534                close : function(win, id) { 
     535                        var t = this, w, d = DOM.doc, fw, id; 
     536 
     537                        id = t._findId(id || win); 
     538 
     539                        // Probably not inline 
     540                        if (!t.windows[id]) { 
     541                                t.parent(win); 
     542                                return; 
     543                        } 
     544 
     545                        t.count--; 
     546 
     547                        if (t.count == 0) { 
     548                                DOM.remove('mceModalBlocker'); 
     549                                DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'false'); 
     550                                t.editor.focus(); 
     551                        } 
     552 
     553                        if (w = t.windows[id]) { 
     554                                t.onClose.dispatch(t); 
     555                                Event.remove(d, 'mousedown', w.mousedownFunc); 
     556                                Event.remove(d, 'click', w.clickFunc); 
     557                                Event.clear(id); 
     558                                Event.clear(id + '_ifr'); 
     559 
     560                                DOM.setAttrib(id + '_ifr', 'src', 'javascript:""'); // Prevent leak 
     561                                w.element.remove(); 
     562                                delete t.windows[id]; 
     563 
     564                                fw = t._frontWindow(); 
     565 
     566                                if (fw) 
     567                                        t.focus(fw.id); 
     568                        } 
     569                }, 
     570                 
     571                // Find front most window 
     572                _frontWindow : function() { 
     573                        var fw, ix = 0; 
     574                        // Find front most window and focus that 
     575                        each (this.windows, function(w) { 
     576                                if (w.zIndex > ix) { 
     577                                        fw = w; 
     578                                        ix = w.zIndex; 
     579                                } 
     580                        }); 
     581                        return fw; 
     582                }, 
     583 
     584                setTitle : function(w, ti) { 
     585                        var e; 
     586 
     587                        w = this._findId(w); 
     588 
     589                        if (e = DOM.get(w + '_title')) 
     590                                e.innerHTML = DOM.encode(ti); 
     591                }, 
     592 
     593                alert : function(txt, cb, s) { 
     594                        var t = this, w; 
     595 
     596                        w = t.open({ 
     597                                title : t, 
     598                                type : 'alert', 
     599                                button_func : function(s) { 
     600                                        if (cb) 
     601                                                cb.call(s || t, s); 
     602 
     603                                        t.close(null, w.id); 
     604                                }, 
     605                                content : DOM.encode(t.editor.getLang(txt, txt)), 
     606                                inline : 1, 
     607                                width : 400, 
     608                                height : 130 
     609                        }); 
     610                }, 
     611 
     612                confirm : function(txt, cb, s) { 
     613                        var t = this, w; 
     614 
     615                        w = t.open({ 
     616                                title : t, 
     617                                type : 'confirm', 
     618                                button_func : function(s) { 
     619                                        if (cb) 
     620                                                cb.call(s || t, s); 
     621 
     622                                        t.close(null, w.id); 
     623                                }, 
     624                                content : DOM.encode(t.editor.getLang(txt, txt)), 
     625                                inline : 1, 
     626                                width : 400, 
     627                                height : 130 
     628                        }); 
     629                }, 
     630 
     631                // Internal functions 
     632 
     633                _findId : function(w) { 
     634                        var t = this; 
     635 
     636                        if (typeof(w) == 'string') 
     637                                return w; 
     638 
     639                        each(t.windows, function(wo) { 
     640                                var ifr = DOM.get(wo.id + '_ifr'); 
     641 
     642                                if (ifr && w == ifr.contentWindow) { 
     643                                        w = wo.id; 
     644                                        return false; 
     645                                } 
     646                        }); 
     647 
     648                        return w; 
     649                }, 
     650 
     651                _fixIELayout : function(id, s) { 
     652                        var w, img; 
     653 
     654                        if (!tinymce.isIE6) 
     655                                return; 
     656 
     657                        // Fixes the bug where hover flickers and does odd things in IE6 
     658                        each(['n','s','w','e','nw','ne','sw','se'], function(v) { 
     659                                var e = DOM.get(id + '_resize_' + v); 
     660 
     661                                DOM.setStyles(e, { 
     662                                        width : s ? e.clientWidth : '', 
     663                                        height : s ? e.clientHeight : '', 
     664                                        cursor : DOM.getStyle(e, 'cursor', 1) 
     665                                }); 
     666 
     667                                DOM.setStyle(id + "_bottom", 'bottom', '-1px'); 
     668 
     669                                e = 0; 
     670                        }); 
     671 
     672                        // Fixes graphics glitch 
     673                        if (w = this.windows[id]) { 
     674                                // Fixes rendering bug after resize 
     675                                w.element.hide(); 
     676                                w.element.show(); 
     677 
     678                                // Forced a repaint of the window 
     679                                //DOM.get(id).style.filter = ''; 
     680 
     681                                // IE has a bug where images used in CSS won't get loaded 
     682                                // sometimes when the cache in the browser is disabled 
     683                                // This fix tries to solve it by loading the images using the image object 
     684                                each(DOM.select('div,a', id), function(e, i) { 
     685                                        if (e.currentStyle.backgroundImage != 'none') { 
     686                                                img = new Image(); 
     687                                                img.src = e.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/, '$1'); 
     688                                        } 
     689                                }); 
     690 
     691                                DOM.get(id).style.filter = ''; 
     692                        } 
     693                } 
     694        }); 
     695 
     696        // Register plugin 
     697        tinymce.PluginManager.add('inlinepopups', tinymce.plugins.InlinePopups); 
     698})(); 
     699 
  • wp-includes/js/tinymce/plugins/tabfocus/editor_plugin.dev.js

     
     1/** 
     2 * editor_plugin_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function() { 
     12        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, explode = tinymce.explode; 
     13 
     14        tinymce.create('tinymce.plugins.TabFocusPlugin', { 
     15                init : function(ed, url) { 
     16                        function tabCancel(ed, e) { 
     17                                if (e.keyCode === 9) 
     18                                        return Event.cancel(e); 
     19                        } 
     20 
     21                        function tabHandler(ed, e) { 
     22                                var x, i, f, el, v; 
     23 
     24                                function find(d) { 
     25                                        el = DOM.select(':input:enabled,*[tabindex]'); 
     26 
     27                                        function canSelectRecursive(e) { 
     28                                                return e.nodeName==="BODY" || (e.type != 'hidden' && 
     29                                                        !(e.style.display == "none") && 
     30                                                        !(e.style.visibility == "hidden") && canSelectRecursive(e.parentNode)); 
     31                                        } 
     32                                        function canSelectInOldIe(el) { 
     33                                                return el.attributes["tabIndex"].specified || el.nodeName == "INPUT" || el.nodeName == "TEXTAREA"; 
     34                                        } 
     35                                        function isOldIe() { 
     36                                                return tinymce.isIE6 || tinymce.isIE7; 
     37                                        } 
     38                                        function canSelect(el) { 
     39                                                return ((!isOldIe() || canSelectInOldIe(el))) && el.getAttribute("tabindex") != '-1' && canSelectRecursive(el); 
     40                                        } 
     41 
     42                                        each(el, function(e, i) { 
     43                                                if (e.id == ed.id) { 
     44                                                        x = i; 
     45                                                        return false; 
     46                                                } 
     47                                        }); 
     48                                        if (d > 0) { 
     49                                                for (i = x + 1; i < el.length; i++) { 
     50                                                        if (canSelect(el[i])) 
     51                                                                return el[i]; 
     52                                                } 
     53                                        } else { 
     54                                                for (i = x - 1; i >= 0; i--) { 
     55                                                        if (canSelect(el[i])) 
     56                                                                return el[i]; 
     57                                                } 
     58                                        } 
     59 
     60                                        return null; 
     61                                } 
     62 
     63                                if (e.keyCode === 9) { 
     64                                        v = explode(ed.getParam('tab_focus', ed.getParam('tabfocus_elements', ':prev,:next'))); 
     65 
     66                                        if (v.length == 1) { 
     67                                                v[1] = v[0]; 
     68                                                v[0] = ':prev'; 
     69                                        } 
     70 
     71                                        // Find element to focus 
     72                                        if (e.shiftKey) { 
     73                                                if (v[0] == ':prev') 
     74                                                        el = find(-1); 
     75                                                else 
     76                                                        el = DOM.get(v[0]); 
     77                                        } else { 
     78                                                if (v[1] == ':next') 
     79                                                        el = find(1); 
     80                                                else 
     81                                                        el = DOM.get(v[1]); 
     82                                        } 
     83 
     84                                        if (el) { 
     85                                                if (el.id && (ed = tinymce.get(el.id || el.name))) 
     86                                                        ed.focus(); 
     87                                                else 
     88                                                        window.setTimeout(function() { 
     89                                                                if (!tinymce.isWebKit) 
     90                                                                        window.focus(); 
     91                                                                el.focus(); 
     92                                                        }, 10); 
     93 
     94                                                return Event.cancel(e); 
     95                                        } 
     96                                } 
     97                        } 
     98 
     99                        ed.onKeyUp.add(tabCancel); 
     100 
     101                        if (tinymce.isGecko) { 
     102                                ed.onKeyPress.add(tabHandler); 
     103                                ed.onKeyDown.add(tabCancel); 
     104                        } else 
     105                                ed.onKeyDown.add(tabHandler); 
     106 
     107                }, 
     108 
     109                getInfo : function() { 
     110                        return { 
     111                                longname : 'Tabfocus', 
     112                                author : 'Moxiecode Systems AB', 
     113                                authorurl : 'http://tinymce.moxiecode.com', 
     114                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus', 
     115                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     116                        }; 
     117                } 
     118        }); 
     119 
     120        // Register plugin 
     121        tinymce.PluginManager.add('tabfocus', tinymce.plugins.TabFocusPlugin); 
     122})(); 
  • wp-includes/js/tinymce/plugins/paste/editor_plugin.dev.js

     
     1/** 
     2 * editor_plugin_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function() { 
     12        var each = tinymce.each, 
     13                defs = { 
     14                        paste_auto_cleanup_on_paste : true, 
     15                        paste_enable_default_filters : true, 
     16                        paste_block_drop : false, 
     17                        paste_retain_style_properties : "none", 
     18                        paste_strip_class_attributes : "mso", 
     19                        paste_remove_spans : false, 
     20                        paste_remove_styles : false, 
     21                        paste_remove_styles_if_webkit : true, 
     22                        paste_convert_middot_lists : true, 
     23                        paste_convert_headers_to_strong : false, 
     24                        paste_dialog_width : "450", 
     25                        paste_dialog_height : "400", 
     26                        paste_text_use_dialog : false, 
     27                        paste_text_sticky : false, 
     28                        paste_text_sticky_default : false, 
     29                        paste_text_notifyalways : false, 
     30                        paste_text_linebreaktype : "combined", 
     31                        paste_text_replacements : [ 
     32                                [/\u2026/g, "..."], 
     33                                [/[\x93\x94\u201c\u201d]/g, '"'], 
     34                                [/[\x60\x91\x92\u2018\u2019]/g, "'"] 
     35                        ] 
     36                }; 
     37 
     38        function getParam(ed, name) { 
     39                return ed.getParam(name, defs[name]); 
     40        } 
     41 
     42        tinymce.create('tinymce.plugins.PastePlugin', { 
     43                init : function(ed, url) { 
     44                        var t = this; 
     45 
     46                        t.editor = ed; 
     47                        t.url = url; 
     48 
     49                        // Setup plugin events 
     50                        t.onPreProcess = new tinymce.util.Dispatcher(t); 
     51                        t.onPostProcess = new tinymce.util.Dispatcher(t); 
     52 
     53                        // Register default handlers 
     54                        t.onPreProcess.add(t._preProcess); 
     55                        t.onPostProcess.add(t._postProcess); 
     56 
     57                        // Register optional preprocess handler 
     58                        t.onPreProcess.add(function(pl, o) { 
     59                                ed.execCallback('paste_preprocess', pl, o); 
     60                        }); 
     61 
     62                        // Register optional postprocess 
     63                        t.onPostProcess.add(function(pl, o) { 
     64                                ed.execCallback('paste_postprocess', pl, o); 
     65                        }); 
     66 
     67                        ed.onKeyDown.addToTop(function(ed, e) { 
     68                                // Block ctrl+v from adding an undo level since the default logic in tinymce.Editor will add that 
     69                                if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45)) 
     70                                        return false; // Stop other listeners 
     71                        }); 
     72 
     73                        // Initialize plain text flag 
     74                        ed.pasteAsPlainText = getParam(ed, 'paste_text_sticky_default'); 
     75 
     76                        // This function executes the process handlers and inserts the contents 
     77                        // force_rich overrides plain text mode set by user, important for pasting with execCommand 
     78                        function process(o, force_rich) { 
     79                                var dom = ed.dom, rng; 
     80 
     81                                // Execute pre process handlers 
     82                                t.onPreProcess.dispatch(t, o); 
     83 
     84                                // Create DOM structure 
     85                                o.node = dom.create('div', 0, o.content); 
     86 
     87                                // If pasting inside the same element and the contents is only one block 
     88                                // remove the block and keep the text since Firefox will copy parts of pre and h1-h6 as a pre element 
     89                                if (tinymce.isGecko) { 
     90                                        rng = ed.selection.getRng(true); 
     91                                        if (rng.startContainer == rng.endContainer && rng.startContainer.nodeType == 3) { 
     92                                                // Is only one block node and it doesn't contain word stuff 
     93                                                if (o.node.childNodes.length === 1 && /^(p|h[1-6]|pre)$/i.test(o.node.firstChild.nodeName) && o.content.indexOf('__MCE_ITEM__') === -1) 
     94                                                        dom.remove(o.node.firstChild, true); 
     95                                        } 
     96                                } 
     97 
     98                                // Execute post process handlers 
     99                                t.onPostProcess.dispatch(t, o); 
     100 
     101                                // Serialize content 
     102                                o.content = ed.serializer.serialize(o.node, {getInner : 1, forced_root_block : ''}); 
     103 
     104                                // Plain text option active? 
     105                                if ((!force_rich) && (ed.pasteAsPlainText)) { 
     106                                        t._insertPlainText(o.content); 
     107 
     108                                        if (!getParam(ed, "paste_text_sticky")) { 
     109                                                ed.pasteAsPlainText = false; 
     110                                                ed.controlManager.setActive("pastetext", false); 
     111                                        } 
     112                                } else { 
     113                                        t._insert(o.content); 
     114                                } 
     115                        } 
     116 
     117                        // Add command for external usage 
     118                        ed.addCommand('mceInsertClipboardContent', function(u, o) { 
     119                                process(o, true); 
     120                        }); 
     121 
     122                        if (!getParam(ed, "paste_text_use_dialog")) { 
     123                                ed.addCommand('mcePasteText', function(u, v) { 
     124                                        var cookie = tinymce.util.Cookie; 
     125 
     126                                        ed.pasteAsPlainText = !ed.pasteAsPlainText; 
     127                                        ed.controlManager.setActive('pastetext', ed.pasteAsPlainText); 
     128 
     129                                        if ((ed.pasteAsPlainText) && (!cookie.get("tinymcePasteText"))) { 
     130                                                if (getParam(ed, "paste_text_sticky")) { 
     131                                                        ed.windowManager.alert(ed.translate('paste.plaintext_mode_sticky')); 
     132                                                } else { 
     133                                                        ed.windowManager.alert(ed.translate('paste.plaintext_mode')); 
     134                                                } 
     135 
     136                                                if (!getParam(ed, "paste_text_notifyalways")) { 
     137                                                        cookie.set("tinymcePasteText", "1", new Date(new Date().getFullYear() + 1, 12, 31)) 
     138                                                } 
     139                                        } 
     140                                }); 
     141                        } 
     142 
     143                        ed.addButton('pastetext', {title: 'paste.paste_text_desc', cmd: 'mcePasteText'}); 
     144                        ed.addButton('selectall', {title: 'paste.selectall_desc', cmd: 'selectall'}); 
     145 
     146                        // This function grabs the contents from the clipboard by adding a 
     147                        // hidden div and placing the caret inside it and after the browser paste 
     148                        // is done it grabs that contents and processes that 
     149                        function grabContent(e) { 
     150                                var n, or, rng, oldRng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY, textContent; 
     151 
     152                                // Check if browser supports direct plaintext access 
     153                                if (e.clipboardData || dom.doc.dataTransfer) { 
     154                                        textContent = (e.clipboardData || dom.doc.dataTransfer).getData('Text'); 
     155 
     156                                        if (ed.pasteAsPlainText) { 
     157                                                e.preventDefault(); 
     158                                                process({content : dom.encode(textContent).replace(/\r?\n/g, '<br />')}); 
     159                                                return; 
     160                                        } 
     161                                } 
     162 
     163                                if (dom.get('_mcePaste')) 
     164                                        return; 
     165 
     166                                // Create container to paste into 
     167                                n = dom.add(body, 'div', {id : '_mcePaste', 'class' : 'mcePaste', 'data-mce-bogus' : '1'}, '\uFEFF\uFEFF'); 
     168 
     169                                // If contentEditable mode we need to find out the position of the closest element 
     170                                if (body != ed.getDoc().body) 
     171                                        posY = dom.getPos(ed.selection.getStart(), body).y; 
     172                                else 
     173                                        posY = body.scrollTop + dom.getViewPort(ed.getWin()).y; 
     174 
     175                                // Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles 
     176                                // If also needs to be in view on IE or the paste would fail 
     177                                dom.setStyles(n, { 
     178                                        position : 'absolute', 
     179                                        left : tinymce.isGecko ? -40 : 0, // Need to move it out of site on Gecko since it will othewise display a ghost resize rect for the div 
     180                                        top : posY - 25, 
     181                                        width : 1, 
     182                                        height : 1, 
     183                                        overflow : 'hidden' 
     184                                }); 
     185 
     186                                if (tinymce.isIE) { 
     187                                        // Store away the old range 
     188                                        oldRng = sel.getRng(); 
     189 
     190                                        // Select the container 
     191                                        rng = dom.doc.body.createTextRange(); 
     192                                        rng.moveToElementText(n); 
     193                                        rng.execCommand('Paste'); 
     194 
     195                                        // Remove container 
     196                                        dom.remove(n); 
     197 
     198                                        // Check if the contents was changed, if it wasn't then clipboard extraction failed probably due 
     199                                        // to IE security settings so we pass the junk though better than nothing right 
     200                                        if (n.innerHTML === '\uFEFF\uFEFF') { 
     201                                                ed.execCommand('mcePasteWord'); 
     202                                                e.preventDefault(); 
     203                                                return; 
     204                                        } 
     205 
     206                                        // Restore the old range and clear the contents before pasting 
     207                                        sel.setRng(oldRng); 
     208                                        sel.setContent(''); 
     209 
     210                                        // For some odd reason we need to detach the the mceInsertContent call from the paste event 
     211                                        // It's like IE has a reference to the parent element that you paste in and the selection gets messed up 
     212                                        // when it tries to restore the selection 
     213                                        setTimeout(function() { 
     214                                                // Process contents 
     215                                                process({content : n.innerHTML}); 
     216                                        }, 0); 
     217 
     218                                        // Block the real paste event 
     219                                        return tinymce.dom.Event.cancel(e); 
     220                                } else { 
     221                                        function block(e) { 
     222                                                e.preventDefault(); 
     223                                        }; 
     224 
     225                                        // Block mousedown and click to prevent selection change 
     226                                        dom.bind(ed.getDoc(), 'mousedown', block); 
     227                                        dom.bind(ed.getDoc(), 'keydown', block); 
     228 
     229                                        or = ed.selection.getRng(); 
     230 
     231                                        // Move select contents inside DIV 
     232                                        n = n.firstChild; 
     233                                        rng = ed.getDoc().createRange(); 
     234                                        rng.setStart(n, 0); 
     235                                        rng.setEnd(n, 2); 
     236                                        sel.setRng(rng); 
     237 
     238                                        // Wait a while and grab the pasted contents 
     239                                        window.setTimeout(function() { 
     240                                                var h = '', nl; 
     241 
     242                                                // Paste divs duplicated in paste divs seems to happen when you paste plain text so lets first look for that broken behavior in WebKit 
     243                                                if (!dom.select('div.mcePaste > div.mcePaste').length) { 
     244                                                        nl = dom.select('div.mcePaste'); 
     245 
     246                                                        // WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string 
     247                                                        each(nl, function(n) { 
     248                                                                var child = n.firstChild; 
     249 
     250                                                                // WebKit inserts a DIV container with lots of odd styles 
     251                                                                if (child && child.nodeName == 'DIV' && child.style.marginTop && child.style.backgroundColor) { 
     252                                                                        dom.remove(child, 1); 
     253                                                                } 
     254 
     255                                                                // Remove apply style spans 
     256                                                                each(dom.select('span.Apple-style-span', n), function(n) { 
     257                                                                        dom.remove(n, 1); 
     258                                                                }); 
     259 
     260                                                                // Remove bogus br elements 
     261                                                                each(dom.select('br[data-mce-bogus]', n), function(n) { 
     262                                                                        dom.remove(n); 
     263                                                                }); 
     264 
     265                                                                // WebKit will make a copy of the DIV for each line of plain text pasted and insert them into the DIV 
     266                                                                if (n.parentNode.className != 'mcePaste') 
     267                                                                        h += n.innerHTML; 
     268                                                        }); 
     269                                                } else { 
     270                                                        // Found WebKit weirdness so force the content into paragraphs this seems to happen when you paste plain text from Nodepad etc 
     271                                                        // So this logic will replace double enter with paragraphs and single enter with br so it kind of looks the same 
     272                                                        h = '<p>' + dom.encode(textContent).replace(/\r?\n\r?\n/g, '</p><p>').replace(/\r?\n/g, '<br />') + '</p>'; 
     273                                                } 
     274 
     275                                                // Remove the nodes 
     276                                                each(dom.select('div.mcePaste'), function(n) { 
     277                                                        dom.remove(n); 
     278                                                }); 
     279 
     280                                                // Restore the old selection 
     281                                                if (or) 
     282                                                        sel.setRng(or); 
     283 
     284                                                process({content : h}); 
     285 
     286                                                // Unblock events ones we got the contents 
     287                                                dom.unbind(ed.getDoc(), 'mousedown', block); 
     288                                                dom.unbind(ed.getDoc(), 'keydown', block); 
     289                                        }, 0); 
     290                                } 
     291                        } 
     292 
     293                        // Check if we should use the new auto process method                    
     294                        if (getParam(ed, "paste_auto_cleanup_on_paste")) { 
     295                                // Is it's Opera or older FF use key handler 
     296                                if (tinymce.isOpera || /Firefox\/2/.test(navigator.userAgent)) { 
     297                                        ed.onKeyDown.addToTop(function(ed, e) { 
     298                                                if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45)) 
     299                                                        grabContent(e); 
     300                                        }); 
     301                                } else { 
     302                                        // Grab contents on paste event on Gecko and WebKit 
     303                                        ed.onPaste.addToTop(function(ed, e) { 
     304                                                return grabContent(e); 
     305                                        }); 
     306                                } 
     307                        } 
     308 
     309                        ed.onInit.add(function() { 
     310                                ed.controlManager.setActive("pastetext", ed.pasteAsPlainText); 
     311 
     312                                // Block all drag/drop events 
     313                                if (getParam(ed, "paste_block_drop")) { 
     314                                        ed.dom.bind(ed.getBody(), ['dragend', 'dragover', 'draggesture', 'dragdrop', 'drop', 'drag'], function(e) { 
     315                                                e.preventDefault(); 
     316                                                e.stopPropagation(); 
     317 
     318                                                return false; 
     319                                        }); 
     320                                } 
     321                        }); 
     322 
     323                        // Add legacy support 
     324                        t._legacySupport(); 
     325                }, 
     326 
     327                getInfo : function() { 
     328                        return { 
     329                                longname : 'Paste text/word', 
     330                                author : 'Moxiecode Systems AB', 
     331                                authorurl : 'http://tinymce.moxiecode.com', 
     332                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste', 
     333                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     334                        }; 
     335                }, 
     336 
     337                _preProcess : function(pl, o) { 
     338                        var ed = this.editor, 
     339                                h = o.content, 
     340                                grep = tinymce.grep, 
     341                                explode = tinymce.explode, 
     342                                trim = tinymce.trim, 
     343                                len, stripClass; 
     344 
     345                        //console.log('Before preprocess:' + o.content); 
     346 
     347                        function process(items) { 
     348                                each(items, function(v) { 
     349                                        // Remove or replace 
     350                                        if (v.constructor == RegExp) 
     351                                                h = h.replace(v, ''); 
     352                                        else 
     353                                                h = h.replace(v[0], v[1]); 
     354                                }); 
     355                        } 
     356                         
     357                        if (ed.settings.paste_enable_default_filters == false) { 
     358                                return; 
     359                        } 
     360 
     361                        // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser 
     362                        if (tinymce.isIE && document.documentMode >= 9) { 
     363                                // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser 
     364                                process([[/(?:<br>&nbsp;[\s\r\n]+|<br>)*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:<br>&nbsp;[\s\r\n]+|<br>)*/g, '$1']]); 
     365 
     366                                // IE9 also adds an extra BR element for each soft-linefeed and it also adds a BR for each word wrap break 
     367                                process([ 
     368                                        [/<br><br>/g, '<BR><BR>'], // Replace multiple BR elements with uppercase BR to keep them intact 
     369                                        [/<br>/g, ' '], // Replace single br elements with space since they are word wrap BR:s 
     370                                        [/<BR><BR>/g, '<br>'] // Replace back the double brs but into a single BR 
     371                                ]); 
     372                        } 
     373 
     374                        // Detect Word content and process it more aggressive 
     375                        if (/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(h) || o.wordContent) { 
     376                                o.wordContent = true;                   // Mark the pasted contents as word specific content 
     377                                //console.log('Word contents detected.'); 
     378 
     379                                // Process away some basic content 
     380                                process([ 
     381                                        /^\s*(&nbsp;)+/gi,                              // &nbsp; entities at the start of contents 
     382                                        /(&nbsp;|<br[^>]*>)+\s*$/gi             // &nbsp; entities at the end of contents 
     383                                ]); 
     384 
     385                                if (getParam(ed, "paste_convert_headers_to_strong")) { 
     386                                        h = h.replace(/<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "<p><strong>$1</strong></p>"); 
     387                                } 
     388 
     389                                if (getParam(ed, "paste_convert_middot_lists")) { 
     390                                        process([ 
     391                                                [/<!--\[if !supportLists\]-->/gi, '$&__MCE_ITEM__'],                                    // Convert supportLists to a list item marker 
     392                                                [/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi, '$1__MCE_ITEM__'],             // Convert mso-list and symbol spans to item markers 
     393                                                [/(<p[^>]+(?:MsoListParagraph)[^>]+>)/gi, '$1__MCE_ITEM__']                             // Convert mso-list and symbol paragraphs to item markers (FF) 
     394                                        ]); 
     395                                } 
     396 
     397                                process([ 
     398                                        // Word comments like conditional comments etc 
     399                                        /<!--[\s\S]+?-->/gi, 
     400 
     401                                        // Remove comments, scripts (e.g., msoShowComment), XML tag, VML content, MS Office namespaced tags, and a few other tags 
     402                                        /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, 
     403 
     404                                        // Convert <s> into <strike> for line-though 
     405                                        [/<(\/?)s>/gi, "<$1strike>"], 
     406 
     407                                        // Replace nsbp entites to char since it's easier to handle 
     408                                        [/&nbsp;/gi, "\u00a0"] 
     409                                ]); 
     410 
     411                                // Remove bad attributes, with or without quotes, ensuring that attribute text is really inside a tag. 
     412                                // If JavaScript had a RegExp look-behind, we could have integrated this with the last process() array and got rid of the loop. But alas, it does not, so we cannot. 
     413                                do { 
     414                                        len = h.length; 
     415                                        h = h.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi, "$1"); 
     416                                } while (len != h.length); 
     417 
     418                                // Remove all spans if no styles is to be retained 
     419                                if (getParam(ed, "paste_retain_style_properties").replace(/^none$/i, "").length == 0) { 
     420                                        h = h.replace(/<\/?span[^>]*>/gi, ""); 
     421                                } else { 
     422                                        // We're keeping styles, so at least clean them up. 
     423                                        // CSS Reference: http://msdn.microsoft.com/en-us/library/aa155477.aspx 
     424 
     425                                        process([ 
     426                                                // Convert <span style="mso-spacerun:yes">___</span> to string of alternating breaking/non-breaking spaces of same length 
     427                                                [/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi, 
     428                                                        function(str, spaces) { 
     429                                                                return (spaces.length > 0)? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : ""; 
     430                                                        } 
     431                                                ], 
     432 
     433                                                // Examine all styles: delete junk, transform some, and keep the rest 
     434                                                [/(<[a-z][^>]*)\sstyle="([^"]*)"/gi, 
     435                                                        function(str, tag, style) { 
     436                                                                var n = [], 
     437                                                                        i = 0, 
     438                                                                        s = explode(trim(style).replace(/&quot;/gi, "'"), ";"); 
     439 
     440                                                                // Examine each style definition within the tag's style attribute 
     441                                                                each(s, function(v) { 
     442                                                                        var name, value, 
     443                                                                                parts = explode(v, ":"); 
     444 
     445                                                                        function ensureUnits(v) { 
     446                                                                                return v + ((v !== "0") && (/\d$/.test(v)))? "px" : ""; 
     447                                                                        } 
     448 
     449                                                                        if (parts.length == 2) { 
     450                                                                                name = parts[0].toLowerCase(); 
     451                                                                                value = parts[1].toLowerCase(); 
     452 
     453                                                                                // Translate certain MS Office styles into their CSS equivalents 
     454                                                                                switch (name) { 
     455                                                                                        case "mso-padding-alt": 
     456                                                                                        case "mso-padding-top-alt": 
     457                                                                                        case "mso-padding-right-alt": 
     458                                                                                        case "mso-padding-bottom-alt": 
     459                                                                                        case "mso-padding-left-alt": 
     460                                                                                        case "mso-margin-alt": 
     461                                                                                        case "mso-margin-top-alt": 
     462                                                                                        case "mso-margin-right-alt": 
     463                                                                                        case "mso-margin-bottom-alt": 
     464                                                                                        case "mso-margin-left-alt": 
     465                                                                                        case "mso-table-layout-alt": 
     466                                                                                        case "mso-height": 
     467                                                                                        case "mso-width": 
     468                                                                                        case "mso-vertical-align-alt": 
     469                                                                                                n[i++] = name.replace(/^mso-|-alt$/g, "") + ":" + ensureUnits(value); 
     470                                                                                                return; 
     471 
     472                                                                                        case "horiz-align": 
     473                                                                                                n[i++] = "text-align:" + value; 
     474                                                                                                return; 
     475 
     476                                                                                        case "vert-align": 
     477                                                                                                n[i++] = "vertical-align:" + value; 
     478                                                                                                return; 
     479 
     480                                                                                        case "font-color": 
     481                                                                                        case "mso-foreground": 
     482                                                                                                n[i++] = "color:" + value; 
     483                                                                                                return; 
     484 
     485                                                                                        case "mso-background": 
     486                                                                                        case "mso-highlight": 
     487                                                                                                n[i++] = "background:" + value; 
     488                                                                                                return; 
     489 
     490                                                                                        case "mso-default-height": 
     491                                                                                                n[i++] = "min-height:" + ensureUnits(value); 
     492                                                                                                return; 
     493 
     494                                                                                        case "mso-default-width": 
     495                                                                                                n[i++] = "min-width:" + ensureUnits(value); 
     496                                                                                                return; 
     497 
     498                                                                                        case "mso-padding-between-alt": 
     499                                                                                                n[i++] = "border-collapse:separate;border-spacing:" + ensureUnits(value); 
     500                                                                                                return; 
     501 
     502                                                                                        case "text-line-through": 
     503                                                                                                if ((value == "single") || (value == "double")) { 
     504                                                                                                        n[i++] = "text-decoration:line-through"; 
     505                                                                                                } 
     506                                                                                                return; 
     507 
     508                                                                                        case "mso-zero-height": 
     509                                                                                                if (value == "yes") { 
     510                                                                                                        n[i++] = "display:none"; 
     511                                                                                                } 
     512                                                                                                return; 
     513                                                                                } 
     514 
     515                                                                                // Eliminate all MS Office style definitions that have no CSS equivalent by examining the first characters in the name 
     516                                                                                if (/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(name)) { 
     517                                                                                        return; 
     518                                                                                } 
     519 
     520                                                                                // If it reached this point, it must be a valid CSS style 
     521                                                                                n[i++] = name + ":" + parts[1];         // Lower-case name, but keep value case 
     522                                                                        } 
     523                                                                }); 
     524 
     525                                                                // If style attribute contained any valid styles the re-write it; otherwise delete style attribute. 
     526                                                                if (i > 0) { 
     527                                                                        return tag + ' style="' + n.join(';') + '"'; 
     528                                                                } else { 
     529                                                                        return tag; 
     530                                                                } 
     531                                                        } 
     532                                                ] 
     533                                        ]); 
     534                                } 
     535                        } 
     536 
     537                        // Replace headers with <strong> 
     538                        if (getParam(ed, "paste_convert_headers_to_strong")) { 
     539                                process([ 
     540                                        [/<h[1-6][^>]*>/gi, "<p><strong>"], 
     541                                        [/<\/h[1-6][^>]*>/gi, "</strong></p>"] 
     542                                ]); 
     543                        } 
     544 
     545                        process([ 
     546                                // Copy paste from Java like Open Office will produce this junk on FF 
     547                                [/Version:[\d.]+\nStartHTML:\d+\nEndHTML:\d+\nStartFragment:\d+\nEndFragment:\d+/gi, ''] 
     548                        ]); 
     549 
     550                        // Class attribute options are: leave all as-is ("none"), remove all ("all"), or remove only those starting with mso ("mso"). 
     551                        // Note:-  paste_strip_class_attributes: "none", verify_css_classes: true is also a good variation. 
     552                        stripClass = getParam(ed, "paste_strip_class_attributes"); 
     553 
     554                        if (stripClass !== "none") { 
     555                                function removeClasses(match, g1) { 
     556                                                if (stripClass === "all") 
     557                                                        return ''; 
     558 
     559                                                var cls = grep(explode(g1.replace(/^(["'])(.*)\1$/, "$2"), " "), 
     560                                                        function(v) { 
     561                                                                return (/^(?!mso)/i.test(v)); 
     562                                                        } 
     563                                                ); 
     564 
     565                                                return cls.length ? ' class="' + cls.join(" ") + '"' : ''; 
     566                                }; 
     567 
     568                                h = h.replace(/ class="([^"]+)"/gi, removeClasses); 
     569                                h = h.replace(/ class=([\-\w]+)/gi, removeClasses); 
     570                        } 
     571 
     572                        // Remove spans option 
     573                        if (getParam(ed, "paste_remove_spans")) { 
     574                                h = h.replace(/<\/?span[^>]*>/gi, ""); 
     575                        } 
     576 
     577                        //console.log('After preprocess:' + h); 
     578 
     579                        o.content = h; 
     580                }, 
     581 
     582                /** 
     583                 * Various post process items. 
     584                 */ 
     585                _postProcess : function(pl, o) { 
     586                        var t = this, ed = t.editor, dom = ed.dom, styleProps; 
     587 
     588                        if (ed.settings.paste_enable_default_filters == false) { 
     589                                return; 
     590                        } 
     591                         
     592                        if (o.wordContent) { 
     593                                // Remove named anchors or TOC links 
     594                                each(dom.select('a', o.node), function(a) { 
     595                                        if (!a.href || a.href.indexOf('#_Toc') != -1) 
     596                                                dom.remove(a, 1); 
     597                                }); 
     598 
     599                                if (getParam(ed, "paste_convert_middot_lists")) { 
     600                                        t._convertLists(pl, o); 
     601                                } 
     602 
     603                                // Process styles 
     604                                styleProps = getParam(ed, "paste_retain_style_properties"); // retained properties 
     605 
     606                                // Process only if a string was specified and not equal to "all" or "*" 
     607                                if ((tinymce.is(styleProps, "string")) && (styleProps !== "all") && (styleProps !== "*")) { 
     608                                        styleProps = tinymce.explode(styleProps.replace(/^none$/i, "")); 
     609 
     610                                        // Retains some style properties 
     611                                        each(dom.select('*', o.node), function(el) { 
     612                                                var newStyle = {}, npc = 0, i, sp, sv; 
     613 
     614                                                // Store a subset of the existing styles 
     615                                                if (styleProps) { 
     616                                                        for (i = 0; i < styleProps.length; i++) { 
     617                                                                sp = styleProps[i]; 
     618                                                                sv = dom.getStyle(el, sp); 
     619 
     620                                                                if (sv) { 
     621                                                                        newStyle[sp] = sv; 
     622                                                                        npc++; 
     623                                                                } 
     624                                                        } 
     625                                                } 
     626 
     627                                                // Remove all of the existing styles 
     628                                                dom.setAttrib(el, 'style', ''); 
     629 
     630                                                if (styleProps && npc > 0) 
     631                                                        dom.setStyles(el, newStyle); // Add back the stored subset of styles 
     632                                                else // Remove empty span tags that do not have class attributes 
     633                                                        if (el.nodeName == 'SPAN' && !el.className) 
     634                                                                dom.remove(el, true); 
     635                                        }); 
     636                                } 
     637                        } 
     638 
     639                        // Remove all style information or only specifically on WebKit to avoid the style bug on that browser 
     640                        if (getParam(ed, "paste_remove_styles") || (getParam(ed, "paste_remove_styles_if_webkit") && tinymce.isWebKit)) { 
     641                                each(dom.select('*[style]', o.node), function(el) { 
     642                                        el.removeAttribute('style'); 
     643                                        el.removeAttribute('data-mce-style'); 
     644                                }); 
     645                        } else { 
     646                                if (tinymce.isWebKit) { 
     647                                        // We need to compress the styles on WebKit since if you paste <img border="0" /> it will become <img border="0" style="... lots of junk ..." /> 
     648                                        // Removing the mce_style that contains the real value will force the Serializer engine to compress the styles 
     649                                        each(dom.select('*', o.node), function(el) { 
     650                                                el.removeAttribute('data-mce-style'); 
     651                                        }); 
     652                                } 
     653                        } 
     654                }, 
     655 
     656                /** 
     657                 * Converts the most common bullet and number formats in Office into a real semantic UL/LI list. 
     658                 */ 
     659                _convertLists : function(pl, o) { 
     660                        var dom = pl.editor.dom, listElm, li, lastMargin = -1, margin, levels = [], lastType, html; 
     661 
     662                        // Convert middot lists into real semantic lists 
     663                        each(dom.select('p', o.node), function(p) { 
     664                                var sib, val = '', type, html, idx, parents; 
     665 
     666                                // Get text node value at beginning of paragraph 
     667                                for (sib = p.firstChild; sib && sib.nodeType == 3; sib = sib.nextSibling) 
     668                                        val += sib.nodeValue; 
     669 
     670                                val = p.innerHTML.replace(/<\/?\w+[^>]*>/gi, '').replace(/&nbsp;/g, '\u00a0'); 
     671 
     672                                // Detect unordered lists look for bullets 
     673                                if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*\u00a0*/.test(val)) 
     674                                        type = 'ul'; 
     675 
     676                                // Detect ordered lists 1., a. or ixv. 
     677                                if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0+/.test(val)) 
     678                                        type = 'ol'; 
     679 
     680                                // Check if node value matches the list pattern: o&nbsp;&nbsp; 
     681                                if (type) { 
     682                                        margin = parseFloat(p.style.marginLeft || 0); 
     683 
     684                                        if (margin > lastMargin) 
     685                                                levels.push(margin); 
     686 
     687                                        if (!listElm || type != lastType) { 
     688                                                listElm = dom.create(type); 
     689                                                dom.insertAfter(listElm, p); 
     690                                        } else { 
     691                                                // Nested list element 
     692                                                if (margin > lastMargin) { 
     693                                                        listElm = li.appendChild(dom.create(type)); 
     694                                                } else if (margin < lastMargin) { 
     695                                                        // Find parent level based on margin value 
     696                                                        idx = tinymce.inArray(levels, margin); 
     697                                                        parents = dom.getParents(listElm.parentNode, type); 
     698                                                        listElm = parents[parents.length - 1 - idx] || listElm; 
     699                                                } 
     700                                        } 
     701 
     702                                        // Remove middot or number spans if they exists 
     703                                        each(dom.select('span', p), function(span) { 
     704                                                var html = span.innerHTML.replace(/<\/?\w+[^>]*>/gi, ''); 
     705 
     706                                                // Remove span with the middot or the number 
     707                                                if (type == 'ul' && /^__MCE_ITEM__[\u2022\u00b7\u00a7\u00d8o\u25CF]/.test(html)) 
     708                                                        dom.remove(span); 
     709                                                else if (/^__MCE_ITEM__[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(html)) 
     710                                                        dom.remove(span); 
     711                                        }); 
     712 
     713                                        html = p.innerHTML; 
     714 
     715                                        // Remove middot/list items 
     716                                        if (type == 'ul') 
     717                                                html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*(&nbsp;|\u00a0)+\s*/, ''); 
     718                                        else 
     719                                                html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^\s*\w+\.(&nbsp;|\u00a0)+\s*/, ''); 
     720 
     721                                        // Create li and add paragraph data into the new li 
     722                                        li = listElm.appendChild(dom.create('li', 0, html)); 
     723                                        dom.remove(p); 
     724 
     725                                        lastMargin = margin; 
     726                                        lastType = type; 
     727                                } else 
     728                                        listElm = lastMargin = 0; // End list element 
     729                        }); 
     730 
     731                        // Remove any left over makers 
     732                        html = o.node.innerHTML; 
     733                        if (html.indexOf('__MCE_ITEM__') != -1) 
     734                                o.node.innerHTML = html.replace(/__MCE_ITEM__/g, ''); 
     735                }, 
     736 
     737                /** 
     738                 * Inserts the specified contents at the caret position. 
     739                 */ 
     740                _insert : function(h, skip_undo) { 
     741                        var ed = this.editor, r = ed.selection.getRng(); 
     742 
     743                        // First delete the contents seems to work better on WebKit when the selection spans multiple list items or multiple table cells. 
     744                        if (!ed.selection.isCollapsed() && r.startContainer != r.endContainer) 
     745                                ed.getDoc().execCommand('Delete', false, null); 
     746 
     747                        ed.execCommand('mceInsertContent', false, h, {skip_undo : skip_undo}); 
     748                }, 
     749 
     750                /** 
     751                 * Instead of the old plain text method which tried to re-create a paste operation, the 
     752                 * new approach adds a plain text mode toggle switch that changes the behavior of paste. 
     753                 * This function is passed the same input that the regular paste plugin produces. 
     754                 * It performs additional scrubbing and produces (and inserts) the plain text. 
     755                 * This approach leverages all of the great existing functionality in the paste 
     756                 * plugin, and requires minimal changes to add the new functionality. 
     757                 * Speednet - June 2009 
     758                 */ 
     759                _insertPlainText : function(content) { 
     760                        var ed = this.editor, 
     761                                linebr = getParam(ed, "paste_text_linebreaktype"), 
     762                                rl = getParam(ed, "paste_text_replacements"), 
     763                                is = tinymce.is; 
     764 
     765                        function process(items) { 
     766                                each(items, function(v) { 
     767                                        if (v.constructor == RegExp) 
     768                                                content = content.replace(v, ""); 
     769                                        else 
     770                                                content = content.replace(v[0], v[1]); 
     771                                }); 
     772                        }; 
     773 
     774                        if ((typeof(content) === "string") && (content.length > 0)) { 
     775                                // If HTML content with line-breaking tags, then remove all cr/lf chars because only tags will break a line 
     776                                if (/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(content)) { 
     777                                        process([ 
     778                                                /[\n\r]+/g 
     779                                        ]); 
     780                                } else { 
     781                                        // Otherwise just get rid of carriage returns (only need linefeeds) 
     782                                        process([ 
     783                                                /\r+/g 
     784                                        ]); 
     785                                } 
     786 
     787                                process([ 
     788                                        [/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi, "\n\n"],               // Block tags get a blank line after them 
     789                                        [/<br[^>]*>|<\/tr>/gi, "\n"],                           // Single linebreak for <br /> tags and table rows 
     790                                        [/<\/t[dh]>\s*<t[dh][^>]*>/gi, "\t"],           // Table cells get tabs betweem them 
     791                                        /<[a-z!\/?][^>]*>/gi,                                           // Delete all remaining tags 
     792                                        [/&nbsp;/gi, " "],                                                      // Convert non-break spaces to regular spaces (remember, *plain text*) 
     793                                        [/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"],// Cool little RegExp deletes whitespace around linebreak chars. 
     794                                        [/\n{3,}/g, "\n\n"]                                                     // Max. 2 consecutive linebreaks 
     795                                ]); 
     796 
     797                                content = ed.dom.decode(tinymce.html.Entities.encodeRaw(content)); 
     798 
     799                                // Perform default or custom replacements 
     800                                if (is(rl, "array")) { 
     801                                        process(rl); 
     802                                } else if (is(rl, "string")) { 
     803                                        process(new RegExp(rl, "gi")); 
     804                                } 
     805 
     806                                // Treat paragraphs as specified in the config 
     807                                if (linebr == "none") { 
     808                                        // Convert all line breaks to space 
     809                                        process([ 
     810                                                [/\n+/g, " "] 
     811                                        ]); 
     812                                } else if (linebr == "br") { 
     813                                        // Convert all line breaks to <br /> 
     814                                        process([ 
     815                                                [/\n/g, "<br />"] 
     816                                        ]); 
     817                                } else if (linebr == "p") { 
     818                                        // Convert all line breaks to <p>...</p> 
     819                                        process([ 
     820                                                [/\n+/g, "</p><p>"], 
     821                                                [/^(.*<\/p>)(<p>)$/, '<p>$1'] 
     822                                        ]); 
     823                                } else { 
     824                                        // defaults to "combined" 
     825                                        // Convert single line breaks to <br /> and double line breaks to <p>...</p> 
     826                                        process([ 
     827                                                [/\n\n/g, "</p><p>"], 
     828                                                [/^(.*<\/p>)(<p>)$/, '<p>$1'], 
     829                                                [/\n/g, "<br />"] 
     830                                        ]); 
     831                                } 
     832 
     833                                ed.execCommand('mceInsertContent', false, content); 
     834                        } 
     835                }, 
     836 
     837                /** 
     838                 * This method will open the old style paste dialogs. Some users might want the old behavior but still use the new cleanup engine. 
     839                 */ 
     840                _legacySupport : function() { 
     841                        var t = this, ed = t.editor; 
     842 
     843                        // Register command(s) for backwards compatibility 
     844                        ed.addCommand("mcePasteWord", function() { 
     845                                ed.windowManager.open({ 
     846                                        file: t.url + "/pasteword.htm", 
     847                                        width: parseInt(getParam(ed, "paste_dialog_width")), 
     848                                        height: parseInt(getParam(ed, "paste_dialog_height")), 
     849                                        inline: 1 
     850                                }); 
     851                        }); 
     852 
     853                        if (getParam(ed, "paste_text_use_dialog")) { 
     854                                ed.addCommand("mcePasteText", function() { 
     855                                        ed.windowManager.open({ 
     856                                                file : t.url + "/pastetext.htm", 
     857                                                width: parseInt(getParam(ed, "paste_dialog_width")), 
     858                                                height: parseInt(getParam(ed, "paste_dialog_height")), 
     859                                                inline : 1 
     860                                        }); 
     861                                }); 
     862                        } 
     863 
     864                        // Register button for backwards compatibility 
     865                        ed.addButton("pasteword", {title : "paste.paste_word_desc", cmd : "mcePasteWord"}); 
     866                } 
     867        }); 
     868 
     869        // Register plugin 
     870        tinymce.PluginManager.add("paste", tinymce.plugins.PastePlugin); 
     871})(); 
  • wp-includes/js/tinymce/themes/advanced/editor_template.dev.js

     
     1/** 
     2 * editor_template_src.js 
     3 * 
     4 * Copyright 2009, Moxiecode Systems AB 
     5 * Released under LGPL License. 
     6 * 
     7 * License: http://tinymce.moxiecode.com/license 
     8 * Contributing: http://tinymce.moxiecode.com/contributing 
     9 */ 
     10 
     11(function(tinymce) { 
     12        var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode; 
     13 
     14        // Tell it to load theme specific language pack(s) 
     15        tinymce.ThemeManager.requireLangPack('advanced'); 
     16 
     17        tinymce.create('tinymce.themes.AdvancedTheme', { 
     18                sizes : [8, 10, 12, 14, 18, 24, 36], 
     19 
     20                // Control name lookup, format: title, command 
     21                controls : { 
     22                        bold : ['bold_desc', 'Bold'], 
     23                        italic : ['italic_desc', 'Italic'], 
     24                        underline : ['underline_desc', 'Underline'], 
     25                        strikethrough : ['striketrough_desc', 'Strikethrough'], 
     26                        justifyleft : ['justifyleft_desc', 'JustifyLeft'], 
     27                        justifycenter : ['justifycenter_desc', 'JustifyCenter'], 
     28                        justifyright : ['justifyright_desc', 'JustifyRight'], 
     29                        justifyfull : ['justifyfull_desc', 'JustifyFull'], 
     30                        bullist : ['bullist_desc', 'InsertUnorderedList'], 
     31                        numlist : ['numlist_desc', 'InsertOrderedList'], 
     32                        outdent : ['outdent_desc', 'Outdent'], 
     33                        indent : ['indent_desc', 'Indent'], 
     34                        cut : ['cut_desc', 'Cut'], 
     35                        copy : ['copy_desc', 'Copy'], 
     36                        paste : ['paste_desc', 'Paste'], 
     37                        undo : ['undo_desc', 'Undo'], 
     38                        redo : ['redo_desc', 'Redo'], 
     39                        link : ['link_desc', 'mceLink'], 
     40                        unlink : ['unlink_desc', 'unlink'], 
     41                        image : ['image_desc', 'mceImage'], 
     42                        cleanup : ['cleanup_desc', 'mceCleanup'], 
     43                        help : ['help_desc', 'mceHelp'], 
     44                        code : ['code_desc', 'mceCodeEditor'], 
     45                        hr : ['hr_desc', 'InsertHorizontalRule'], 
     46                        removeformat : ['removeformat_desc', 'RemoveFormat'], 
     47                        sub : ['sub_desc', 'subscript'], 
     48                        sup : ['sup_desc', 'superscript'], 
     49                        forecolor : ['forecolor_desc', 'ForeColor'], 
     50                        forecolorpicker : ['forecolor_desc', 'mceForeColor'], 
     51                        backcolor : ['backcolor_desc', 'HiliteColor'], 
     52                        backcolorpicker : ['backcolor_desc', 'mceBackColor'], 
     53                        charmap : ['charmap_desc', 'mceCharMap'], 
     54                        visualaid : ['visualaid_desc', 'mceToggleVisualAid'], 
     55                        anchor : ['anchor_desc', 'mceInsertAnchor'], 
     56                        newdocument : ['newdocument_desc', 'mceNewDocument'], 
     57                        blockquote : ['blockquote_desc', 'mceBlockQuote'] 
     58                }, 
     59 
     60                stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'], 
     61 
     62                init : function(ed, url) { 
     63                        var t = this, s, v, o; 
     64         
     65                        t.editor = ed; 
     66                        t.url = url; 
     67                        t.onResolveName = new tinymce.util.Dispatcher(this); 
     68 
     69                        ed.forcedHighContrastMode = ed.settings.detect_highcontrast && t._isHighContrast(); 
     70                        ed.settings.skin = ed.forcedHighContrastMode ? 'highcontrast' : ed.settings.skin; 
     71 
     72                        // Default settings 
     73                        t.settings = s = extend({ 
     74                                theme_advanced_path : true, 
     75                                theme_advanced_toolbar_location : 'bottom', 
     76                                theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect", 
     77                                theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code", 
     78                                theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap", 
     79                                theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6", 
     80                                theme_advanced_toolbar_align : "center", 
     81                                theme_advanced_fonts : "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats", 
     82                                theme_advanced_more_colors : 1, 
     83                                theme_advanced_row_height : 23, 
     84                                theme_advanced_resize_horizontal : 1, 
     85                                theme_advanced_resizing_use_cookie : 1, 
     86                                theme_advanced_font_sizes : "1,2,3,4,5,6,7", 
     87                                theme_advanced_font_selector : "span", 
     88                                theme_advanced_show_current_color: 0, 
     89                                readonly : ed.settings.readonly 
     90                        }, ed.settings); 
     91 
     92                        // Setup default font_size_style_values 
     93                        if (!s.font_size_style_values) 
     94                                s.font_size_style_values = "8pt,10pt,12pt,14pt,18pt,24pt,36pt"; 
     95 
     96                        if (tinymce.is(s.theme_advanced_font_sizes, 'string')) { 
     97                                s.font_size_style_values = tinymce.explode(s.font_size_style_values); 
     98                                s.font_size_classes = tinymce.explode(s.font_size_classes || ''); 
     99 
     100                                // Parse string value 
     101                                o = {}; 
     102                                ed.settings.theme_advanced_font_sizes = s.theme_advanced_font_sizes; 
     103                                each(ed.getParam('theme_advanced_font_sizes', '', 'hash'), function(v, k) { 
     104                                        var cl; 
     105 
     106                                        if (k == v && v >= 1 && v <= 7) { 
     107                                                k = v + ' (' + t.sizes[v - 1] + 'pt)'; 
     108                                                cl = s.font_size_classes[v - 1]; 
     109                                                v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt'); 
     110                                        } 
     111 
     112                                        if (/^\s*\./.test(v)) 
     113                                                cl = v.replace(/\./g, ''); 
     114 
     115                                        o[k] = cl ? {'class' : cl} : {fontSize : v}; 
     116                                }); 
     117 
     118                                s.theme_advanced_font_sizes = o; 
     119                        } 
     120 
     121                        if ((v = s.theme_advanced_path_location) && v != 'none') 
     122                                s.theme_advanced_statusbar_location = s.theme_advanced_path_location; 
     123 
     124                        if (s.theme_advanced_statusbar_location == 'none') 
     125                                s.theme_advanced_statusbar_location = 0; 
     126 
     127                        if (ed.settings.content_css !== false) 
     128                                ed.contentCSS.push(ed.baseURI.toAbsolute(url + "/skins/" + ed.settings.skin + "/content.css")); 
     129 
     130                        // Init editor 
     131                        ed.onInit.add(function() { 
     132                                if (!ed.settings.readonly) { 
     133                                        ed.onNodeChange.add(t._nodeChanged, t); 
     134                                        ed.onKeyUp.add(t._updateUndoStatus, t); 
     135                                        ed.onMouseUp.add(t._updateUndoStatus, t); 
     136                                        ed.dom.bind(ed.dom.getRoot(), 'dragend', function() { 
     137                                                t._updateUndoStatus(ed); 
     138                                        }); 
     139                                } 
     140                        }); 
     141 
     142                        ed.onSetProgressState.add(function(ed, b, ti) { 
     143                                var co, id = ed.id, tb; 
     144 
     145                                if (b) { 
     146                                        t.progressTimer = setTimeout(function() { 
     147                                                co = ed.getContainer(); 
     148                                                co = co.insertBefore(DOM.create('DIV', {style : 'position:relative'}), co.firstChild); 
     149                                                tb = DOM.get(ed.id + '_tbl'); 
     150 
     151                                                DOM.add(co, 'div', {id : id + '_blocker', 'class' : 'mceBlocker', style : {width : tb.clientWidth + 2, height : tb.clientHeight + 2}}); 
     152                                                DOM.add(co, 'div', {id : id + '_progress', 'class' : 'mceProgress', style : {left : tb.clientWidth / 2, top : tb.clientHeight / 2}}); 
     153                                        }, ti || 0); 
     154                                } else { 
     155                                        DOM.remove(id + '_blocker'); 
     156                                        DOM.remove(id + '_progress'); 
     157                                        clearTimeout(t.progressTimer); 
     158                                } 
     159                        }); 
     160 
     161                        DOM.loadCSS(s.editor_css ? ed.documentBaseURI.toAbsolute(s.editor_css) : url + "/skins/" + ed.settings.skin + "/ui.css"); 
     162 
     163                        if (s.skin_variant) 
     164                                DOM.loadCSS(url + "/skins/" + ed.settings.skin + "/ui_" + s.skin_variant + ".css"); 
     165                }, 
     166 
     167                _isHighContrast : function() { 
     168                        var actualColor, div = DOM.add(DOM.getRoot(), 'div', {'style': 'background-color: rgb(171,239,86);'}); 
     169 
     170                        actualColor = (DOM.getStyle(div, 'background-color', true) + '').toLowerCase().replace(/ /g, ''); 
     171                        DOM.remove(div); 
     172 
     173                        return actualColor != 'rgb(171,239,86)' && actualColor != '#abef56'; 
     174                }, 
     175 
     176                createControl : function(n, cf) { 
     177                        var cd, c; 
     178 
     179                        if (c = cf.createControl(n)) 
     180                                return c; 
     181 
     182                        switch (n) { 
     183                                case "styleselect": 
     184                                        return this._createStyleSelect(); 
     185 
     186                                case "formatselect": 
     187                                        return this._createBlockFormats(); 
     188 
     189                                case "fontselect": 
     190                                        return this._createFontSelect(); 
     191 
     192                                case "fontsizeselect": 
     193                                        return this._createFontSizeSelect(); 
     194 
     195                                case "forecolor": 
     196                                        return this._createForeColorMenu(); 
     197 
     198                                case "backcolor": 
     199                                        return this._createBackColorMenu(); 
     200                        } 
     201 
     202                        if ((cd = this.controls[n])) 
     203                                return cf.createButton(n, {title : "advanced." + cd[0], cmd : cd[1], ui : cd[2], value : cd[3]}); 
     204                }, 
     205 
     206                execCommand : function(cmd, ui, val) { 
     207                        var f = this['_' + cmd]; 
     208 
     209                        if (f) { 
     210                                f.call(this, ui, val); 
     211                                return true; 
     212                        } 
     213 
     214                        return false; 
     215                }, 
     216 
     217                _importClasses : function(e) { 
     218                        var ed = this.editor, ctrl = ed.controlManager.get('styleselect'); 
     219 
     220                        if (ctrl.getLength() == 0) { 
     221                                each(ed.dom.getClasses(), function(o, idx) { 
     222                                        var name = 'style_' + idx; 
     223 
     224                                        ed.formatter.register(name, { 
     225                                                inline : 'span', 
     226                                                attributes : {'class' : o['class']}, 
     227                                                selector : '*' 
     228                                        }); 
     229 
     230                                        ctrl.add(o['class'], name); 
     231                                }); 
     232                        } 
     233                }, 
     234 
     235                _createStyleSelect : function(n) { 
     236                        var t = this, ed = t.editor, ctrlMan = ed.controlManager, ctrl; 
     237 
     238                        // Setup style select box 
     239                        ctrl = ctrlMan.createListBox('styleselect', { 
     240                                title : 'advanced.style_select', 
     241                                onselect : function(name) { 
     242                                        var matches, formatNames = []; 
     243 
     244                                        each(ctrl.items, function(item) { 
     245                                                formatNames.push(item.value); 
     246                                        }); 
     247 
     248                                        ed.focus(); 
     249                                        ed.undoManager.add(); 
     250 
     251                                        // Toggle off the current format 
     252                                        matches = ed.formatter.matchAll(formatNames); 
     253                                        if (!name || matches[0] == name) { 
     254                                                if (matches[0])  
     255                                                        ed.formatter.remove(matches[0]); 
     256                                        } else 
     257                                                ed.formatter.apply(name); 
     258 
     259                                        ed.undoManager.add(); 
     260                                        ed.nodeChanged(); 
     261 
     262                                        return false; // No auto select 
     263                                } 
     264                        }); 
     265 
     266                        // Handle specified format 
     267                        ed.onInit.add(function() { 
     268                                var counter = 0, formats = ed.getParam('style_formats'); 
     269 
     270                                if (formats) { 
     271                                        each(formats, function(fmt) { 
     272                                                var name, keys = 0; 
     273 
     274                                                each(fmt, function() {keys++;}); 
     275 
     276                                                if (keys > 1) { 
     277                                                        name = fmt.name = fmt.name || 'style_' + (counter++); 
     278                                                        ed.formatter.register(name, fmt); 
     279                                                        ctrl.add(fmt.title, name); 
     280                                                } else 
     281                                                        ctrl.add(fmt.title); 
     282                                        }); 
     283                                } else { 
     284                                        each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) { 
     285                                                var name; 
     286 
     287                                                if (val) { 
     288                                                        name = 'style_' + (counter++); 
     289 
     290                                                        ed.formatter.register(name, { 
     291                                                                inline : 'span', 
     292                                                                classes : val, 
     293                                                                selector : '*' 
     294                                                        }); 
     295 
     296                                                        ctrl.add(t.editor.translate(key), name); 
     297                                                } 
     298                                        }); 
     299                                } 
     300                        }); 
     301 
     302                        // Auto import classes if the ctrl box is empty 
     303                        if (ctrl.getLength() == 0) { 
     304                                ctrl.onPostRender.add(function(ed, n) { 
     305                                        if (!ctrl.NativeListBox) { 
     306                                                Event.add(n.id + '_text', 'focus', t._importClasses, t); 
     307                                                Event.add(n.id + '_text', 'mousedown', t._importClasses, t); 
     308                                                Event.add(n.id + '_open', 'focus', t._importClasses, t); 
     309                                                Event.add(n.id + '_open', 'mousedown', t._importClasses, t); 
     310                                        } else 
     311                                                Event.add(n.id, 'focus', t._importClasses, t); 
     312                                }); 
     313                        } 
     314 
     315                        return ctrl; 
     316                }, 
     317 
     318                _createFontSelect : function() { 
     319                        var c, t = this, ed = t.editor; 
     320 
     321                        c = ed.controlManager.createListBox('fontselect', { 
     322                                title : 'advanced.fontdefault', 
     323                                onselect : function(v) { 
     324                                        var cur = c.items[c.selectedIndex]; 
     325 
     326                                        if (!v && cur) { 
     327                                                ed.execCommand('FontName', false, cur.value); 
     328                                                return; 
     329                                        } 
     330 
     331                                        ed.execCommand('FontName', false, v); 
     332 
     333                                        // Fake selection, execCommand will fire a nodeChange and update the selection 
     334                                        c.select(function(sv) { 
     335                                                return v == sv; 
     336                                        }); 
     337 
     338                                        if (cur && cur.value == v) { 
     339                                                c.select(null); 
     340                                        } 
     341 
     342                                        return false; // No auto select 
     343                                } 
     344                        }); 
     345 
     346                        if (c) { 
     347                                each(ed.getParam('theme_advanced_fonts', t.settings.theme_advanced_fonts, 'hash'), function(v, k) { 
     348                                        c.add(ed.translate(k), v, {style : v.indexOf('dings') == -1 ? 'font-family:' + v : ''}); 
     349                                }); 
     350                        } 
     351 
     352                        return c; 
     353                }, 
     354 
     355                _createFontSizeSelect : function() { 
     356                        var t = this, ed = t.editor, c, i = 0, cl = []; 
     357 
     358                        c = ed.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', onselect : function(v) { 
     359                                var cur = c.items[c.selectedIndex]; 
     360 
     361                                if (!v && cur) { 
     362                                        cur = cur.value; 
     363 
     364                                        if (cur['class']) { 
     365                                                ed.formatter.toggle('fontsize_class', {value : cur['class']}); 
     366                                                ed.undoManager.add(); 
     367                                                ed.nodeChanged(); 
     368                                        } else { 
     369                                                ed.execCommand('FontSize', false, cur.fontSize); 
     370                                        } 
     371 
     372                                        return; 
     373                                } 
     374 
     375                                if (v['class']) { 
     376                                        ed.focus(); 
     377                                        ed.undoManager.add(); 
     378                                        ed.formatter.toggle('fontsize_class', {value : v['class']}); 
     379                                        ed.undoManager.add(); 
     380                                        ed.nodeChanged(); 
     381                                } else 
     382                                        ed.execCommand('FontSize', false, v.fontSize); 
     383 
     384                                // Fake selection, execCommand will fire a nodeChange and update the selection 
     385                                c.select(function(sv) { 
     386                                        return v == sv; 
     387                                }); 
     388 
     389                                if (cur && (cur.value.fontSize == v.fontSize || cur.value['class'] && cur.value['class'] == v['class'])) { 
     390                                        c.select(null); 
     391                                } 
     392 
     393                                return false; // No auto select 
     394                        }}); 
     395 
     396                        if (c) { 
     397                                each(t.settings.theme_advanced_font_sizes, function(v, k) { 
     398                                        var fz = v.fontSize; 
     399 
     400                                        if (fz >= 1 && fz <= 7) 
     401                                                fz = t.sizes[parseInt(fz) - 1] + 'pt'; 
     402 
     403                                        c.add(k, v, {'style' : 'font-size:' + fz, 'class' : 'mceFontSize' + (i++) + (' ' + (v['class'] || ''))}); 
     404                                }); 
     405                        } 
     406 
     407                        return c; 
     408                }, 
     409 
     410                _createBlockFormats : function() { 
     411                        var c, fmts = { 
     412                                p : 'advanced.paragraph', 
     413                                address : 'advanced.address', 
     414                                pre : 'advanced.pre', 
     415                                h1 : 'advanced.h1', 
     416                                h2 : 'advanced.h2', 
     417                                h3 : 'advanced.h3', 
     418                                h4 : 'advanced.h4', 
     419                                h5 : 'advanced.h5', 
     420                                h6 : 'advanced.h6', 
     421                                div : 'advanced.div', 
     422                                blockquote : 'advanced.blockquote', 
     423                                code : 'advanced.code', 
     424                                dt : 'advanced.dt', 
     425                                dd : 'advanced.dd', 
     426                                samp : 'advanced.samp' 
     427                        }, t = this; 
     428 
     429                        c = t.editor.controlManager.createListBox('formatselect', {title : 'advanced.block', onselect : function(v) { 
     430                                t.editor.execCommand('FormatBlock', false, v); 
     431                                return false; 
     432                        }}); 
     433 
     434                        if (c) { 
     435                                each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) { 
     436                                        c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v}); 
     437                                }); 
     438                        } 
     439 
     440                        return c; 
     441                }, 
     442 
     443                _createForeColorMenu : function() { 
     444                        var c, t = this, s = t.settings, o = {}, v; 
     445 
     446                        if (s.theme_advanced_more_colors) { 
     447                                o.more_colors_func = function() { 
     448                                        t._mceColorPicker(0, { 
     449                                                color : c.value, 
     450                                                func : function(co) { 
     451                                                        c.setColor(co); 
     452                                                } 
     453                                        }); 
     454                                }; 
     455                        } 
     456 
     457                        if (v = s.theme_advanced_text_colors) 
     458                                o.colors = v; 
     459 
     460                        if (s.theme_advanced_default_foreground_color) 
     461                                o.default_color = s.theme_advanced_default_foreground_color; 
     462 
     463                        o.title = 'advanced.forecolor_desc'; 
     464                        o.cmd = 'ForeColor'; 
     465                        o.scope = this; 
     466 
     467                        c = t.editor.controlManager.createColorSplitButton('forecolor', o); 
     468 
     469                        return c; 
     470                }, 
     471 
     472                _createBackColorMenu : function() { 
     473                        var c, t = this, s = t.settings, o = {}, v; 
     474 
     475                        if (s.theme_advanced_more_colors) { 
     476                                o.more_colors_func = function() { 
     477                                        t._mceColorPicker(0, { 
     478                                                color : c.value, 
     479                                                func : function(co) { 
     480                                                        c.setColor(co); 
     481                                                } 
     482                                        }); 
     483                                }; 
     484                        } 
     485 
     486                        if (v = s.theme_advanced_background_colors) 
     487                                o.colors = v; 
     488 
     489                        if (s.theme_advanced_default_background_color) 
     490                                o.default_color = s.theme_advanced_default_background_color; 
     491 
     492                        o.title = 'advanced.backcolor_desc'; 
     493                        o.cmd = 'HiliteColor'; 
     494                        o.scope = this; 
     495 
     496                        c = t.editor.controlManager.createColorSplitButton('backcolor', o); 
     497 
     498                        return c; 
     499                }, 
     500 
     501                renderUI : function(o) { 
     502                        var n, ic, tb, t = this, ed = t.editor, s = t.settings, sc, p, nl; 
     503 
     504                        if (ed.settings) { 
     505                                ed.settings.aria_label = s.aria_label + ed.getLang('advanced.help_shortcut'); 
     506                        } 
     507 
     508                        // TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for. 
     509                        // Maybe actually inherit it from the original textara? 
     510                        n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')}); 
     511                        DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label); 
     512 
     513                        if (!DOM.boxModel) 
     514                                n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'}); 
     515 
     516                        n = sc = DOM.add(n, 'table', {role : "presentation", id : ed.id + '_tbl', 'class' : 'mceLayout', cellSpacing : 0, cellPadding : 0}); 
     517                        n = tb = DOM.add(n, 'tbody'); 
     518 
     519                        switch ((s.theme_advanced_layout_manager || '').toLowerCase()) { 
     520                                case "rowlayout": 
     521                                        ic = t._rowLayout(s, tb, o); 
     522                                        break; 
     523 
     524                                case "customlayout": 
     525                                        ic = ed.execCallback("theme_advanced_custom_layout", s, tb, o, p); 
     526                                        break; 
     527 
     528                                default: 
     529                                        ic = t._simpleLayout(s, tb, o, p); 
     530                        } 
     531 
     532                        n = o.targetNode; 
     533 
     534                        // Add classes to first and last TRs 
     535                        nl = sc.rows; 
     536                        DOM.addClass(nl[0], 'mceFirst'); 
     537                        DOM.addClass(nl[nl.length - 1], 'mceLast'); 
     538 
     539                        // Add classes to first and last TDs 
     540                        each(DOM.select('tr', tb), function(n) { 
     541                                DOM.addClass(n.firstChild, 'mceFirst'); 
     542                                DOM.addClass(n.childNodes[n.childNodes.length - 1], 'mceLast'); 
     543                        }); 
     544 
     545                        if (DOM.get(s.theme_advanced_toolbar_container)) 
     546                                DOM.get(s.theme_advanced_toolbar_container).appendChild(p); 
     547                        else 
     548                                DOM.insertAfter(p, n); 
     549 
     550                        Event.add(ed.id + '_path_row', 'click', function(e) { 
     551                                e = e.target; 
     552 
     553                                if (e.nodeName == 'A') { 
     554                                        t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/, '$1')); 
     555 
     556                                        return Event.cancel(e); 
     557                                } 
     558                        }); 
     559/* 
     560                        if (DOM.get(ed.id + '_path_row')) { 
     561                                Event.add(ed.id + '_tbl', 'mouseover', function(e) { 
     562                                        var re; 
     563         
     564                                        e = e.target; 
     565 
     566                                        if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) { 
     567                                                re = DOM.get(ed.id + '_path_row'); 
     568                                                t.lastPath = re.innerHTML; 
     569                                                DOM.setHTML(re, e.parentNode.title); 
     570                                        } 
     571                                }); 
     572 
     573                                Event.add(ed.id + '_tbl', 'mouseout', function(e) { 
     574                                        if (t.lastPath) { 
     575                                                DOM.setHTML(ed.id + '_path_row', t.lastPath); 
     576                                                t.lastPath = 0; 
     577                                        } 
     578                                }); 
     579                        } 
     580*/ 
     581 
     582                        if (!ed.getParam('accessibility_focus')) 
     583                                Event.add(DOM.add(p, 'a', {href : '#'}, '<!-- IE -->'), 'focus', function() {tinyMCE.get(ed.id).focus();}); 
     584 
     585                        if (s.theme_advanced_toolbar_location == 'external') 
     586                                o.deltaHeight = 0; 
     587 
     588                        t.deltaHeight = o.deltaHeight; 
     589                        o.targetNode = null; 
     590 
     591                        ed.onKeyDown.add(function(ed, evt) { 
     592                                var DOM_VK_F10 = 121, DOM_VK_F11 = 122; 
     593 
     594                                if (evt.altKey) { 
     595                                        if (evt.keyCode === DOM_VK_F10) { 
     596                                                // Make sure focus is given to toolbar in Safari. 
     597                                                // We can't do this in IE as it prevents giving focus to toolbar when editor is in a frame 
     598                                                if (tinymce.isWebKit) { 
     599                                                        window.focus(); 
     600                                                } 
     601                                                t.toolbarGroup.focus(); 
     602                                                return Event.cancel(evt); 
     603                                        } else if (evt.keyCode === DOM_VK_F11) { 
     604                                                DOM.get(ed.id + '_path_row').focus(); 
     605                                                return Event.cancel(evt); 
     606                                        } 
     607                                } 
     608                        }); 
     609 
     610                        // alt+0 is the UK recommended shortcut for accessing the list of access controls. 
     611                        ed.addShortcut('alt+0', '', 'mceShortcuts', t); 
     612 
     613                        return { 
     614                                iframeContainer : ic, 
     615                                editorContainer : ed.id + '_parent', 
     616                                sizeContainer : sc, 
     617                                deltaHeight : o.deltaHeight 
     618                        }; 
     619                }, 
     620 
     621                getInfo : function() { 
     622                        return { 
     623                                longname : 'Advanced theme', 
     624                                author : 'Moxiecode Systems AB', 
     625                                authorurl : 'http://tinymce.moxiecode.com', 
     626                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     627                        } 
     628                }, 
     629 
     630                resizeBy : function(dw, dh) { 
     631                        var e = DOM.get(this.editor.id + '_ifr'); 
     632 
     633                        this.resizeTo(e.clientWidth + dw, e.clientHeight + dh); 
     634                }, 
     635 
     636                resizeTo : function(w, h, store) { 
     637                        var ed = this.editor, s = this.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr'); 
     638 
     639                        // Boundery fix box 
     640                        w = Math.max(s.theme_advanced_resizing_min_width || 100, w); 
     641                        h = Math.max(s.theme_advanced_resizing_min_height || 100, h); 
     642                        w = Math.min(s.theme_advanced_resizing_max_width || 0xFFFF, w); 
     643                        h = Math.min(s.theme_advanced_resizing_max_height || 0xFFFF, h); 
     644 
     645                        // Resize iframe and container 
     646                        DOM.setStyle(e, 'height', ''); 
     647                        DOM.setStyle(ifr, 'height', h); 
     648 
     649                        if (s.theme_advanced_resize_horizontal) { 
     650                                DOM.setStyle(e, 'width', ''); 
     651                                DOM.setStyle(ifr, 'width', w); 
     652 
     653                                // Make sure that the size is never smaller than the over all ui 
     654                                if (w < e.clientWidth) { 
     655                                        w = e.clientWidth; 
     656                                        DOM.setStyle(ifr, 'width', e.clientWidth); 
     657                                } 
     658                        } 
     659 
     660                        // Store away the size 
     661                        if (store && s.theme_advanced_resizing_use_cookie) { 
     662                                Cookie.setHash("TinyMCE_" + ed.id + "_size", { 
     663                                        cw : w, 
     664                                        ch : h 
     665                                }); 
     666                        } 
     667                }, 
     668 
     669                destroy : function() { 
     670                        var id = this.editor.id; 
     671 
     672                        Event.clear(id + '_resize'); 
     673                        Event.clear(id + '_path_row'); 
     674                        Event.clear(id + '_external_close'); 
     675                }, 
     676 
     677                // Internal functions 
     678 
     679                _simpleLayout : function(s, tb, o, p) { 
     680                        var t = this, ed = t.editor, lo = s.theme_advanced_toolbar_location, sl = s.theme_advanced_statusbar_location, n, ic, etb, c; 
     681 
     682                        if (s.readonly) { 
     683                                n = DOM.add(tb, 'tr'); 
     684                                n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); 
     685                                return ic; 
     686                        } 
     687 
     688                        // Create toolbar container at top 
     689                        if (lo == 'top') 
     690                                t._addToolbars(tb, o); 
     691 
     692                        // Create external toolbar 
     693                        if (lo == 'external') { 
     694                                n = c = DOM.create('div', {style : 'position:relative'}); 
     695                                n = DOM.add(n, 'div', {id : ed.id + '_external', 'class' : 'mceExternalToolbar'}); 
     696                                DOM.add(n, 'a', {id : ed.id + '_external_close', href : 'javascript:;', 'class' : 'mceExternalClose'}); 
     697                                n = DOM.add(n, 'table', {id : ed.id + '_tblext', cellSpacing : 0, cellPadding : 0}); 
     698                                etb = DOM.add(n, 'tbody'); 
     699 
     700                                if (p.firstChild.className == 'mceOldBoxModel') 
     701                                        p.firstChild.appendChild(c); 
     702                                else 
     703                                        p.insertBefore(c, p.firstChild); 
     704 
     705                                t._addToolbars(etb, o); 
     706 
     707                                ed.onMouseUp.add(function() { 
     708                                        var e = DOM.get(ed.id + '_external'); 
     709                                        DOM.show(e); 
     710 
     711                                        DOM.hide(lastExtID); 
     712 
     713                                        var f = Event.add(ed.id + '_external_close', 'click', function() { 
     714                                                DOM.hide(ed.id + '_external'); 
     715                                                Event.remove(ed.id + '_external_close', 'click', f); 
     716                                        }); 
     717 
     718                                        DOM.show(e); 
     719                                        DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1); 
     720 
     721                                        // Fixes IE rendering bug 
     722                                        DOM.hide(e); 
     723                                        DOM.show(e); 
     724                                        e.style.filter = ''; 
     725 
     726                                        lastExtID = ed.id + '_external'; 
     727 
     728                                        e = null; 
     729                                }); 
     730                        } 
     731 
     732                        if (sl == 'top') 
     733                                t._addStatusBar(tb, o); 
     734 
     735                        // Create iframe container 
     736                        if (!s.theme_advanced_toolbar_container) { 
     737                                n = DOM.add(tb, 'tr'); 
     738                                n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); 
     739                        } 
     740 
     741                        // Create toolbar container at bottom 
     742                        if (lo == 'bottom') 
     743                                t._addToolbars(tb, o); 
     744 
     745                        if (sl == 'bottom') 
     746                                t._addStatusBar(tb, o); 
     747 
     748                        return ic; 
     749                }, 
     750 
     751                _rowLayout : function(s, tb, o) { 
     752                        var t = this, ed = t.editor, dc, da, cf = ed.controlManager, n, ic, to, a; 
     753 
     754                        dc = s.theme_advanced_containers_default_class || ''; 
     755                        da = s.theme_advanced_containers_default_align || 'center'; 
     756 
     757                        each(explode(s.theme_advanced_containers || ''), function(c, i) { 
     758                                var v = s['theme_advanced_container_' + c] || ''; 
     759 
     760                                switch (c.toLowerCase()) { 
     761                                        case 'mceeditor': 
     762                                                n = DOM.add(tb, 'tr'); 
     763                                                n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); 
     764                                                break; 
     765 
     766                                        case 'mceelementpath': 
     767                                                t._addStatusBar(tb, o); 
     768                                                break; 
     769 
     770                                        default: 
     771                                                a = (s['theme_advanced_container_' + c + '_align'] || da).toLowerCase(); 
     772                                                a = 'mce' + t._ufirst(a); 
     773 
     774                                                n = DOM.add(DOM.add(tb, 'tr'), 'td', { 
     775                                                        'class' : 'mceToolbar ' + (s['theme_advanced_container_' + c + '_class'] || dc) + ' ' + a || da 
     776                                                }); 
     777 
     778                                                to = cf.createToolbar("toolbar" + i); 
     779                                                t._addControls(v, to); 
     780                                                DOM.setHTML(n, to.renderHTML()); 
     781                                                o.deltaHeight -= s.theme_advanced_row_height; 
     782                                } 
     783                        }); 
     784 
     785                        return ic; 
     786                }, 
     787 
     788                _addControls : function(v, tb) { 
     789                        var t = this, s = t.settings, di, cf = t.editor.controlManager; 
     790 
     791                        if (s.theme_advanced_disable && !t._disabled) { 
     792                                di = {}; 
     793 
     794                                each(explode(s.theme_advanced_disable), function(v) { 
     795                                        di[v] = 1; 
     796                                }); 
     797 
     798                                t._disabled = di; 
     799                        } else 
     800                                di = t._disabled; 
     801 
     802                        each(explode(v), function(n) { 
     803                                var c; 
     804 
     805                                if (di && di[n]) 
     806                                        return; 
     807 
     808                                // Compatiblity with 2.x 
     809                                if (n == 'tablecontrols') { 
     810                                        each(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"], function(n) { 
     811                                                n = t.createControl(n, cf); 
     812 
     813                                                if (n) 
     814                                                        tb.add(n); 
     815                                        }); 
     816 
     817                                        return; 
     818                                } 
     819 
     820                                c = t.createControl(n, cf); 
     821 
     822                                if (c) 
     823                                        tb.add(c); 
     824                        }); 
     825                }, 
     826 
     827                _addToolbars : function(c, o) { 
     828                        var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup; 
     829 
     830                        toolbarGroup = cf.createToolbarGroup('toolbargroup', { 
     831                                'name': ed.getLang('advanced.toolbar'), 
     832                                'tab_focus_toolbar':ed.getParam('theme_advanced_tab_focus_toolbar') 
     833                        }); 
     834 
     835                        t.toolbarGroup = toolbarGroup; 
     836 
     837                        a = s.theme_advanced_toolbar_align.toLowerCase(); 
     838                        a = 'mce' + t._ufirst(a); 
     839 
     840                        n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"presentation"}); 
     841 
     842                        // Create toolbar and add the controls 
     843                        for (i=1; (v = s['theme_advanced_buttons' + i]); i++) { 
     844                                tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i}); 
     845 
     846                                if (s['theme_advanced_buttons' + i + '_add']) 
     847                                        v += ',' + s['theme_advanced_buttons' + i + '_add']; 
     848 
     849                                if (s['theme_advanced_buttons' + i + '_add_before']) 
     850                                        v = s['theme_advanced_buttons' + i + '_add_before'] + ',' + v; 
     851 
     852                                t._addControls(v, tb); 
     853                                toolbarGroup.add(tb); 
     854 
     855                                o.deltaHeight -= s.theme_advanced_row_height; 
     856                        } 
     857                        h.push(toolbarGroup.renderHTML()); 
     858                        h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->')); 
     859                        DOM.setHTML(n, h.join('')); 
     860                }, 
     861 
     862                _addStatusBar : function(tb, o) { 
     863                        var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td; 
     864 
     865                        n = DOM.add(tb, 'tr'); 
     866                        n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'});  
     867                        n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'}); 
     868                        if (s.theme_advanced_path) { 
     869                                DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path')); 
     870                                DOM.add(n, 'span', {}, ': '); 
     871                        } else { 
     872                                DOM.add(n, 'span', {}, '&#160;'); 
     873                        } 
     874                         
     875 
     876                        if (s.theme_advanced_resizing) { 
     877                                DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"}); 
     878 
     879                                if (s.theme_advanced_resizing_use_cookie) { 
     880                                        ed.onPostRender.add(function() { 
     881                                                var o = Cookie.getHash("TinyMCE_" + ed.id + "_size"), c = DOM.get(ed.id + '_tbl'); 
     882 
     883                                                if (!o) 
     884                                                        return; 
     885 
     886                                                t.resizeTo(o.cw, o.ch); 
     887                                        }); 
     888                                } 
     889 
     890                                ed.onPostRender.add(function() { 
     891                                        Event.add(ed.id + '_resize', 'click', function(e) { 
     892                                                e.preventDefault(); 
     893                                        }); 
     894 
     895                                        Event.add(ed.id + '_resize', 'mousedown', function(e) { 
     896                                                var mouseMoveHandler1, mouseMoveHandler2, 
     897                                                        mouseUpHandler1, mouseUpHandler2, 
     898                                                        startX, startY, startWidth, startHeight, width, height, ifrElm; 
     899 
     900                                                function resizeOnMove(e) { 
     901                                                        e.preventDefault(); 
     902 
     903                                                        width = startWidth + (e.screenX - startX); 
     904                                                        height = startHeight + (e.screenY - startY); 
     905 
     906                                                        t.resizeTo(width, height); 
     907                                                }; 
     908 
     909                                                function endResize(e) { 
     910                                                        // Stop listening 
     911                                                        Event.remove(DOM.doc, 'mousemove', mouseMoveHandler1); 
     912                                                        Event.remove(ed.getDoc(), 'mousemove', mouseMoveHandler2); 
     913                                                        Event.remove(DOM.doc, 'mouseup', mouseUpHandler1); 
     914                                                        Event.remove(ed.getDoc(), 'mouseup', mouseUpHandler2); 
     915 
     916                                                        width = startWidth + (e.screenX - startX); 
     917                                                        height = startHeight + (e.screenY - startY); 
     918                                                        t.resizeTo(width, height, true); 
     919                                                }; 
     920 
     921                                                e.preventDefault(); 
     922 
     923                                                // Get the current rect size 
     924                                                startX = e.screenX; 
     925                                                startY = e.screenY; 
     926                                                ifrElm = DOM.get(t.editor.id + '_ifr'); 
     927                                                startWidth = width = ifrElm.clientWidth; 
     928                                                startHeight = height = ifrElm.clientHeight; 
     929 
     930                                                // Register envent handlers 
     931                                                mouseMoveHandler1 = Event.add(DOM.doc, 'mousemove', resizeOnMove); 
     932                                                mouseMoveHandler2 = Event.add(ed.getDoc(), 'mousemove', resizeOnMove); 
     933                                                mouseUpHandler1 = Event.add(DOM.doc, 'mouseup', endResize); 
     934                                                mouseUpHandler2 = Event.add(ed.getDoc(), 'mouseup', endResize); 
     935                                        }); 
     936                                }); 
     937                        } 
     938 
     939                        o.deltaHeight -= 21; 
     940                        n = tb = null; 
     941                }, 
     942 
     943                _updateUndoStatus : function(ed) { 
     944                        var cm = ed.controlManager, um = ed.undoManager; 
     945 
     946                        cm.setDisabled('undo', !um.hasUndo() && !um.typing); 
     947                        cm.setDisabled('redo', !um.hasRedo()); 
     948                }, 
     949 
     950                _nodeChanged : function(ed, cm, n, co, ob) { 
     951                        var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn, fc, bc, formatNames, matches; 
     952 
     953                        tinymce.each(t.stateControls, function(c) { 
     954                                cm.setActive(c, ed.queryCommandState(t.controls[c][1])); 
     955                        }); 
     956 
     957                        function getParent(name) { 
     958                                var i, parents = ob.parents, func = name; 
     959 
     960                                if (typeof(name) == 'string') { 
     961                                        func = function(node) { 
     962                                                return node.nodeName == name; 
     963                                        }; 
     964                                } 
     965 
     966                                for (i = 0; i < parents.length; i++) { 
     967                                        if (func(parents[i])) 
     968                                                return parents[i]; 
     969                                } 
     970                        }; 
     971 
     972                        cm.setActive('visualaid', ed.hasVisual); 
     973                        t._updateUndoStatus(ed); 
     974                        cm.setDisabled('outdent', !ed.queryCommandState('Outdent')); 
     975 
     976                        p = getParent('A'); 
     977                        if (c = cm.get('link')) { 
     978                                if (!p || !p.name) { 
     979                                        c.setDisabled(!p && co); 
     980                                        c.setActive(!!p); 
     981                                } 
     982                        } 
     983 
     984                        if (c = cm.get('unlink')) { 
     985                                c.setDisabled(!p && co); 
     986                                c.setActive(!!p && !p.name); 
     987                        } 
     988 
     989                        if (c = cm.get('anchor')) { 
     990                                c.setActive(!co && !!p && p.name); 
     991                        } 
     992 
     993                        p = getParent('IMG'); 
     994                        if (c = cm.get('image')) 
     995                                c.setActive(!co && !!p && n.className.indexOf('mceItem') == -1); 
     996 
     997                        if (c = cm.get('styleselect')) { 
     998                                t._importClasses(); 
     999 
     1000                                formatNames = []; 
     1001                                each(c.items, function(item) { 
     1002                                        formatNames.push(item.value); 
     1003                                }); 
     1004 
     1005                                matches = ed.formatter.matchAll(formatNames); 
     1006                                c.select(matches[0]); 
     1007                        } 
     1008 
     1009                        if (c = cm.get('formatselect')) { 
     1010                                p = getParent(DOM.isBlock); 
     1011 
     1012                                if (p) 
     1013                                        c.select(p.nodeName.toLowerCase()); 
     1014                        } 
     1015 
     1016                        // Find out current fontSize, fontFamily and fontClass 
     1017                        getParent(function(n) { 
     1018                                if (n.nodeName === 'SPAN') { 
     1019                                        if (!cl && n.className) 
     1020                                                cl = n.className; 
     1021                                } 
     1022 
     1023                                if (ed.dom.is(n, s.theme_advanced_font_selector)) { 
     1024                                        if (!fz && n.style.fontSize) 
     1025                                                fz = n.style.fontSize; 
     1026 
     1027                                        if (!fn && n.style.fontFamily) 
     1028                                                fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase(); 
     1029                                         
     1030                                        if (!fc && n.style.color) 
     1031                                                fc = n.style.color; 
     1032 
     1033                                        if (!bc && n.style.backgroundColor) 
     1034                                                bc = n.style.backgroundColor; 
     1035                                } 
     1036 
     1037                                return false; 
     1038                        }); 
     1039 
     1040                        if (c = cm.get('fontselect')) { 
     1041                                c.select(function(v) { 
     1042                                        return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn; 
     1043                                }); 
     1044                        } 
     1045 
     1046                        // Select font size 
     1047                        if (c = cm.get('fontsizeselect')) { 
     1048                                // Use computed style 
     1049                                if (s.theme_advanced_runtime_fontsize && !fz && !cl) 
     1050                                        fz = ed.dom.getStyle(n, 'fontSize', true); 
     1051 
     1052                                c.select(function(v) { 
     1053                                        if (v.fontSize && v.fontSize === fz) 
     1054                                                return true; 
     1055 
     1056                                        if (v['class'] && v['class'] === cl) 
     1057                                                return true; 
     1058                                }); 
     1059                        } 
     1060                         
     1061                        if (s.theme_advanced_show_current_color) { 
     1062                                function updateColor(controlId, color) { 
     1063                                        if (c = cm.get(controlId)) { 
     1064                                                if (!color) 
     1065                                                        color = c.settings.default_color; 
     1066                                                if (color !== c.value) { 
     1067                                                        c.displayColor(color); 
     1068                                                } 
     1069                                        } 
     1070                                } 
     1071                                updateColor('forecolor', fc); 
     1072                                updateColor('backcolor', bc); 
     1073                        } 
     1074 
     1075                        if (s.theme_advanced_show_current_color) { 
     1076                                function updateColor(controlId, color) { 
     1077                                        if (c = cm.get(controlId)) { 
     1078                                                if (!color) 
     1079                                                        color = c.settings.default_color; 
     1080                                                if (color !== c.value) { 
     1081                                                        c.displayColor(color); 
     1082                                                } 
     1083                                        } 
     1084                                }; 
     1085 
     1086                                updateColor('forecolor', fc); 
     1087                                updateColor('backcolor', bc); 
     1088                        } 
     1089 
     1090                        if (s.theme_advanced_path && s.theme_advanced_statusbar_location) { 
     1091                                p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'}); 
     1092 
     1093                                if (t.statusKeyboardNavigation) { 
     1094                                        t.statusKeyboardNavigation.destroy(); 
     1095                                        t.statusKeyboardNavigation = null; 
     1096                                } 
     1097 
     1098                                DOM.setHTML(p, ''); 
     1099 
     1100                                getParent(function(n) { 
     1101                                        var na = n.nodeName.toLowerCase(), u, pi, ti = ''; 
     1102 
     1103                                        // Ignore non element and bogus/hidden elements 
     1104                                        if (n.nodeType != 1 || na === 'br' || n.getAttribute('data-mce-bogus') || DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved')) 
     1105                                                return; 
     1106 
     1107                                        // Handle prefix 
     1108                                        if (tinymce.isIE && n.scopeName !== 'HTML') 
     1109                                                na = n.scopeName + ':' + na; 
     1110 
     1111                                        // Remove internal prefix 
     1112                                        na = na.replace(/mce\:/g, ''); 
     1113 
     1114                                        // Handle node name 
     1115                                        switch (na) { 
     1116                                                case 'b': 
     1117                                                        na = 'strong'; 
     1118                                                        break; 
     1119 
     1120                                                case 'i': 
     1121                                                        na = 'em'; 
     1122                                                        break; 
     1123 
     1124                                                case 'img': 
     1125                                                        if (v = DOM.getAttrib(n, 'src')) 
     1126                                                                ti += 'src: ' + v + ' '; 
     1127 
     1128                                                        break; 
     1129 
     1130                                                case 'a': 
     1131                                                        if (v = DOM.getAttrib(n, 'name')) { 
     1132                                                                ti += 'name: ' + v + ' '; 
     1133                                                                na += '#' + v; 
     1134                                                        } 
     1135 
     1136                                                        if (v = DOM.getAttrib(n, 'href')) 
     1137                                                                ti += 'href: ' + v + ' '; 
     1138 
     1139                                                        break; 
     1140 
     1141                                                case 'font': 
     1142                                                        if (v = DOM.getAttrib(n, 'face')) 
     1143                                                                ti += 'font: ' + v + ' '; 
     1144