WordPress.org

Make WordPress Core

Changeset 22004


Ignore:
Timestamp:
09/26/12 01:00:08 (19 months ago)
Author:
koopersmith
Message:

Add JavaScript methods for handling shortcodes.

Adds wp.shortcode, a set of methods used for parsing shortcodes out of content. Also adds a default set of shortcode properties to wp.mce.view.

fixes #21996, see #21812, #21813, #21815.

Location:
trunk/wp-includes
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/js/mce-view.js

    r21962 r22004  
     1// Ensure the global `wp` object exists. 
    12if ( typeof wp === 'undefined' ) 
    23    var wp = {}; 
     
    67        instances = {}; 
    78 
    8     wp.mce = {}; 
    9  
     9    // Create the `wp.mce` object if necessary. 
     10    wp.mce = wp.mce || {}; 
     11 
     12    // wp.mce.view 
     13    // ----------- 
     14    // 
     15    // A set of utilities that simplifies adding custom UI within a TinyMCE editor. 
     16    // At its core, it serves as a series of converters, transforming text to a 
     17    // custom UI, and back again. 
    1018    wp.mce.view = { 
     19        // ### defaults 
    1120        // The default properties used for the objects in `wp.mce.view.add()`. 
    1221        defaults: { 
     
    1423            text: function( instance ) { 
    1524                return instance.options.original; 
     25            }, 
     26 
     27            toView: function( content ) { 
     28                if ( ! this.pattern ) 
     29                    return; 
     30 
     31                this.pattern.lastIndex = 0; 
     32                var match = this.pattern.exec( content ); 
     33 
     34                if ( ! match ) 
     35                    return; 
     36 
     37                return { 
     38                    index:   match.index, 
     39                    content: match[0], 
     40                    options: { 
     41                        original: match[0], 
     42                        results:  _.toArray( arguments ) 
     43                    } 
     44                }; 
    1645            } 
    1746        }, 
    1847 
     48        shortcode: { 
     49            view: Backbone.View, 
     50            text: function( instance ) { 
     51                return instance.options.shortcode.text(); 
     52            }, 
     53 
     54            toView: function( content ) { 
     55                var match = wp.shortcode.next( this.tag, content ); 
     56 
     57                if ( ! match ) 
     58                    return; 
     59 
     60                return { 
     61                    index:   match.index, 
     62                    content: match.content, 
     63                    options: { 
     64                        shortcode: match.shortcode 
     65                    } 
     66                }; 
     67            } 
     68        }, 
     69 
     70        // ### add( id, options ) 
    1971        // Registers a new TinyMCE view. 
    2072        // 
     
    2375        // `options` accepts the following properties: 
    2476        // 
    25         // `pattern` is the regular expression used to scan the content and 
     77        // * `pattern` is the regular expression used to scan the content and 
    2678        // detect matching views. 
    2779        // 
    28         // `view` is a `Backbone.View` constructor. If a plain object is 
     80        // * `view` is a `Backbone.View` constructor. If a plain object is 
    2981        // provided, it will automatically extend the parent constructor 
    3082        // (usually `Backbone.View`). Views are instantiated when the `pattern` 
     
    3385        // capture groups, and the `viewType`, which is the constructor's `id`. 
    3486        // 
    35         // `extend` an existing view by passing in its `id`. The current 
     87        // * `extend` an existing view by passing in its `id`. The current 
    3688        // view will inherit all properties from the parent view, and if 
    3789        // `view` is set to a plain object, it will extend the parent `view` 
    3890        // constructor. 
    3991        // 
    40         // `text` is a method that accepts an instance of the `view` 
     92        // * `text` is a method that accepts an instance of the `view` 
    4193        // constructor and transforms it into a text representation. 
    4294        add: function( id, options ) { 
    43             var parent; 
    44  
    4595            // Fetch the parent view or the default options. 
    46             parent = options.extend ? wp.mce.view.get( options.extend ) : wp.mce.view.defaults; 
     96            var parent = options.extend ? wp.mce.view.get( options.extend ) : wp.mce.view.defaults; 
    4797 
    4898            // Extend the `options` object with the parent's properties. 
     
    59109        }, 
    60110 
     111        // ### get( id ) 
    61112        // Returns a TinyMCE view options object. 
    62113        get: function( id ) { 
     
    64115        }, 
    65116 
     117        // ### remove( id ) 
    66118        // Unregisters a TinyMCE view. 
    67119        remove: function( id ) { 
     
    69121        }, 
    70122 
     123        // ### toViews( content ) 
    71124        // Scans a `content` string for each view's pattern, replacing any 
    72125        // matches with wrapper elements, and creates a new view instance for 
     
    75128        // To render the views, call `wp.mce.view.render( scope )`. 
    76129        toViews: function( content ) { 
     130            var pieces = [ { content: content } ], 
     131                current; 
     132 
    77133            _.each( views, function( view, viewType ) { 
    78                 if ( ! view.pattern ) 
    79                     return; 
    80  
    81                 // Scan for matches. 
    82                 content = content.replace( view.pattern, function( match ) { 
    83                     var instance, id, tag; 
    84  
    85                     // Create a new view instance. 
    86                     instance = new view.view({ 
    87                         original: match, 
    88                         results:  _.toArray( arguments ), 
    89                         viewType: viewType 
    90                     }); 
    91  
    92                     // Use the view's `id` if it already exists. Otherwise, 
    93                     // create a new `id`. 
    94                     id = instance.el.id = instance.el.id || _.uniqueId('__wpmce-'); 
    95                     instances[ id ] = instance; 
    96  
    97                     // If the view is a span, wrap it in a span. 
    98                     tag = 'span' === instance.tagName ? 'span' : 'div'; 
    99  
    100                     return '<' + tag + ' class="wp-view-wrap" data-wp-view="' + id + '" contenteditable="false"></' + tag + '>'; 
     134                current = pieces.slice(); 
     135                pieces  = []; 
     136 
     137                _.each( current, function( piece ) { 
     138                    var remaining = piece.content, 
     139                        result; 
     140 
     141                    // Ignore processed pieces, but retain their location. 
     142                    if ( piece.processed ) { 
     143                        pieces.push( piece ); 
     144                        return; 
     145                    } 
     146 
     147                    // Iterate through the string progressively matching views 
     148                    // and slicing the string as we go. 
     149                    while ( remaining && (result = view.toView( remaining )) ) { 
     150                        // Any text before the match becomes an unprocessed piece. 
     151                        if ( result.index ) 
     152                            pieces.push({ content: remaining.substring( 0, result.index ) }); 
     153 
     154                        // Add the processed piece for the match. 
     155                        pieces.push({ 
     156                            content:   wp.mce.view.toView( viewType, result.options ), 
     157                            processed: true 
     158                        }); 
     159 
     160                        // Update the remaining content. 
     161                        remaining = remaining.slice( result.index + result.content.length ); 
     162                    } 
     163 
     164                    // There are no additional matches. If any content remains, 
     165                    // add it as an unprocessed piece. 
     166                    if ( remaining ) 
     167                        pieces.push({ content: remaining }); 
    101168                }); 
    102169            }); 
    103170 
    104             return content; 
    105         }, 
    106  
     171            return _.pluck( pieces, 'content' ).join(''); 
     172        }, 
     173 
     174        toView: function( viewType, options ) { 
     175            var view = wp.mce.view.get( viewType ), 
     176                instance, id, tag; 
     177 
     178            if ( ! view ) 
     179                return ''; 
     180 
     181            // Create a new view instance. 
     182            instance = new view.view( _.extend( options || {}, { 
     183                viewType: viewType 
     184            }) ); 
     185 
     186            // Use the view's `id` if it already exists. Otherwise, 
     187            // create a new `id`. 
     188            id = instance.el.id = instance.el.id || _.uniqueId('__wpmce-'); 
     189            instances[ id ] = instance; 
     190 
     191            // If the view is a span, wrap it in a span. 
     192            tag = 'span' === instance.tagName ? 'span' : 'div'; 
     193 
     194            return '<' + tag + ' class="wp-view-wrap" data-wp-view="' + id + '" contenteditable="false"></' + tag + '>'; 
     195        }, 
     196 
     197        // ### render( scope ) 
    107198        // Renders any view instances inside a DOM node `scope`. 
    108199        // 
     
    131222        }, 
    132223 
     224        // ### toText( content ) 
    133225        // Scans an HTML `content` string and replaces any view instances with 
    134226        // their respective text representations. 
  • trunk/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css

    r21961 r22004  
    143143 
    144144/* WordPress TinyMCE Previews */ 
    145 div.wp-preview-wrap { 
    146     display: inline; 
     145div.wp-view-wrap, 
     146div.wp-view { 
     147    display: inline-block; 
    147148} 
  • trunk/wp-includes/script-loader.php

    r21961 r22004  
    323323    ) ); 
    324324 
    325     $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'backbone', 'jquery' ), false, 1 ); 
     325    $scripts->add( 'shortcode', "/wp-includes/js/shortcode$suffix.js", array( 'underscore' ), false, 1 ); 
     326    $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'backbone', 'jquery' ), false, 1 ); 
    326327 
    327328    if ( is_admin() ) { 
Note: See TracChangeset for help on using the changeset viewer.