Make WordPress Core

Changeset 22004


Ignore:
Timestamp:
09/26/2012 01:00:08 AM (14 years 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.