WordPress.org

Make WordPress Core

Ticket #21585: 21585.patch

File 21585.patch, 46.6 KB (added by azaozz, 20 months ago)
  • wp-admin/admin-ajax.php

     
    5050        'menu-locations-save', 'menu-quick-search', 'meta-box-order', 'get-permalink', 
    5151        'sample-permalink', 'inline-save', 'inline-save-tax', 'find_posts', 'widgets-order', 
    5252        'save-widget', 'set-post-thumbnail', 'date_format', 'time_format', 'wp-fullscreen-save-post', 
    53         'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 
     53        'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'mce-gallery-preview', 
    5454); 
    5555 
    5656// Register core Ajax calls. 
  • wp-admin/includes/ajax-actions.php

     
    5050 
    5151        wp_die( 0 ); 
    5252} 
     53 
    5354function wp_ajax_ajax_tag_search() { 
    5455        global $wpdb; 
    5556 
     
    18011802        update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed ); 
    18021803        wp_die( 1 ); 
    18031804} 
     1805 
     1806function wp_ajax_mce_gallery_preview() { 
     1807        if ( empty($_POST['post_ID']) || empty($_POST['shortcode']) ) 
     1808                wp_die( 0 ); 
     1809 
     1810        $post_id = (int) $_POST['post_ID']; 
     1811        if ( !current_user_can('edit_post', $post_id) ) 
     1812                die('-1'); 
     1813 
     1814        $shortcode_args = trim( str_replace('[gallery', '', $_POST['shortcode']), '[] //' ); 
     1815        $args = $shortcode_args ? shortcode_parse_atts( stripslashes($shortcode_args) ) : array(); 
     1816        $args['id'] = $post_id; 
     1817        $args['mce_preview'] = preg_replace('/[^a-z0-9_]+/', '', $_POST['mcediv_id']); 
     1818 
     1819         
     1820         
     1821        //var_dump($args); 
     1822 
     1823         
     1824        echo gallery_shortcode( $args ); 
     1825        die; 
     1826 
     1827        // allow only some args? 
     1828        $order = !empty($args['order']) && 'desc' == strtolower($args['order']) ? 'DESC' : 'ASC'; 
     1829        $orderby = !empty($args['orderby']) ? preg_replace('/[^a-zA-Z_ ]+/', '', $args['orderby']) : 'menu_order ID'; 
     1830        $columns = !empty($args['columns']) ? (int) $args['columns'] : 3; 
     1831        $size = !empty($args['size']) && in_array( $args['size'], array('thumbnail', 'medium', 'large', 'full' ), true ) ? $args['size'] : 'thumbnail'; 
     1832        $include = !empty($args['include']) ? preg_replace('/[^0-9,]+/', '', $args['include']) : ''; 
     1833        $exclude = !empty($args['exclude']) ? preg_replace('/[^0-9,]+/', '', $args['exclude']) : ''; 
     1834        $mce_preview = true; 
     1835         
     1836        echo gallery_shortcode( compact( 'id', 'order', 'orderby', 'columns', 'size', 'include', 'exclude', 'mce_preview' ) ); 
     1837        die; 
     1838} 
     1839 
  • wp-admin/includes/media.php

     
    470470 
    471471        if ( isset($_POST['insert-gallery']) || isset($_POST['update-gallery']) ) { ?> 
    472472                <script type="text/javascript"> 
    473                 /* <![CDATA[ */ 
    474473                var win = window.dialogArguments || opener || parent || top; 
    475474                win.tb_remove(); 
    476                 /* ]]> */ 
    477475                </script> 
    478476                <?php 
    479477                exit; 
     
    16301628?> 
    16311629 
    16321630<script type="text/javascript"> 
    1633 <!-- 
    16341631jQuery(function($){ 
    16351632        var preloaded = $(".media-item.preloaded"); 
    16361633        if ( preloaded.length > 0 ) { 
     
    16381635                updateMediaForm(); 
    16391636        } 
    16401637}); 
    1641 --> 
    16421638</script> 
    16431639<div id="sort-buttons" class="hide-if-no-js"> 
    16441640<span> 
  • wp-admin/js/gallery.dev.js

     
    6060                w = wpgallery.getWin(); 
    6161 
    6262                $('#save-all, #gallery-settings').show(); 
    63                 if ( typeof w.tinyMCE != 'undefined' && w.tinyMCE.activeEditor && ! w.tinyMCE.activeEditor.isHidden() ) { 
    64                         wpgallery.mcemode = true; 
    65                         wpgallery.init(); 
     63                if ( typeof w.tinymce != 'undefined' && w.tinymce.activeEditor && ! w.tinymce.activeEditor.isHidden() ) { 
     64                        wpgallery.init(true); 
    6665                } else { 
    6766                        $('#insert-gallery').show(); 
    6867                } 
     
    7473/* gallery settings */ 
    7574var tinymce = null, tinyMCE, wpgallery; 
    7675 
     76(function($){ 
    7777wpgallery = { 
    7878        mcemode : false, 
    7979        editor : {}, 
    8080        dom : {}, 
    8181        is_update : false, 
    8282        el : {}, 
     83        args : '', 
    8384 
    84         I : function(e) { 
    85                 return document.getElementById(e); 
    86         }, 
     85        init: function(mcemode) { 
     86                var t = this, query, args = {}, i, val, w = t.getWin(); 
    8787 
    88         init: function() { 
    89                 var t = this, li, q, i, it, w = t.getWin(); 
     88                if ( mcemode ) 
     89                        t.mcemode = true; 
     90                else 
     91                        return; 
    9092 
    91                 if ( ! t.mcemode ) return; 
     93                query = ('' + document.location.search).replace(/^\?/, '').split('&'); 
    9294 
    93                 li = ('' + document.location.search).replace(/^\?/, '').split('&'); 
    94                 q = {}; 
    95                 for (i=0; i<li.length; i++) { 
    96                         it = li[i].split('='); 
    97                         q[unescape(it[0])] = unescape(it[1]); 
     95                for ( i in query ) { 
     96                        if ( query[i] ) { 
     97                                val = query[i].split('='); 
     98                                args[decodeURIComponent(val[0])] = decodeURIComponent(val[1]); 
     99                        } 
    98100                } 
    99101 
    100                 if (q.mce_rdomain) 
    101                         document.domain = q.mce_rdomain; 
    102  
    103102                // Find window & API 
    104103                tinymce = w.tinymce; 
    105104                tinyMCE = w.tinyMCE; 
    106105                t.editor = tinymce.EditorManager.activeEditor; 
     106                t.args = args; 
    107107 
    108108                t.setup(); 
    109109        }, 
     
    113113        }, 
    114114 
    115115        setup : function() { 
    116                 var t = this, a, ed = t.editor, g, columns, link, order, orderby; 
    117                 if ( ! t.mcemode ) return; 
     116                var t = this, shortcode = t.args.shortcode, sh, a, ed = t.editor, g, columns, link, order, orderby, val; 
     117                 
     118                if ( ! t.mcemode ) 
     119                        return; 
    118120 
    119                 t.el = ed.selection.getNode(); 
     121                if ( shortcode ) { 
     122                        $('#update-gallery').show(); 
     123                        t.is_update = true; 
    120124 
    121                 if ( t.el.nodeName != 'IMG' || ! ed.dom.hasClass(t.el, 'wpGallery') ) { 
    122                         if ( (g = ed.dom.select('img.wpGallery')) && g[0] ) { 
    123                                 t.el = g[0]; 
    124                         } else { 
    125                                 if ( getUserSetting('galfile') == '1' ) t.I('linkto-file').checked = "checked"; 
    126                                 if ( getUserSetting('galdesc') == '1' ) t.I('order-desc').checked = "checked"; 
    127                                 if ( getUserSetting('galcols') ) t.I('columns').value = getUserSetting('galcols'); 
    128                                 if ( getUserSetting('galord') ) t.I('orderby').value = getUserSetting('galord'); 
    129                                 jQuery('#insert-gallery').show(); 
    130                                 return; 
    131                         } 
     125                        columns = shortcode.match(/columns=['"]([0-9]+)['"]/); 
     126                        link = shortcode.match(/link=['"]([^'"]+)['"]/i); 
     127                        order = shortcode.match(/order=['"]([^'"]+)['"]/i); 
     128                        orderby = shortcode.match(/orderby=['"]([^'"]+)['"]/i); 
     129 
     130                        // console.log( columns );console.log( link );console.log( order );console.log( orderby ); 
     131                } else { 
     132                        $('#insert-gallery').show(); 
    132133                } 
     134                 
     135                // If inserting new gallery, use the user states, if editing a gallery, use defaults + shortcode 
     136                if ( ( ! t.is_update && getUserSetting('galfile') ) || ( link && link[1] ) ) 
     137                        $('#linkto-file').prop('checked', true); 
    133138 
    134                 a = ed.dom.getAttrib(t.el, 'title'); 
    135                 a = ed.dom.decode(a); 
     139                if ( ( ! t.is_update && getUserSetting('galdesc') ) || ( order && order[1] ) ) 
     140                        $('#order-desc').prop('checked', true); 
    136141 
    137                 if ( a ) { 
    138                         jQuery('#update-gallery').show(); 
    139                         t.is_update = true; 
     142                if ( columns && columns[1] ) 
     143                        $('#columns').val( columns[1] ); 
     144                else if ( ! t.is_update && ( val = getUserSetting('galcols') ) ) 
     145                        $('#columns').val( val ); 
    140146 
    141                         columns = a.match(/columns=['"]([0-9]+)['"]/); 
    142                         link = a.match(/link=['"]([^'"]+)['"]/i); 
    143                         order = a.match(/order=['"]([^'"]+)['"]/i); 
    144                         orderby = a.match(/orderby=['"]([^'"]+)['"]/i); 
    145  
    146                         if ( link && link[1] ) t.I('linkto-file').checked = "checked"; 
    147                         if ( order && order[1] ) t.I('order-desc').checked = "checked"; 
    148                         if ( columns && columns[1] ) t.I('columns').value = ''+columns[1]; 
    149                         if ( orderby && orderby[1] ) t.I('orderby').value = orderby[1]; 
    150                 } else { 
    151                         jQuery('#insert-gallery').show(); 
    152                 } 
     147                if ( orderby && orderby[1] ) 
     148                        $('#orderby').val( orderby[1] ); 
     149                else if ( ! t.is_update && ( val = getUserSetting('galord') ) ) 
     150                        $('#orderby').val( val ); 
    153151        }, 
    154152 
    155153        update : function() { 
    156                 var t = this, ed = t.editor, all = '', s; 
     154                var t = this, ed = t.editor, args = t.args, div, new_div, new_div_id, sh = '[gallery'+t.getSettings()+']'; 
    157155 
    158156                if ( ! t.mcemode || ! t.is_update ) { 
    159                         s = '[gallery'+t.getSettings()+']'; 
    160                         t.getWin().send_to_editor(s); 
     157                        t.getWin().send_to_editor(sh); 
    161158                        return; 
    162159                } 
    163160 
    164                 if (t.el.nodeName != 'IMG') return; 
     161                div = ed.dom.select('#'+args.div_id); 
    165162 
    166                 all = ed.dom.decode(ed.dom.getAttrib(t.el, 'title')); 
    167                 all = all.replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi, ''); 
    168                 all += t.getSettings(); 
     163                if ( div ) { 
     164                        new_div = ed.dom.create( 'div', {}, ed.wpSetGalleryPreview(sh) ); 
     165                        new_div = new_div.firstChild; 
     166                        ed.dom.replace( new_div, div ); 
     167                } 
    169168 
    170                 ed.dom.setAttrib(t.el, 'title', all); 
    171169                t.getWin().tb_remove(); 
    172170        }, 
    173171 
    174172        getSettings : function() { 
    175                 var I = this.I, s = ''; 
     173                var s = '', columns = $('#columns').val(), orderby = $('#orderby').val(); 
    176174 
    177                 if ( I('linkto-file').checked ) { 
     175                if ( $('#linkto-file').prop('checked') ) { 
    178176                        s += ' link="file"'; 
    179177                        setUserSetting('galfile', '1'); 
     178                } else { 
     179                        deleteUserSetting('galfile'); 
    180180                } 
    181181 
    182                 if ( I('order-desc').checked ) { 
     182                if ( $('#order-desc').prop('checked') ) { 
    183183                        s += ' order="DESC"'; 
    184184                        setUserSetting('galdesc', '1'); 
     185                } else { 
     186                        deleteUserSetting('galdesc'); 
    185187                } 
    186188 
    187                 if ( I('columns').value != 3 ) { 
    188                         s += ' columns="'+I('columns').value+'"'; 
    189                         setUserSetting('galcols', I('columns').value); 
     189                if ( columns != 3 ) { 
     190                        s += ' columns="'+columns+'"'; 
     191                        setUserSetting('galcols', columns); 
     192                } else { 
     193                        deleteUserSetting('galcols'); 
    190194                } 
    191195 
    192                 if ( I('orderby').value != 'menu_order' ) { 
    193                         s += ' orderby="'+I('orderby').value+'"'; 
    194                         setUserSetting('galord', I('orderby').value); 
     196                if ( orderby != 'menu_order' ) { 
     197                        s += ' orderby="'+orderby+'"'; 
     198                        setUserSetting('galord', orderby); 
     199                } else { 
     200                        deleteUserSetting('galord'); 
    195201                } 
    196202 
    197203                return s; 
    198204        } 
    199205}; 
     206})(jQuery); 
     207 
  • wp-includes/class-wp-editor.php

     
    167167                                self::$baseurl = includes_url('js/tinymce'); 
    168168                                self::$mce_locale = $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1 
    169169                                $no_captions = (bool) apply_filters( 'disable_captions', '' ); 
    170                                 $plugins = array( 'inlinepopups', 'spellchecker', 'tabfocus', 'paste', 'media', 'fullscreen', 'wordpress', 'wpeditimage', 'wpgallery', 'wplink', 'wpdialogs' ); 
     170                                $plugins = array( 'inlinepopups', 'spellchecker', 'tabfocus', 'paste', 'media', 'fullscreen', 'noneditable', 'wordpress', 'wpeditimage', 'wpgallery', 'wplink', 'wpdialogs' ); 
    171171                                $first_run = true; 
    172172                                $ext_plugins = ''; 
    173173 
  • wp-includes/css/editor.dev.css

     
    102102        font-size: 12px; 
    103103        line-height: 16px; 
    104104        padding: 0 0 0 8px; 
    105         overflow: visible; 
     105        overflow: hidden; 
    106106        height: 20px; 
    107107        border-top: 1px solid #dfdfdf; 
    108108        color: #000; 
    109109        background-color: #f5f5f5; 
     110        position: relative; 
    110111} 
    111112 
    112113.rtl .wp_themeSkin .mceStatusbar { 
     
    120121.wp_themeSkin .mceStatusbar div { 
    121122        float: left; 
    122123        padding: 2px; 
     124        overflow: hidden; 
     125    position: absolute; 
     126    width: 97%; 
    123127} 
    124128 
    125129.rtl .wp_themeSkin .mceStatusbar div { 
  • wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js

     
     1(function(){var c=tinymce.dom.TreeWalker;var a="contenteditable",d="data-mce-"+a;var e=tinymce.VK;function b(n){var j=n.dom,p=n.selection,r,o="mce_noneditablecaret";r=tinymce.isGecko?"\u200B":"\uFEFF";function m(t){var s;if(t.nodeType===1){s=t.getAttribute(d);if(s&&s!=="inherit"){return s}s=t.contentEditable;if(s!=="inherit"){return s}}return null}function g(s){var t;while(s){t=m(s);if(t){return t==="false"?s:null}s=s.parentNode}}function l(s){while(s){if(s.id===o){return s}s=s.parentNode}}function k(s){var t;if(s){t=new c(s,s);for(s=t.current();s;s=t.next()){if(s.nodeType===3){return s}}}}function f(v,u){var s,t;if(m(v)==="false"){if(j.isBlock(v)){p.select(v);return}}t=j.createRng();if(m(v)==="true"){if(!v.firstChild){v.appendChild(n.getDoc().createTextNode("\u00a0"))}v=v.firstChild;u=true}s=j.create("span",{id:o,"data-mce-bogus":true},r);if(u){v.parentNode.insertBefore(s,v)}else{j.insertAfter(s,v)}t.setStart(s.firstChild,1);t.collapse(true);p.setRng(t);return s}function i(s){var v,t,u;if(s){rng=p.getRng(true);rng.setStartBefore(s);rng.setEndBefore(s);v=k(s);if(v&&v.nodeValue.charAt(0)==r){v=v.deleteData(0,1)}j.remove(s,true);p.setRng(rng)}else{t=l(p.getStart());while((s=j.get(o))&&s!==u){if(t!==s){v=k(s);if(v&&v.nodeValue.charAt(0)==r){v=v.deleteData(0,1)}j.remove(s,true)}u=s}}}function q(){var s,w,u,t,v;function x(B,D){var A,F,E,C,z;A=t.startContainer;F=t.startOffset;if(A.nodeType==3){z=A.nodeValue.length;if((F>0&&F<z)||(D?F==z:F==0)){return}}else{if(F<A.childNodes.length){var G=!D&&F>0?F-1:F;A=A.childNodes[G];if(A.hasChildNodes()){A=A.firstChild}}else{return !D?B:null}}E=new c(A,B);while(C=E[D?"prev":"next"]()){if(C.nodeType===3&&C.nodeValue.length>0){return}else{if(m(C)==="true"){return C}}}return B}i();u=p.isCollapsed();s=g(p.getStart());w=g(p.getEnd());if(s||w){t=p.getRng(true);if(u){s=s||w;var y=p.getStart();if(v=x(s,true)){f(v,true)}else{if(v=x(s,false)){f(v,false)}else{p.select(s)}}}else{t=p.getRng(true);if(s){t.setStartBefore(s)}if(w){t.setEndAfter(w)}p.setRng(t)}}}function h(z,B){var F=B.keyCode,x,C,D,v;function u(H,G){while(H=H[G?"previousSibling":"nextSibling"]){if(H.nodeType!==3||H.nodeValue.length>0){return H}}}function y(G,H){p.select(G);p.collapse(H)}function t(K){var J,I,M,H;function G(O){var N=I;while(N){if(N===O){return}N=N.parentNode}j.remove(O);q()}function L(){var O,P,N=z.schema.getNonEmptyElements();P=new tinymce.dom.TreeWalker(I,z.getBody());while(O=(K?P.prev():P.next())){if(N[O.nodeName.toLowerCase()]){break}if(O.nodeType===3&&tinymce.trim(O.nodeValue).length>0){break}if(m(O)==="false"){G(O);return true}}if(g(O)){return true}return false}if(p.isCollapsed()){J=p.getRng(true);I=J.startContainer;M=J.startOffset;I=l(I)||I;if(H=g(I)){G(H);return false}if(I.nodeType==3&&(K?M>0:M<I.nodeValue.length)){return true}if(I.nodeType==1){I=I.childNodes[M]||I}if(L()){return false}}return true}D=p.getStart();v=p.getEnd();x=g(D)||g(v);if(x&&(F<112||F>124)&&F!=e.DELETE&&F!=e.BACKSPACE){if((tinymce.isMac?B.metaKey:B.ctrlKey)&&(F==67||F==88||F==86)){return}B.preventDefault();if(F==e.LEFT||F==e.RIGHT){var w=F==e.LEFT;if(z.dom.isBlock(x)){var A=w?x.previousSibling:x.nextSibling;var s=new c(A,A);var E=w?s.prev():s.next();y(E,!w)}else{y(x,w)}}}else{if(F==e.LEFT||F==e.RIGHT||F==e.BACKSPACE||F==e.DELETE){C=l(D);if(C){if(F==e.LEFT||F==e.BACKSPACE){x=u(C,true);if(x&&m(x)==="false"){B.preventDefault();if(F==e.LEFT){y(x,true)}else{j.remove(x);return}}else{i(C)}}if(F==e.RIGHT||F==e.DELETE){x=u(C);if(x&&m(x)==="false"){B.preventDefault();if(F==e.RIGHT){y(x,false)}else{j.remove(x);return}}else{i(C)}}}if((F==e.BACKSPACE||F==e.DELETE)&&!t(F==e.BACKSPACE)){B.preventDefault();return false}}}}n.onMouseDown.addToTop(function(s,u){var t=s.selection.getNode();if(m(t)==="false"&&t==u.target){q()}});n.onMouseUp.addToTop(q);n.onKeyDown.addToTop(h);n.onKeyUp.addToTop(q)}tinymce.create("tinymce.plugins.NonEditablePlugin",{init:function(i,k){var h,g,j;function f(m,n){var o=j.length,p=n.content,l=tinymce.trim(g);if(n.format=="raw"){return}while(o--){p=p.replace(j[o],function(s){var r=arguments,q=r[r.length-2];if(q>0&&p.charAt(q-1)=='"'){return s}return'<span class="'+l+'" data-mce-content="'+m.dom.encode(r[0])+'">'+m.dom.encode(typeof(r[1])==="string"?r[1]:r[0])+"</span>"})}n.content=p}h=" "+tinymce.trim(i.getParam("noneditable_editable_class","mceEditable"))+" ";g=" "+tinymce.trim(i.getParam("noneditable_noneditable_class","mceNonEditable"))+" ";j=i.getParam("noneditable_regexp");if(j&&!j.length){j=[j]}i.onPreInit.add(function(){b(i);if(j){i.selection.onBeforeSetContent.add(f);i.onBeforeSetContent.add(f)}i.parser.addAttributeFilter("class",function(l){var m=l.length,n,o;while(m--){o=l[m];n=" "+o.attr("class")+" ";if(n.indexOf(h)!==-1){o.attr(d,"true")}else{if(n.indexOf(g)!==-1){o.attr(d,"false")}}}});i.serializer.addAttributeFilter(d,function(l,m){var n=l.length,o;while(n--){o=l[n];if(j&&o.attr("data-mce-content")){o.name="#text";o.type=3;o.raw=true;o.value=o.attr("data-mce-content")}else{o.attr(a,null);o.attr(d,null)}}});i.parser.addAttributeFilter(a,function(l,m){var n=l.length,o;while(n--){o=l[n];o.attr(d,o.attr(a));o.attr(a,null)}})})},getInfo:function(){return{longname:"Non editable elements",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("noneditable",tinymce.plugins.NonEditablePlugin)})(); 
     2 No newline at end of file 
  • wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js

  • wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js

    Property changes on: wp-includes/js/tinymce/plugins/noneditable/editor_plugin.js
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
    \ No newline at end of property
     
     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 TreeWalker = tinymce.dom.TreeWalker; 
     13        var externalName = 'contenteditable', internalName = 'data-mce-' + externalName; 
     14        var VK = tinymce.VK; 
     15 
     16        function handleContentEditableSelection(ed) { 
     17                var dom = ed.dom, selection = ed.selection, invisibleChar, caretContainerId = 'mce_noneditablecaret'; 
     18 
     19                // Setup invisible character use zero width space on Gecko since it doesn't change the height of the container 
     20                invisibleChar = '\uFEFF'; 
     21 
     22                // Returns the content editable state of a node "true/false" or null 
     23                function getContentEditable(node) { 
     24                        var contentEditable; 
     25 
     26                        // Ignore non elements 
     27                        if (node.nodeType === 1) { 
     28                                // Check for fake content editable 
     29                                contentEditable = node.getAttribute(internalName); 
     30                                if (contentEditable && contentEditable !== "inherit") { 
     31                                        return contentEditable; 
     32                                } 
     33 
     34                                // Check for real content editable 
     35                                contentEditable = node.contentEditable; 
     36                                if (contentEditable !== "inherit") { 
     37                                        return contentEditable; 
     38                                } 
     39                        } 
     40 
     41                        return null; 
     42                }; 
     43 
     44                // Returns the noneditable parent or null if there is a editable before it or if it wasn't found 
     45                function getNonEditableParent(node) { 
     46                        var state; 
     47 
     48                        while (node) { 
     49                                state = getContentEditable(node); 
     50                                if (state) { 
     51                                        return state  === "false" ? node : null; 
     52                                } 
     53 
     54                                node = node.parentNode; 
     55                        } 
     56                }; 
     57 
     58                // Get caret container parent for the specified node 
     59                function getParentCaretContainer(node) { 
     60                        while (node) { 
     61                                if (node.id === caretContainerId) { 
     62                                        return node; 
     63                                } 
     64 
     65                                node = node.parentNode; 
     66                        } 
     67                }; 
     68 
     69                // Finds the first text node in the specified node 
     70                function findFirstTextNode(node) { 
     71                        var walker; 
     72 
     73                        if (node) { 
     74                                walker = new TreeWalker(node, node); 
     75 
     76                                for (node = walker.current(); node; node = walker.next()) { 
     77                                        if (node.nodeType === 3) { 
     78                                                return node; 
     79                                        } 
     80                                } 
     81                        } 
     82                }; 
     83 
     84                // Insert caret container before/after target or expand selection to include block 
     85                function insertCaretContainerOrExpandToBlock(target, before) { 
     86                        var caretContainer, rng; 
     87 
     88                        // Select block 
     89                        if (getContentEditable(target) === "false") { 
     90                                if (dom.isBlock(target)) { 
     91                                        selection.select(target); 
     92                                        return; 
     93                                } 
     94                        } 
     95 
     96                        rng = dom.createRng(); 
     97 
     98                        if (getContentEditable(target) === "true") { 
     99                                if (!target.firstChild) { 
     100                                        target.appendChild(ed.getDoc().createTextNode('\u00a0')); 
     101                                } 
     102 
     103                                target = target.firstChild; 
     104                                before = true; 
     105                        } 
     106 
     107                        //caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true, style:'border: 1px solid red'}, invisibleChar); 
     108                        caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true}, invisibleChar); 
     109 
     110                        if (before) { 
     111                                target.parentNode.insertBefore(caretContainer, target); 
     112                        } else { 
     113                                dom.insertAfter(caretContainer, target); 
     114                        } 
     115 
     116                        rng.setStart(caretContainer.firstChild, 1); 
     117                        rng.collapse(true); 
     118                        selection.setRng(rng); 
     119 
     120                        return caretContainer; 
     121                }; 
     122 
     123                // Removes any caret container except the one we might be in 
     124                function removeCaretContainer(caretContainer) { 
     125                        var child, currentCaretContainer, lastContainer; 
     126 
     127                        if (caretContainer) { 
     128                                        rng = selection.getRng(true); 
     129                                        rng.setStartBefore(caretContainer); 
     130                                        rng.setEndBefore(caretContainer); 
     131 
     132                                        child = findFirstTextNode(caretContainer); 
     133                                        if (child && child.nodeValue.charAt(0) == invisibleChar) { 
     134                                                child = child.deleteData(0, 1); 
     135                                        } 
     136 
     137                                        dom.remove(caretContainer, true); 
     138 
     139                                        selection.setRng(rng); 
     140                        } else { 
     141                                currentCaretContainer = getParentCaretContainer(selection.getStart()); 
     142                                while ((caretContainer = dom.get(caretContainerId)) && caretContainer !== lastContainer) { 
     143                                        if (currentCaretContainer !== caretContainer) { 
     144                                                child = findFirstTextNode(caretContainer); 
     145                                                if (child && child.nodeValue.charAt(0) == invisibleChar) { 
     146                                                        child = child.deleteData(0, 1); 
     147                                                } 
     148 
     149                                                dom.remove(caretContainer, true); 
     150                                        } 
     151 
     152                                        lastContainer = caretContainer; 
     153                                } 
     154                        } 
     155                }; 
     156 
     157                // Modifies the selection to include contentEditable false elements or insert caret containers 
     158                function moveSelection() { 
     159                        var nonEditableStart, nonEditableEnd, isCollapsed, rng, element; 
     160 
     161                        // Checks if there is any contents to the left/right side of caret returns the noneditable element or any editable element if it finds one inside 
     162                        function hasSideContent(element, left) { 
     163                                var container, offset, walker, node, len; 
     164 
     165                                container = rng.startContainer; 
     166                                offset = rng.startOffset; 
     167 
     168                                // If endpoint is in middle of text node then expand to beginning/end of element 
     169                                if (container.nodeType == 3) { 
     170                                        len = container.nodeValue.length; 
     171                                        if ((offset > 0 && offset < len) || (left ? offset == len : offset == 0)) { 
     172                                                return; 
     173                                        } 
     174                                } else { 
     175                                        // Can we resolve the node by index 
     176                                        if (offset < container.childNodes.length) { 
     177                                                // Browser represents caret position as the offset at the start of an element. When moving right 
     178                                                // this is the element we are moving into so we consider our container to be child node at offset-1 
     179                                                var pos = !left && offset > 0 ? offset-1 : offset; 
     180                                                container = container.childNodes[pos]; 
     181                                                if (container.hasChildNodes()) { 
     182                                                        container = container.firstChild; 
     183                                                } 
     184                                        } else { 
     185                                                // If not then the caret is at the last position in it's container and the caret container should be inserted after the noneditable element 
     186                                                return !left ? element : null; 
     187                                        } 
     188                                } 
     189 
     190                                // Walk left/right to look for contents 
     191                                walker = new TreeWalker(container, element); 
     192                                while (node = walker[left ? 'prev' : 'next']()) { 
     193                                        if (node.nodeType === 3 && node.nodeValue.length > 0) { 
     194                                                return; 
     195                                        } else if (getContentEditable(node) === "true") { 
     196                                                // Found contentEditable=true element return this one to we can move the caret inside it 
     197                                                return node; 
     198                                        } 
     199                                } 
     200 
     201                                return element; 
     202                        }; 
     203 
     204                        // Remove any existing caret containers 
     205                        removeCaretContainer(); 
     206 
     207                        // Get noneditable start/end elements 
     208                        isCollapsed = selection.isCollapsed(); 
     209                        nonEditableStart = getNonEditableParent(selection.getStart()); 
     210                        nonEditableEnd = getNonEditableParent(selection.getEnd()); 
     211 
     212                        // Is any fo the range endpoints noneditable 
     213                        if (nonEditableStart || nonEditableEnd) { 
     214                                rng = selection.getRng(true); 
     215 
     216                                // If it's a caret selection then look left/right to see if we need to move the caret out side or expand 
     217                                if (isCollapsed) { 
     218                                        nonEditableStart = nonEditableStart || nonEditableEnd; 
     219                                        var start = selection.getStart(); 
     220                                        if (element = hasSideContent(nonEditableStart, true)) { 
     221                                                // We have no contents to the left of the caret then insert a caret container before the noneditable element 
     222                                                insertCaretContainerOrExpandToBlock(element, true); 
     223                                        } else if (element = hasSideContent(nonEditableStart, false)) { 
     224                                                // We have no contents to the right of the caret then insert a caret container after the noneditable element 
     225                                                insertCaretContainerOrExpandToBlock(element, false); 
     226                                        } else { 
     227                                                // We are in the middle of a noneditable so expand to select it 
     228                                                selection.select(nonEditableStart); 
     229                                        } 
     230                                } else { 
     231                                        rng = selection.getRng(true); 
     232 
     233                                        // Expand selection to include start non editable element 
     234                                        if (nonEditableStart) { 
     235                                                rng.setStartBefore(nonEditableStart); 
     236                                        } 
     237 
     238                                        // Expand selection to include end non editable element 
     239                                        if (nonEditableEnd) { 
     240                                                rng.setEndAfter(nonEditableEnd); 
     241                                        } 
     242 
     243                                        selection.setRng(rng); 
     244                                } 
     245                        } 
     246                }; 
     247 
     248                function handleKey(ed, e) { 
     249                        var keyCode = e.keyCode, nonEditableParent, caretContainer, startElement, endElement; 
     250 
     251                        function getNonEmptyTextNodeSibling(node, prev) { 
     252                                while (node = node[prev ? 'previousSibling' : 'nextSibling']) { 
     253                                        if (node.nodeType !== 3 || node.nodeValue.length > 0) { 
     254                                                return node; 
     255                                        } 
     256                                } 
     257                        }; 
     258 
     259                        function positionCaretOnElement(element, start) { 
     260                                selection.select(element); 
     261                                selection.collapse(start); 
     262                        } 
     263 
     264                        function canDelete(backspace) { 
     265                                var rng, container, offset, nonEditableParent; 
     266 
     267                                function removeNodeIfNotParent(node) { 
     268                                        var parent = container; 
     269 
     270                                        while (parent) { 
     271                                                if (parent === node) { 
     272                                                        return; 
     273                                                } 
     274 
     275                                                parent = parent.parentNode; 
     276                                        } 
     277 
     278                                        dom.remove(node); 
     279                                        moveSelection(); 
     280                                } 
     281 
     282                                function isNextPrevTreeNodeNonEditable() { 
     283                                        var node, walker, nonEmptyElements = ed.schema.getNonEmptyElements(); 
     284 
     285                                        walker = new tinymce.dom.TreeWalker(container, ed.getBody()); 
     286                                        while (node = (backspace ? walker.prev() : walker.next())) { 
     287                                                // Found IMG/INPUT etc 
     288                                                if (nonEmptyElements[node.nodeName.toLowerCase()]) { 
     289                                                        break; 
     290                                                } 
     291 
     292                                                // Found text node with contents 
     293                                                if (node.nodeType === 3 && tinymce.trim(node.nodeValue).length > 0) { 
     294                                                        break; 
     295                                                } 
     296 
     297                                                // Found non editable node 
     298                                                if (getContentEditable(node) === "false") { 
     299                                                        removeNodeIfNotParent(node); 
     300                                                        return true; 
     301                                                } 
     302                                        } 
     303 
     304                                        // Check if the content node is within a non editable parent 
     305                                        if (getNonEditableParent(node)) { 
     306                                                return true; 
     307                                        } 
     308 
     309                                        return false; 
     310                                } 
     311 
     312                                if (selection.isCollapsed()) { 
     313                                        rng = selection.getRng(true); 
     314                                        container = rng.startContainer; 
     315                                        offset = rng.startOffset; 
     316                                        container = getParentCaretContainer(container) || container; 
     317 
     318                                        // Is in noneditable parent 
     319                                        if (nonEditableParent = getNonEditableParent(container)) { 
     320                                                removeNodeIfNotParent(nonEditableParent); 
     321                                                return false; 
     322                                        } 
     323 
     324                                        // Check if the caret is in the middle of a text node 
     325                                        if (container.nodeType == 3 && (backspace ? offset > 0 : offset < container.nodeValue.length)) { 
     326                                                return true; 
     327                                        } 
     328 
     329                                        // Resolve container index 
     330                                        if (container.nodeType == 1) { 
     331                                                container = container.childNodes[offset] || container; 
     332                                        } 
     333 
     334                                        // Check if previous or next tree node is non editable then block the event 
     335                                        if (isNextPrevTreeNodeNonEditable()) { 
     336                                                return false; 
     337                                        } 
     338                                } 
     339 
     340                                return true; 
     341                        } 
     342 
     343                        startElement = selection.getStart() 
     344                        endElement = selection.getEnd(); 
     345 
     346                        // Disable all key presses in contentEditable=false except delete or backspace 
     347                        nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement); 
     348                        if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) { 
     349                                // Is Ctrl+c, Ctrl+v or Ctrl+x then use default browser behavior 
     350                                if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) { 
     351                                        return; 
     352                                } 
     353 
     354                                e.preventDefault(); 
     355 
     356                                // Arrow left/right select the element and collapse left/right 
     357                                if (keyCode == VK.LEFT || keyCode == VK.RIGHT) { 
     358                                        var left = keyCode == VK.LEFT; 
     359                                        // If a block element find previous or next element to position the caret 
     360                                        if (ed.dom.isBlock(nonEditableParent)) { 
     361                                                var targetElement = left ? nonEditableParent.previousSibling : nonEditableParent.nextSibling; 
     362                                                var walker = new TreeWalker(targetElement, targetElement); 
     363                                                var caretElement = left ? walker.prev() : walker.next(); 
     364                                                positionCaretOnElement(caretElement, !left); 
     365                                        } else { 
     366                                                positionCaretOnElement(nonEditableParent, left); 
     367                                        } 
     368                                } 
     369                        } else { 
     370                                // Is arrow left/right, backspace or delete 
     371                                if (keyCode == VK.LEFT || keyCode == VK.RIGHT || keyCode == VK.BACKSPACE || keyCode == VK.DELETE) { 
     372                                        caretContainer = getParentCaretContainer(startElement); 
     373                                        if (caretContainer) { 
     374                                                // Arrow left or backspace 
     375                                                if (keyCode == VK.LEFT || keyCode == VK.BACKSPACE) { 
     376                                                        nonEditableParent = getNonEmptyTextNodeSibling(caretContainer, true); 
     377 
     378                                                        if (nonEditableParent && getContentEditable(nonEditableParent) === "false") { 
     379                                                                e.preventDefault(); 
     380 
     381                                                                if (keyCode == VK.LEFT) { 
     382                                                                        positionCaretOnElement(nonEditableParent, true); 
     383                                                                } else { 
     384                                                                        dom.remove(nonEditableParent); 
     385                                                                        return; 
     386                                                                } 
     387                                                        } else { 
     388                                                                removeCaretContainer(caretContainer); 
     389                                                        } 
     390                                                } 
     391 
     392                                                // Arrow right or delete 
     393                                                if (keyCode == VK.RIGHT || keyCode == VK.DELETE) { 
     394                                                        nonEditableParent = getNonEmptyTextNodeSibling(caretContainer); 
     395 
     396                                                        if (nonEditableParent && getContentEditable(nonEditableParent) === "false") { 
     397                                                                e.preventDefault(); 
     398 
     399                                                                if (keyCode == VK.RIGHT) { 
     400                                                                        positionCaretOnElement(nonEditableParent, false); 
     401                                                                } else { 
     402                                                                        dom.remove(nonEditableParent); 
     403                                                                        return; 
     404                                                                } 
     405                                                        } else { 
     406                                                                removeCaretContainer(caretContainer); 
     407                                                        } 
     408                                                } 
     409                                        } 
     410 
     411                                        if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) { 
     412                                                e.preventDefault(); 
     413                                                return false; 
     414                                        } 
     415                                } 
     416                        } 
     417                }; 
     418 
     419                ed.onMouseDown.addToTop(function(ed, e) { 
     420                        var node = ed.selection.getNode(); 
     421 
     422                        if (getContentEditable(node) === "false" && node == e.target) { 
     423                                // Expand selection on mouse down we can't block the default event since it's used for drag/drop 
     424                                moveSelection(); 
     425                        } 
     426                }); 
     427 
     428                ed.onMouseUp.addToTop(moveSelection); 
     429                ed.onKeyDown.addToTop(handleKey); 
     430                ed.onKeyUp.addToTop(moveSelection); 
     431        }; 
     432 
     433        tinymce.create('tinymce.plugins.NonEditablePlugin', { 
     434                init : function(ed, url) { 
     435                        var editClass, nonEditClass, nonEditableRegExps; 
     436 
     437                        // Converts configured regexps to noneditable span items 
     438                        function convertRegExpsToNonEditable(ed, args) { 
     439                                var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass); 
     440 
     441                                // Don't replace the variables when raw is used for example on undo/redo 
     442                                if (args.format == "raw") { 
     443                                        return; 
     444                                } 
     445 
     446                                while (i--) { 
     447                                        content = content.replace(nonEditableRegExps[i], function(match) { 
     448                                                var args = arguments, index = args[args.length - 2]; 
     449 
     450                                                // Is value inside an attribute then don't replace 
     451                                                if (index > 0 && content.charAt(index - 1) == '"') { 
     452                                                        return match; 
     453                                                } 
     454 
     455                                                return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>'; 
     456                                        }); 
     457                                } 
     458 
     459                                args.content = content; 
     460                        }; 
     461                         
     462                        editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " "; 
     463                        nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " "; 
     464 
     465                        // Setup noneditable regexps array 
     466                        nonEditableRegExps = ed.getParam("noneditable_regexp"); 
     467                        if (nonEditableRegExps && !nonEditableRegExps.length) { 
     468                                nonEditableRegExps = [nonEditableRegExps]; 
     469                        } 
     470 
     471                        ed.onPreInit.add(function() { 
     472                                handleContentEditableSelection(ed); 
     473 
     474                                if (nonEditableRegExps) { 
     475                                        ed.selection.onBeforeSetContent.add(convertRegExpsToNonEditable); 
     476                                        ed.onBeforeSetContent.add(convertRegExpsToNonEditable); 
     477                                } 
     478 
     479                                // Apply contentEditable true/false on elements with the noneditable/editable classes 
     480                                ed.parser.addAttributeFilter('class', function(nodes) { 
     481                                        var i = nodes.length, className, node; 
     482 
     483                                        while (i--) { 
     484                                                node = nodes[i]; 
     485                                                className = " " + node.attr("class") + " "; 
     486 
     487                                                if (className.indexOf(editClass) !== -1) { 
     488                                                        node.attr(internalName, "true"); 
     489                                                } else if (className.indexOf(nonEditClass) !== -1) { 
     490                                                        node.attr(internalName, "false"); 
     491                                                } 
     492                                        } 
     493                                }); 
     494 
     495                                // Remove internal name 
     496                                ed.serializer.addAttributeFilter(internalName, function(nodes, name) { 
     497                                        var i = nodes.length, node; 
     498 
     499                                        while (i--) { 
     500                                                node = nodes[i]; 
     501 
     502                                                if (nonEditableRegExps && node.attr('data-mce-content')) { 
     503                                                        node.name = "#text"; 
     504                                                        node.type = 3; 
     505                                                        node.raw = true; 
     506                                                        node.value = node.attr('data-mce-content'); 
     507                                                } else { 
     508                                                        node.attr(externalName, null); 
     509                                                        node.attr(internalName, null); 
     510                                                } 
     511                                        } 
     512                                }); 
     513 
     514                                // Convert external name into internal name 
     515                                ed.parser.addAttributeFilter(externalName, function(nodes, name) { 
     516                                        var i = nodes.length, node; 
     517 
     518                                        while (i--) { 
     519                                                node = nodes[i]; 
     520                                                node.attr(internalName, node.attr(externalName)); 
     521                                                node.attr(externalName, null); 
     522                                        } 
     523                                }); 
     524                        }); 
     525                }, 
     526 
     527                getInfo : function() { 
     528                        return { 
     529                                longname : 'Non editable elements', 
     530                                author : 'Moxiecode Systems AB', 
     531                                authorurl : 'http://tinymce.moxiecode.com', 
     532                                infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable', 
     533                                version : tinymce.majorVersion + "." + tinymce.minorVersion 
     534                        }; 
     535                } 
     536        }); 
     537 
     538        // Register plugin 
     539        tinymce.PluginManager.add('noneditable', tinymce.plugins.NonEditablePlugin); 
     540})(); 
  • wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js

  • wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js

    Property changes on: wp-includes/js/tinymce/plugins/noneditable/editor_plugin_src.js
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
    \ No newline at end of property
     
    11 
    22(function() { 
    33        tinymce.create('tinymce.plugins.wpGallery', { 
     4                sh : {i: 0}, 
    45 
    56                init : function(ed, url) { 
    6                         var t = this; 
     7                        var t = this, target; 
    78 
     9                        t.ed = ed; 
    810                        t.url = url; 
    911                        t._createButtons(); 
    1012 
    1113                        // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('...'); 
    1214                        ed.addCommand('WP_Gallery', function() { 
    13                                 var el = ed.selection.getNode(), post_id, vp = tinymce.DOM.getViewPort(), 
    14                                         H = vp.h - 80, W = ( 640 < vp.w ) ? 640 : vp.w; 
     15                                var shortcode, div_id, q_string, post_id, vp = tinymce.DOM.getViewPort(), H = vp.h - 80, W = ( 640 < vp.w ) ? 640 : vp.w; 
    1516 
    16                                 if ( el.nodeName != 'IMG' ) return; 
    17                                 if ( ed.dom.getAttrib(el, 'class').indexOf('wpGallery') == -1 ) return; 
     17                                div_id = target.id; 
     18                                shortcode = ed.dom.getAttrib( target, 'data-wp-gallery-args' ); // already urlencoded 
     19                                if ( !shortcode || !div_id ) 
     20                                        return; 
    1821 
    19                                 post_id = tinymce.DOM.get('post_ID').value; 
    20                                 tb_show('', tinymce.documentBaseURL + 'media-upload.php?post_id='+post_id+'&tab=gallery&TB_iframe=true&width='+W+'&height='+H); 
     22                                post_id = document.getElementById('post_ID'); 
     23                                post_id = post_id ? post_id.value : 0; 
     24                                q_string = 'post_id='+post_id+'&tab=gallery&shortcode='+shortcode+'&div_id='+encodeURIComponent(div_id)+'&TB_iframe=true&width='+W+'&height='+H; 
     25                                 
     26                                tb_show('', tinymce.documentBaseURL + 'media-upload.php?'+q_string); 
    2127 
    2228                                tinymce.DOM.setStyle( ['TB_overlay','TB_window','TB_load'], 'z-index', '999999' ); 
    2329                        }); 
    2430 
    2531                        ed.onMouseDown.add(function(ed, e) { 
    26                                 if ( e.target.nodeName == 'IMG' && ed.dom.hasClass(e.target, 'wpGallery') ) 
    27                                         ed.plugins.wordpress._showButtons(e.target, 'wp_gallerybtns'); 
     32                                target = ed.dom.getParent(e.target, 'div.wp-gallery-preview'); 
     33 
     34                                if ( target ) 
     35                                        ed.plugins.wordpress._showButtons(target, 'wp_gallerybtns'); 
    2836                        }); 
    2937 
    3038                        ed.onBeforeSetContent.add(function(ed, o) { 
    3139                                o.content = t._do_gallery(o.content); 
    3240                        }); 
    3341 
    34                         ed.onPostProcess.add(function(ed, o) { 
    35                                 if (o.get) 
    36                                         o.content = t._get_gallery(o.content); 
     42                        ed.onInit.add(function(ed){ 
     43                                // replace the gallery preview dom nodes in the dom copy that is being serialized 
     44                                ed.serializer.onPreProcess.add(function(ed, o) { 
     45                                        if ( o.get && o.save ) 
     46                                                t._remove_gallery_preview(); 
     47                                }); 
    3748                        }); 
    38                 }, 
    3949 
    40                 _do_gallery : function(co) { 
    41                         return co.replace(/\[gallery([^\]]*)\]/g, function(a,b){ 
    42                                 return '<img src="'+tinymce.baseURL+'/plugins/wpgallery/img/t.gif" class="wpGallery mceItem" title="gallery'+tinymce.DOM.encode(b)+'" />'; 
    43                         }); 
     50                        ed.wpSetGalleryPreview = function(content) { 
     51                                return t._do_gallery(content); 
     52                        } 
    4453                }, 
    4554 
    46                 _get_gallery : function(co) { 
     55                _do_gallery : function(content) { 
     56                        var self = this, ed = self.ed, dom = ed.dom, args, data, post_id, sh = self.sh; 
    4757 
    48                         function getAttr(s, n) { 
    49                                 n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s); 
    50                                 return n ? tinymce.DOM.decode(n[1]) : ''; 
     58                        if ( !content.match(/\[gallery[^\]]*\]/) ) 
     59                                return content; 
     60 
     61                        // post_ID is a hidden input field in edit-form-advanced.php 
     62                        post_id = document.getElementById('post_ID'); 
     63                        if ( post_id ) 
     64                                post_id = post_id.value; 
     65                        else 
     66                                return content; 
     67 
     68                        args = { 
     69                                url: ajaxurl, 
     70                                type: 'POST', 
     71                                content_type: 'application/x-www-form-urlencoded', 
     72                                success: function(r) { 
     73                                        var shortcode, div_id, new_id; 
     74 
     75                                        div_id = /^wp_gallery_shortcode_\d+/.exec(r); 
     76                                        shortcode = div_id && sh[div_id] ? sh[div_id] : ''; 
     77 
     78                                        if ( !div_id || !shortcode ) { 
     79                                                ed.setProgressState(false); 
     80                                                return; 
     81                                        } 
     82 
     83                                        div_id = div_id.toString(); 
     84                                        r = r.replace(div_id, ''); 
     85                                        // if there are any " even double entity encoded, switching Visual -> Text and back breaks it 
     86                                        shortcode = encodeURIComponent( shortcode ); 
     87                                        div = ed.dom.select('div#'+div_id); 
     88 
     89                                        if ( !div ) { 
     90                                                ed.setProgressState(false); 
     91                                                return; 
     92                                        } 
     93 
     94                                        new_id = 'wp_gallery_preview_' + div_id.replace(/[^0-9]+/, ''); 
     95                                        dom.setAttrib( div, 'id', new_id ); 
     96                                        dom.setAttrib( div, 'data-wp-gallery-args', shortcode ); 
     97                                        dom.addClass( div, 'wp-gallery-preview mceNonEditable' ); 
     98                                        dom.setHTML( div, r ); 
     99 
     100                                        ed.setProgressState(false); 
     101                                        ed.execCommand('mceRepaint'); 
     102                                }, 
     103                                error: function() { 
     104                                        ed.setProgressState(false); 
     105                                } 
    51106                        }; 
    52107 
    53                         return co.replace(/(?:<p[^>]*>)*(<img[^>]+>)(?:<\/p>)*/g, function(a,im) { 
    54                                 var cls = getAttr(im, 'class'); 
     108                        data = { 
     109                                action: 'mce-gallery-preview', 
     110                                post_ID: post_id 
     111                        }; 
    55112 
    56                                 if ( cls.indexOf('wpGallery') != -1 ) 
    57                                         return '<p>['+tinymce.trim(getAttr(im, 'title'))+']</p>'; 
     113                        ed.setProgressState(true); 
    58114 
    59                                 return a; 
     115                        return content.replace(/(?:<p>\s*)?(\[gallery[^\]]*\])(?:\s*<\/p>)?/g, function(a, shortcode){ 
     116                                var val, div_id, str = ''; 
     117 
     118                                sh.i++; 
     119                                div_id = 'wp_gallery_shortcode_' + sh.i; 
     120                                data['mcediv_id'] = div_id; 
     121                                sh[div_id] = shortcode; 
     122                                data['shortcode'] = shortcode; 
     123 
     124                                for ( val in data ) { 
     125                                        if ( str ) 
     126                                                str += '&'; 
     127 
     128                                        str += val + '=' + encodeURIComponent( data[val] ); 
     129                                } 
     130 
     131                                args['data'] = str; 
     132                                tinymce.util.XHR.send( args ); 
     133 
     134                                return '<div id="'+div_id+'">' + shortcode + '</div>'; 
    60135                        }); 
    61136                }, 
    62137 
     138                _remove_gallery_preview : function() { 
     139                        var ed = this.ed, dom = ed.dom, divs; 
     140 
     141                        divs = ed.dom.select('div.wp-gallery-preview'); 
     142                        if ( !divs ) 
     143                                return; 
     144 
     145                        tinymce.each( divs, function(el){ 
     146                                var p, args = dom.getAttrib( el, 'data-wp-gallery-args' ); 
     147 
     148                                args = args ? ' ' + decodeURIComponent(args) : ''; 
     149                                p = dom.create( 'p', {}, args ); 
     150                                dom.replace( p, el ); 
     151                        }); 
     152                }, 
     153 
    63154                _createButtons : function() { 
    64155                        var t = this, ed = tinyMCE.activeEditor, DOM = tinymce.DOM, editButton, dellButton; 
    65156 
  • wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css

     
    147147        height: 250px; 
    148148} 
    149149 
     150/* Gallery preview */ 
     151 
     152div.wp-gallery-preview { 
     153        margin: 10px auto; 
     154        -ms-user-select: none; 
     155        -moz-user-select: none; 
     156        -webkit-user-select: none; 
     157        user-select: none; 
     158} 
     159 
     160div.wp-gallery-preview .gallery-icon { 
     161        text-align: center; 
     162} 
     163 
     164div.wp-gallery-preview .gallery-icon img { 
     165        margin: 0; 
     166        padding: 0; 
     167        max-width: 90%; 
     168        height: auto; 
     169} 
     170 
     171div.wp-gallery-preview div.gallery { 
     172        clear: both; 
     173} 
     174 
     175div.wp-gallery-preview div.gallery dl.gallery-item { 
     176        float: left; 
     177        margin: 10px 0; 
     178        padding: 0; 
     179} 
     180 
     181div.wp-gallery-preview div.gallery-columns-1 dl.gallery-item { 
     182        width: 98%; 
     183} 
     184 
     185div.wp-gallery-preview div.gallery-columns-2 dl.gallery-item { 
     186        width: 49%; 
     187} 
     188 
     189div.wp-gallery-preview div.gallery-columns-3 dl.gallery-item { 
     190        width: 32%; 
     191} 
     192 
     193div.wp-gallery-preview div.gallery-columns-4 dl.gallery-item { 
     194        width: 24%; 
     195} 
     196 
     197div.wp-gallery-preview div.gallery-columns-5 dl.gallery-item { 
     198        width: 19%; 
     199} 
     200 
     201 
     202 
  • wp-includes/media.php

     
    780780        static $instance = 0; 
    781781        $instance++; 
    782782 
    783         // Allow plugins/themes to override the default gallery template. 
    784         $output = apply_filters('post_gallery', '', $attr); 
    785         if ( $output != '' ) 
    786                 return $output; 
     783        // Allow plugins/themes to override the default gallery template if not previewing. 
     784        if ( !isset($attr['mce_preview']) ) { 
     785                $output = apply_filters('post_gallery', '', $attr); 
     786                if ( $output != '' ) 
     787                        return $output; 
     788        } 
    787789 
    788790        // We're trusting author input, so let's at least make sure it looks like a valid orderby statement 
    789791        if ( isset( $attr['orderby'] ) ) { 
     
    792794                        unset( $attr['orderby'] ); 
    793795        } 
    794796 
    795         extract(shortcode_atts(array( 
     797        $attr = shortcode_atts( array( 
    796798                'order'      => 'ASC', 
    797799                'orderby'    => 'menu_order ID', 
    798                 'id'         => $post->ID, 
     800                'id'         => isset($post) ? $post->ID : 0, 
    799801                'itemtag'    => 'dl', 
    800802                'icontag'    => 'dt', 
    801803                'captiontag' => 'dd', 
    802804                'columns'    => 3, 
    803805                'size'       => 'thumbnail', 
    804806                'include'    => '', 
    805                 'exclude'    => '' 
    806         ), $attr)); 
     807                'exclude'    => '', 
     808                'mce_preview' => false, 
     809        ), $attr ); 
    807810 
     811        extract( $attr, EXTR_SKIP ); 
    808812        $id = intval($id); 
     813 
    809814        if ( 'RAND' == $order ) 
    810815                $orderby = 'none'; 
    811816 
     
    817822                foreach ( $_attachments as $key => $val ) { 
    818823                        $attachments[$val->ID] = $_attachments[$key]; 
    819824                } 
    820         } elseif ( !empty($exclude) ) { 
     825        } elseif ( !empty($exclude) && $id ) { 
    821826                $exclude = preg_replace( '/[^0-9,]+/', '', $exclude ); 
    822827                $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); 
    823         } else { 
     828        } elseif ( $id ) { 
    824829                $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); 
    825830        } 
    826831 
     
    834839                return $output; 
    835840        } 
    836841 
    837         $itemtag = tag_escape($itemtag); 
    838         $captiontag = tag_escape($captiontag); 
     842        if ( $mce_preview ) { 
     843                $itemtag = 'dl'; 
     844                $icontag = 'dt'; 
     845                $captiontag = 'dd'; 
     846        } else { 
     847                $itemtag = tag_escape($itemtag); 
     848                $captiontag = tag_escape($captiontag); 
     849        } 
     850 
    839851        $columns = intval($columns); 
    840852        $itemwidth = $columns > 0 ? floor(100/$columns) : 100; 
    841853        $float = is_rtl() ? 'right' : 'left'; 
     
    864876                </style> 
    865877                <!-- see gallery_shortcode() in wp-includes/media.php -->"; 
    866878        $size_class = sanitize_html_class( $size ); 
    867         $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>"; 
    868         $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div ); 
     879        $wrapper_id = $mce_preview ? '' : " id='$selector'"; 
     880        $gallery_div = "<div{$wrapper_id} class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>"; 
     881        $itemclass = 'gallery-item'; 
    869882 
     883        if ( $mce_preview ) { 
     884                $output = $mce_preview . $gallery_div; 
     885        } else { 
     886                $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div ); 
     887        } 
     888 
    870889        $i = 0; 
    871890        foreach ( $attachments as $id => $attachment ) { 
    872891                $link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false); 
    873892 
    874                 $output .= "<{$itemtag} class='gallery-item'>"; 
    875                 $output .= " 
    876                         <{$icontag} class='gallery-icon'> 
    877                                 $link 
    878                         </{$icontag}>"; 
     893                $output .= "\n<{$itemtag} class='$itemclass'><{$icontag} class='gallery-icon'>$link</{$icontag}>"; 
     894                 
    879895                if ( $captiontag && trim($attachment->post_excerpt) ) { 
    880                         $output .= " 
    881                                 <{$captiontag} class='wp-caption-text gallery-caption'> 
    882                                 " . wptexturize($attachment->post_excerpt) . " 
    883                                 </{$captiontag}>"; 
     896                        $output .= "<{$captiontag} class='wp-caption-text gallery-caption'>" 
     897                                . wptexturize($attachment->post_excerpt) . 
     898                                "</{$captiontag}>"; 
    884899                } 
     900 
    885901                $output .= "</{$itemtag}>"; 
     902 
    886903                if ( $columns > 0 && ++$i % $columns == 0 ) 
    887                         $output .= '<br style="clear: both" />'; 
     904                        $output .= "<br style='clear: both' />"; 
    888905        } 
    889906 
    890         $output .= " 
    891                         <br style='clear: both;' /> 
    892                 </div>\n"; 
     907        $output .= "<br style='clear: both;' /></div>\n"; 
    893908 
    894909        return $output; 
    895910}