WordPress.org

Plugin Directory

Changeset 430741


Ignore:
Timestamp:
08/30/11 14:33:10 (3 years ago)
Author:
JohnPBloch
Message:

Add much better documentation to the editor plugin file. Dear future me: you're welcome.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • visual-shortcodes/trunk/visualshortcodes/editor_plugin.js

    r425210 r430741  
    11(function(){ 
     2    /* 
     3     * Create the TinyMCE plugin object. 
     4     *  
     5     * See http://www.tinymce.com/wiki.php/Creating_a_plugin for more information 
     6     * on how to create TinyMCE plugins. 
     7     */ 
    28    tinymce.create( 'tinymce.plugins.visualShortcodes', { 
     9         
     10        /* 
     11         * Create the function to initialize our plugin. We're going to set up all the 
     12         * properties necessary to function and then set some event handlers to make everything 
     13         * work properly. 
     14         *  
     15         * This function takes two arguments: 
     16         *  
     17         * ed: the Editor object (this code will run once for each editor on the page) 
     18         * url: the URL of the directory that this file resides in 
     19         */ 
    320        init : function( ed, url ){ 
     21             
     22            // A counter will help us assign unique ids to each shortcode in this editor. 
    423            this.counter = 0; 
     24             
     25            // Set up some variables 
    526            var t = this, 
    627                i, 
    728                shortcode, 
    829                names = []; 
     30             
     31            // Save the url in the object so that it's accessible elsewhere 
    932            t.url = url; 
    1033 
     34            // Pull in the shortcodes object that we stored in the internationalization object earlier 
    1135            t._shortcodes = tinymce.i18n['visualShortcode.shortcodes']; 
     36             
    1237            if( !t._shortcodes || undefined === t._shortcodes.length || 0 == t._shortcodes.length ){ 
     38                // If we don't have any shortcodes, we don't need to do anything else. Bail immediately. 
    1339                return; 
    1440            } 
     41             
     42            // Set up the shortcodes object and fill it with the shortcodes 
    1543            t.shortcodes = {}; 
    1644            for( i = 0, shortcode = t._shortcodes[i]; i < t._shortcodes.length; shortcode = t._shortcodes[++i]){ 
    1745                if(undefined === shortcode.shortcode || '' == shortcode.shortcode || undefined === shortcode.image || '' == shortcode.image){ 
     46                    /* 
     47                     * All shortcodes must have a non-empty string for the shortcode and image properties. 
     48                     * If those conditions are not met, skip to the next one. 
     49                     */ 
    1850                    continue; 
    1951                } 
     
    2254            } 
    2355            if( names.length < 1 ){ 
     56                // Again, if we don't have any valid shortcodes to work with, bail. 
    2457                return; 
    2558            } 
     
    2962            t._createButtons(); 
    3063 
     64            /* 
     65             * Add an event handler for our plugin on the 'mousedown' event. This sets up 
     66             * the handler to show our control buttons if the user clicks an image that 
     67             * represents a shortcode. 
     68             */ 
    3169            ed.onMouseDown.add(function( ed, e ){ 
     70                // We're only interested in images that have the right class 
    3271                if( e.target.nodeName == 'IMG' && ed.dom.hasClass(e.target, 'jpbVisualShortcode')){ 
     72                    // Get the name of the shortcode from the ID 
    3373                    var imgID = e.target.id.replace( /^vscImage\d+-(.+)$/, '$1' ); 
     74                    // Check if the shortcode has a command defined. If so... 
    3475                    if( undefined !== t.shortcodes[imgID] && undefined !== t.shortcodes[imgID].command ){ 
     76                        // Show both the delete and edit buttons. Otherwise... 
    3577                        ed.plugins.wordpress._showButtons(e.target, 'jpb_vscbuttons'); 
    3678                    } else { 
     79                        // Only show the delete button 
    3780                        ed.plugins.wordpress._showButtons(e.target, 'jpb_vscbutton'); 
    3881                    } 
    3982                } else { 
     83                    // If we're not clicking the right kind of image, hide the buttons just in case 
    4084                    t._hideButtons(); 
    4185                } 
    4286            }); 
    4387 
     88            /* 
     89             * Add an event handler for our plugin on the editor's 'change' event. This function 
     90             * replaces the shortcodes with their images and updates the content of the editor as 
     91             * the contents of the editor are being changed. 
     92             *  
     93             * The 'change' event fires each time there is an 'undo-able' block change made. 
     94             */ 
    4495            ed.onChange.add(function(ed, o){ 
    4596                if( !t.regex.test(o.content)){ 
     97                    /* 
     98                     * We shouldn't bother with changing anything and repainting the editor if we 
     99                     * don't even have a regex match on our shortcodes. 
     100                     */ 
    46101                    return; 
    47102                } 
     103                 
     104                // Get the updated content 
    48105                o.content = t._doScImage( o.content ); 
     106                // Set the new content 
    49107                ed.setContent(o.content); 
     108                // Repaint the editor 
    50109                ed.execCommand('mceRepaint'); 
    51110            }); 
    52111 
     112            /* 
     113             * Add an event handler for our plugin on the editor's 'beforesetcontent' event. This 
     114             * will swap the shortcode out for its image when the editor is initialized, or 
     115             * whenever switching from HTML to Visual mode. 
     116             */ 
    53117            ed.onBeforeSetContent.add(function(ed, o){ 
     118                if( !t.regex.test(o.content)){ 
     119                    /* 
     120                     * We shouldn't bother with changing anything and repainting the editor if we 
     121                     * don't even have a regex match on our shortcodes. 
     122                     */ 
     123                    return; 
     124                } 
     125                 
     126                /* 
     127                 * Honestly, I'm not sure why/how this works. We don't return anything and are 
     128                 * making the change directly on the object passed in as the second argument. How 
     129                 * does this change the content of the editor? I don't know. But it seems to work. 
     130                 *  
     131                 * For whatever reason, this does not require a full setting / repainting of the 
     132                 * editor's content like the function above. 
     133                 *  
     134                 * This code was borrowed from the WordPress gallery TinyMCE plugin. 
     135                 */ 
    54136                o.content = t._doScImage( o.content ); 
    55137            }); 
    56138 
     139            /* 
     140             * Add an event handler for our plugin on the editor's 'postprocess' event. This 
     141             * changes the images back to shortcodes before saving the content to the form field 
     142             * and when switching from Visual mode to HTML mode. 
     143             *  
     144             * This code was borrowed from the WordPress gallery TinyMCE plugin. 
     145             */ 
    57146            ed.onPostProcess.add(function(ed, o) { 
    58                 if( o.get ) 
     147                if( o.get ){ 
    59148                    o.content = t._getScImage( o.content ); 
    60             }); 
    61  
     149                } 
     150            }); 
     151 
     152            /* 
     153             * Add an event handler for the plugin on the editor's initialization event. This 
     154             * sets up some global event handlers to hide the buttons if the user scrolls or 
     155             * if they drag something with their mouse. 
     156             *  
     157             * This code was borrowed from the WordPress gallery TinyMCE plugin. 
     158             */ 
    62159            ed.onInit.add(function(ed) { 
     160                // Hide the buttons if the user scrolls 
    63161                tinymce.dom.Event.add(ed.getWin(), 'scroll', function(e) { 
    64162                    t._hideButtons(); 
    65163                }); 
     164                // Hide the buttons if the user drags something 
    66165                tinymce.dom.Event.add(ed.getBody(), 'dragstart', function(e) { 
    67166                    t._hideButtons(); 
     
    71170        }, 
    72171 
     172        /* 
     173         * Replace shortcodes with their respective images. 
     174         *  
     175         * For each match, the function will replace it with an image. The arguments correspond, 
     176         * respectively, to: 
     177         *  - the whole matched string (the whole shortcode, possibly wrapped in <p> tags) 
     178         *  - the name of the shortcode 
     179         *  - the arguments of the shortcode (could be an empty string) 
     180         *  
     181         * The id of the shortcode image will start with 'vscImage', followed by the current counter 
     182         * value (which is incremented as it's used, so next time it will be different), a hyphen, and  
     183         * the name of the shortcode. 
     184         *  
     185         * The class 'mceItem' prevents WordPress's normal image management icons from showing up when 
     186         * the image is clicked. 
     187         *  
     188         * The arguments of the shortcode are encoded and stored in the 'title' attribute of the image. 
     189         *  
     190         * This code is based largely on the WordPress gallery TinyMCE plugin. 
     191         */ 
    73192        _doScImage: function( co ){ 
    74193            var t = this; 
     
    78197        }, 
    79198 
     199        /* 
     200         * Replace images with their respective shortcodes. 
     201         *  
     202         * This code is based mostly on the WordPress gallery TinyMCE plugin. 
     203         */ 
    80204        _getScImage: function( co ){ 
    81205 
     206            // Used to grab the title/class attributes and decode them 
    82207            function getAttr(s, n) { 
    83208                n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s); 
     
    95220        }, 
    96221 
     222        /* 
     223         * Builds the plugin's shortcode for finding registered shortcodes 
     224         *  
     225         * The regex is global and case insensitive, and only searches for self-closing 
     226         * shortcodes. 
     227         */ 
    97228        _buildRegex: function( names ){ 
    98229            var t = this, 
     
    102233        }, 
    103234 
     235        /*  
     236         * Hide the buttons from the user! 
     237         */ 
    104238        _hideButtons: function(){ 
    105239            tinymce.DOM.hide('jpb_vscbuttons'); 
     
    107241        }, 
    108242 
     243        /*  
     244         * Creates the action buttons 
     245         *  
     246         * We need two sets of buttons: one for shortcodes that only get a delete button 
     247         * and one for shortcodes that get both a delete and an edit button. Set up the 
     248         * event handlers for all three of the buttons here too. 
     249         */ 
    109250        _createButtons: function(){ 
     251             
     252            // Initialize the variables we need/want 
    110253            var t = this, 
    111254                ed = tinyMCE.activeEditor, 
     
    114257                delbutton, 
    115258                delbutton2; 
     259                 
     260            // Remove extra copies of our buttons (in case we have multiple editors on the page) 
    116261            DOM.remove( 'jpb_vscbuttons' ); 
    117262            DOM.remove( 'jpb_vscbutton' ); 
    118263 
     264            /* 
     265             * Add the divs to hold the buttons and make sure they start their lives hidden. 
     266             * We have two button holder divs; the one with the id 'jpb_vscbuttons' will have 
     267             * both an edit and a delete button, whereas the one with the id 'jpb_vscbutton' 
     268             * will have only a delete button. 
     269             */ 
    119270            DOM.add( document.body, 'div', { 
    120271                id: 'jpb_vscbuttons', 
    121272                style: 'display:none;' 
    122273            }); 
    123  
    124274            DOM.add( document.body, 'div', { 
    125275                id: 'jpb_vscbutton', 
     
    127277            }); 
    128278 
     279            // Add the 'edit' button 
    129280            edbutton = DOM.add( 'jpb_vscbuttons', 'img', { 
    130281                src: t.url + '/img/edit.png', 
     
    135286            }); 
    136287 
     288            // Add the event handler for clicking the 'edit' button 
    137289            tinymce.dom.Event.add( edbutton, 'mousedown', function(e){ 
    138                 var ed = tinyMCE.activeEditor, el = ed.selection.getNode(), imgID = el.id.replace( /^vscImage\d+-(.+)$/, '$1' ); 
     290                // Initialize some variables 
     291                var ed = tinyMCE.activeEditor, 
     292                    el = ed.selection.getNode(), 
     293                    imgID = el.id.replace( /^vscImage\d+-(.+)$/, '$1' ); 
     294 
    139295                if( !imgID || undefined === t.shortcodes[imgID] || undefined === t.shortcodes[imgID].command ){ 
     296                    // We don't want to be here if we're not on a valid shortcode with a command 
    140297                    return; 
    141298                } 
     299                 
     300                // Execute the command 
    142301                ed.execCommand( t.shortcodes[imgID].command ); 
     302                // Hide the buttons 
    143303                t._hideButtons(); 
    144304            }); 
    145305 
     306            // Add the 'delete' button (to go with the 'edit' button) 
    146307            delbutton = DOM.add( 'jpb_vscbuttons', 'img', { 
    147308                src: t.url + '/img/delete.png', 
     
    152313            }); 
    153314 
     315            // Add the 'delete' button (to go by itself) 
    154316            delbutton2 = DOM.add( 'jpb_vscbutton', 'img', { 
    155317                src: t.url + '/img/delete.png', 
     
    160322            }); 
    161323 
     324            // Add an event handler for both delete buttons to delete the image on click 
    162325            tinymce.dom.Event.add( [ delbutton, delbutton2 ], 'mousedown', function(e){ 
    163326                var ed = tinyMCE.activeEditor, el = ed.selection.getNode(), el2; 
    164327                if( el.nodeName == 'IMG' && ed.dom.hasClass( el, 'jpbVisualShortcode' ) ){ 
     328                    // If we have the right kind of image selected, go about deleting it. 
     329                    // Grab the parent node ahead of time. 
    165330                    el2 = el.parentNode; 
     331                    // Get rid of the element 
    166332                    ed.dom.remove( el ); 
     333                    // Repaint the editor, just in case. 
    167334                    ed.execCommand( 'mceRepaint' ); 
     335                    // Hide the buttons 
    168336                    t._hideButtons(); 
     337                    // Select the parent element 
    169338                    ed.selection.select(el2); 
     339                    // Prevent bubbling. 
    170340                    return false; 
    171341                } 
     
    175345    }); 
    176346 
     347    // Add the plugin object to the TinyMCE plugin manager 
    177348    tinymce.PluginManager.add( 'visualshortcodes', tinymce.plugins.visualShortcodes ); 
     349     
    178350})(); 
    179  
Note: See TracChangeset for help on using the changeset viewer.