Make WordPress Core

Ticket #38748: image-edit.diff

File image-edit.diff, 19.2 KB (added by jjcomack, 8 years ago)
  • src/wp-admin/js/image-edit.js

    diff --git a/src/wp-admin/js/image-edit.js b/src/wp-admin/js/image-edit.js
    index 6af28dc..aa8c8d8 100644
    a b  
    11/* global imageEditL10n, ajaxurl, confirm */
     2/**
     3 * @summary   The functions necessary for editing images.
     4 *
     5 * @since     2.8.5
     6 */
    27
    38(function($) {
    4 var imageEdit = window.imageEdit = {
     9
     10        /**
     11         * Contains all the methods to initialise and control the image editor.
     12         *
     13         * @namespace imageEdit
     14         */
     15        var imageEdit = window.imageEdit = {
    516        iasapi : {},
    617        hold : {},
    718        postid : '',
    819        _view : false,
    920
     21        /**
     22         * @summary Converts a value to an integer.
     23         *
     24         * @memberof imageEdit
     25         * @since    2.8.5
     26         *
     27         * @param {number} f The float value should be converted.
     28         *
     29         * @return {number} The integer representation from the float value.
     30         */
    1031        intval : function(f) {
    1132                /*
    1233                 * Bitwise OR operator: one of the obscure ways to truncate floating point figures,
    var imageEdit = window.imageEdit = { 
    1435                 */
    1536                return f | 0;
    1637        },
    17 
     38        /**
     39         * @summary Adds the disabled attribute and class to a single form element
     40         *          or a field set.
     41         *
     42         * @memberof imageEdit
     43         * @since    2.9
     44         *
     45         * @param {jQuery}         el The element that should be modified.
     46         * @param {bool|number}    s  The state for the element. If set to true
     47         *                            the element is disabled,
     48         *                            else the element is enabled.
     49         *                            The function is sometimes called with a 0 or 1
     50         *                            instead of true or false.
     51         *
     52         * @returns {void}
     53         */
    1854        setDisabled : function( el, s ) {
    1955                /*
    2056                 * `el` can be a single form element or a fieldset. Before #28864, the disabled state on
    var imageEdit = window.imageEdit = { 
    2965                }
    3066        },
    3167
     68        /**
     69         * @summary Initializes the image editor.
     70         *
     71         * @memberof imageEdit
     72         * @since    2.9
     73         *
     74         * @param {number} postid The post id.
     75         *
     76         * @returns {void}
     77         */
    3278        init : function(postid) {
    3379                var t = this, old = $('#image-editor-' + t.postid),
    3480                        x = t.intval( $('#imgedit-x-' + postid).val() ),
    var imageEdit = window.imageEdit = { 
    4894                $('input[type="text"]', '#imgedit-panel-' + postid).keypress(function(e) {
    4995                        var k = e.keyCode;
    5096
     97                        // Key codes 37 till 40 are the arrow keys.
    5198                        if ( 36 < k && k < 41 ) {
    5299                                $(this).blur();
    53100                        }
    54101
     102                        // The key code 13 is the enter key.
    55103                        if ( 13 === k ) {
    56104                                e.preventDefault();
    57105                                e.stopPropagation();
    var imageEdit = window.imageEdit = { 
    60108                });
    61109        },
    62110
     111        /**
     112         * @summary Toggles the wait/load icon in the editor.
     113         *
     114         * @memberof imageEdit
     115         * @since    2.9
     116         *
     117         * @param {number} postid The post id.
     118         * @param {number} toggle Is 0 or 1, fades the icon in then 1 and out when 0.
     119         *
     120         * @returns {void}
     121         */
    63122        toggleEditor : function(postid, toggle) {
    64123                var wait = $('#imgedit-wait-' + postid);
    65124
    var imageEdit = window.imageEdit = { 
    70129                }
    71130        },
    72131
     132        /**
     133         * @summary Shows or hides the image edit help box.
     134         *
     135         * @memberof imageEdit
     136         * @since    2.9
     137         *
     138         * @param {HTMLElement} el The element to create the help window in.
     139         *
     140         * @returns {boolean} Always returns false.
     141         */
    73142        toggleHelp : function(el) {
    74143                var $el = $( el );
    75144                $el
    var imageEdit = window.imageEdit = { 
    79148                return false;
    80149        },
    81150
     151        /**
     152         * @summary Gets the value from the image edit target.
     153         *
     154         * The image edit target contains the image sizes where the (possible) changes
     155         * have to be applied to.
     156         *
     157         * @memberof imageEdit
     158         * @since    2.9
     159         *
     160         * @param {number} postid The post id.
     161         *
     162         * @returns {string} The value from the imagedit-save-target input field when available,
     163         *                   or 'full' when not available.
     164         */
    82165        getTarget : function(postid) {
    83166                return $('input[name="imgedit-target-' + postid + '"]:checked', '#imgedit-save-target-' + postid).val() || 'full';
    84167        },
    85168
     169        /**
     170         * @summary Recalculates the height or width and keeps the original aspect ratio.
     171         *
     172         * If the original image size is exceeded a red exclamation mark is shown.
     173         *
     174         * @memberof imageEdit
     175         * @since    2.9
     176         *
     177         * @param {number}         postid The current post id.
     178         * @param {number}         x      Is 0 when it applies the y-axis
     179         *                                and 1 when applicable for the x-axis.
     180         * @param {jQuery}         el     Element.
     181         *
     182         * @returns {void}
     183         */
    86184        scaleChanged : function( postid, x, el ) {
    87185                var w = $('#imgedit-scale-width-' + postid), h = $('#imgedit-scale-height-' + postid),
    88186                warn = $('#imgedit-scale-warn-' + postid), w1 = '', h1 = '';
    var imageEdit = window.imageEdit = { 
    106204                }
    107205        },
    108206
     207        /**
     208         * @summary Gets the selected aspect ratio.
     209         *
     210         * @memberof imageEdit
     211         * @since    2.9
     212         *
     213         * @param {number} postid The post id.
     214         *
     215         * @returns {string} The aspect ratio.
     216         */
    109217        getSelRatio : function(postid) {
    110218                var x = this.hold.w, y = this.hold.h,
    111219                        X = this.intval( $('#imgedit-crop-width-' + postid).val() ),
    var imageEdit = window.imageEdit = { 
    122230                return '1:1';
    123231        },
    124232
     233        /**
     234         * @summary Removes the last action from the image edit history
     235         * The history consist of (edit)actions performed on the image.
     236         *
     237         * @memberof imageEdit
     238         * @since    2.9
     239         *
     240         * @param {number} postid  The post id.
     241         * @param {number} setSize 0 or 1, when 1 the image resets to its original size.
     242         *
     243         * @returns {string} JSON string containing the history or an empty string if no history exists.
     244         */
    125245        filterHistory : function(postid, setSize) {
    126                 // apply undo state to history
     246                // Apply undo state to history.
    127247                var history = $('#imgedit-history-' + postid).val(), pop, n, o, i, op = [];
    128248
    129249                if ( history !== '' ) {
     250                        // Read the JSON string with the image edit history.
    130251                        history = JSON.parse(history);
    131252                        pop = this.intval( $('#imgedit-undone-' + postid).val() );
    132253                        if ( pop > 0 ) {
    var imageEdit = window.imageEdit = { 
    136257                                }
    137258                        }
    138259
     260                        // Reset size to it's original state.
    139261                        if ( setSize ) {
    140262                                if ( !history.length ) {
    141263                                        this.hold.w = this.hold.ow;
    var imageEdit = window.imageEdit = { 
    143265                                        return '';
    144266                                }
    145267
    146                                 // restore
     268                                // Restore original 'o'.
    147269                                o = history[history.length - 1];
     270
     271                                // c = 'crop', r = 'rotate', f = 'flip'
    148272                                o = o.c || o.r || o.f || false;
    149273
    150274                                if ( o ) {
     275                                        // fw = Full image width
    151276                                        this.hold.w = o.fw;
     277                                        // fh = Full image height
    152278                                        this.hold.h = o.fh;
    153279                                }
    154280                        }
    155281
    156                         // filter the values
     282                        // Filter the last step/action from the history.
    157283                        for ( n in history ) {
    158284                                i = history[n];
    159285                                if ( i.hasOwnProperty('c') ) {
    var imageEdit = window.imageEdit = { 
    168294                }
    169295                return '';
    170296        },
    171 
     297        /**
     298         * @summary Binds the necessary events to the image.
     299         *
     300         * When the image source is reloaded the image will be reloaded.
     301         *
     302         * @memberof imageEdit
     303         * @since    2.9
     304         *
     305         * @param {number}   postid   The post id.
     306         * @param {string}   nonce    The nonce to verify the request.
     307         * @param {function} callback Function executed when the image is loaded.
     308         *
     309         * @returns {void}
     310         */
    172311        refreshEditor : function(postid, nonce, callback) {
    173312                var t = this, data, img;
    174313
    var imageEdit = window.imageEdit = { 
    188327                                        t = imageEdit,
    189328                                        historyObj;
    190329
     330                                // Checks if there already is some image-edit history.
    191331                                if ( '' !== event.data.history ) {
    192332                                        historyObj = JSON.parse( event.data.history );
    193333                                        // If last executed action in history is a crop action.
    var imageEdit = window.imageEdit = { 
    230370                        })
    231371                        .attr('src', ajaxurl + '?' + $.param(data));
    232372        },
    233 
     373        /**
     374         * @summary Performs an image edit action.
     375         *
     376         * @memberof imageEdit
     377         * @since    2.9
     378         *
     379         * @param  {number}  postid The post id.
     380         * @param  {string}  nonce  The nonce to verify the request.
     381         * @param  {string}  action The action to perform on the image.
     382         *                          The possible actions are: "scale" and "restore".
     383         *
     384         * @returns {boolean|void} Executes a post request that refreshes the page
     385         *                         when the action is performed.
     386         *                         Returns false if a invalid action is given,
     387         *                         or when the action cannot be performed.
     388         */
    234389        action : function(postid, nonce, action) {
    235390                var t = this, data, w, h, fw, fh;
    236391
    var imageEdit = window.imageEdit = { 
    282437                });
    283438        },
    284439
     440        /**
     441         * @summary Stores the changes that are made to the image.
     442         *
     443         * @memberof imageEdit
     444         * @since    2.9
     445         *
     446         * @param {number}  postid   The post id to get the image from the database.
     447         * @param {string}  nonce    The nonce to verify the request.
     448         *
     449         * @returns {boolean|void}  If the actions are successfully saved a response message is shown.
     450         *                          Returns false if there is no image editing history,
     451         *                          thus there are not edit-actions performed on the image.
     452         */
    285453        save : function(postid, nonce) {
    286454                var data,
    287455                        target = this.getTarget(postid),
    var imageEdit = window.imageEdit = { 
    302470                        'context': $('#image-edit-context').length ? $('#image-edit-context').val() : null,
    303471                        'do': 'save'
    304472                };
    305 
     473                // Post the image edit data to the backend.
    306474                $.post(ajaxurl, data, function(r) {
     475                        // Read the response.
    307476                        var ret = JSON.parse(r);
    308477
     478                        // If a response is returned, close the editor and show an error.
    309479                        if ( ret.error ) {
    310480                                $('#imgedit-response-' + postid).html('<div class="error"><p>' + ret.error + '</p></div>');
    311481                                imageEdit.close(postid);
    var imageEdit = window.imageEdit = { 
    332502                });
    333503        },
    334504
     505        /**
     506         * @summary Creates the image edit window.
     507         *
     508         * @memberof imageEdit
     509         * @since    2.9
     510         *
     511         * @param {number} postid   The post id for the image.
     512         * @param {string} nonce    The nonce to verify the request.
     513         * @param {object} view     The image editor view to be used for the editing.
     514         *
     515         * @returns {void|promise} Either returns void if the button was already activated
     516         *                          or returns an instance of the image editor, wrapped in a promise.
     517         */
    335518        open : function( postid, nonce, view ) {
    336519                this._view = view;
    337520
    var imageEdit = window.imageEdit = { 
    376559                return dfd;
    377560        },
    378561
     562        /**
     563         * @summary Initializes the cropping tool and sets a default cropping selection.
     564         *
     565         * @memberof imageEdit
     566         * @since    2.9
     567         *
     568         * @param {number} postid The post id.
     569         *
     570         * @returns {void}
     571         */
    379572        imgLoaded : function(postid) {
    380573                var img = $('#image-preview-' + postid), parent = $('#imgedit-crop-' + postid);
    381574
    var imageEdit = window.imageEdit = { 
    386579                $( '.imgedit-wrap .imgedit-help-toggle' ).eq( 0 ).focus();
    387580        },
    388581
     582        /**
     583         * @summary Initializes the cropping tool.
     584         *
     585         * @memberof imageEdit
     586         * @since    2.9
     587         *
     588         * @param {number}      postid The post id.
     589         * @param {HTMLElement} image  The preview image.
     590         * @param {HTMLElement} parent The preview image container.
     591         *
     592         * @returns {void}
     593         */
    389594        initCrop : function(postid, image, parent) {
    390595                var t = this,
    391596                        selW = $('#imgedit-sel-width-' + postid),
    var imageEdit = window.imageEdit = { 
    400605                        minWidth: 3,
    401606                        minHeight: 3,
    402607
     608                        /**
     609                         * @summary Sets the CSS styles and binds events for locking the aspect ratio.
     610                         *
     611                         * @param {jQuery} img The preview image.
     612                         */
    403613                        onInit: function( img ) {
    404                                 // Ensure that the imgareaselect wrapper elements are position:absolute
     614                                // Ensure that the imgAreaSelect wrapper elements are position:absolute
    405615                                // (even if we're in a position:fixed modal)
    406616                                $img = $( img );
    407617                                $img.next().css( 'position', 'absolute' )
    408618                                        .nextAll( '.imgareaselect-outer' ).css( 'position', 'absolute' );
    409 
     619                                /**
     620                                 * @summary Binds mouse down event to the cropping container.
     621                                 *
     622                                 * @returns {void}
     623                                 */
    410624                                parent.children().mousedown(function(e){
    411625                                        var ratio = false, sel, defRatio;
    412626
    var imageEdit = window.imageEdit = { 
    422636                                });
    423637                        },
    424638
     639                        /**
     640                         * @summary Event triggered when starting a selection.
     641                         *
     642                         * @returns {void}
     643                         */
    425644                        onSelectStart: function() {
    426645                                imageEdit.setDisabled($('#imgedit-crop-sel-' + postid), 1);
    427646                        },
    428 
     647                        /**
     648                         * @summary Event triggered when the selection is ended.
     649                         *
     650                         * @param {object} img jQuery object representing the image.
     651                         * @param {object} c   The selection.
     652                         *
     653                         * @returns {object}
     654                         */
    429655                        onSelectEnd: function(img, c) {
    430656                                imageEdit.setCropSelection(postid, c);
    431657                        },
    432658
     659                        /**
     660                         * @summary Event triggered when the selection changed.
     661                         *
     662                         * @param {object} img jQuery object representing the image.
     663                         * @param {object} c   The selection.
     664                         *
     665                         * @returns {void}
     666                         */
    433667                        onSelectChange: function(img, c) {
    434668                                var sizer = imageEdit.hold.sizer;
    435669                                selW.val( imageEdit.round(c.width / sizer) );
    var imageEdit = window.imageEdit = { 
    438672                });
    439673        },
    440674
     675        /**
     676         * @summary Stores the current crop selection.
     677         *
     678         * @memberof imageEdit
     679         * @since    2.9
     680         *
     681         * @param {number} postid The post id.
     682         * @param {object} c      The selection.
     683         *
     684         * @returns {boolean}
     685         */
    441686        setCropSelection : function(postid, c) {
    442687                var sel;
    443688
    var imageEdit = window.imageEdit = { 
    457702                $('#imgedit-selection-' + postid).val( JSON.stringify(sel) );
    458703        },
    459704
     705
     706        /**
     707         * @summary Closes the image editor.
     708         *
     709         * @memberof imageEdit
     710         * @since    2.9
     711         *
     712         * @param {number}  postid The post id.
     713         * @param {bool}    warn   Warning message.
     714         *
     715         * @returns {void|bool} Returns false if there is a warning.
     716         */
    460717        close : function(postid, warn) {
    461718                warn = warn || false;
    462719
    var imageEdit = window.imageEdit = { 
    487744
    488745        },
    489746
     747        /**
     748         * @summary Checks if the image edit history is saved.
     749         *
     750         * @memberof imageEdit
     751         * @since    2.9
     752         *
     753         * @param {number} postid The post id.
     754         *
     755         * @returns {boolean} Returns true if the history is not saved.
     756         */
    490757        notsaved : function(postid) {
    491758                var h = $('#imgedit-history-' + postid).val(),
    492759                        history = ( h !== '' ) ? JSON.parse(h) : [],
    var imageEdit = window.imageEdit = { 
    501768                return false;
    502769        },
    503770
     771        /**
     772         * @summary Adds a image edit action to the history.
     773         *
     774         * @memberof imageEdit
     775         * @since    2.9
     776         *
     777         * @param {object} op     The original position.
     778         * @param {number} postid The post id.
     779         * @param {string} nonce  The nonce.
     780         *
     781         * @returns {void}
     782         */
    504783        addStep : function(op, postid, nonce) {
    505784                var t = this, elem = $('#imgedit-history-' + postid),
    506785                        history = ( elem.val() !== '' ) ? JSON.parse( elem.val() ) : [],
    var imageEdit = window.imageEdit = { 
    522801                });
    523802        },
    524803
     804        /**
     805         * @summary Rotates the image.
     806         *
     807         * @memberof imageEdit
     808         * @since    2.9
     809         *
     810         * @param {string} angle  The angle the image is rotated with.
     811         * @param {number} postid The post id.
     812         * @param {string} nonce  The nonce
     813         * @param {object} t      The target element.
     814         *
     815         * @returns {boolean}
     816         */
    525817        rotate : function(angle, postid, nonce, t) {
    526818                if ( $(t).hasClass('disabled') ) {
    527819                        return false;
    var imageEdit = window.imageEdit = { 
    530822                this.addStep({ 'r': { 'r': angle, 'fw': this.hold.h, 'fh': this.hold.w }}, postid, nonce);
    531823        },
    532824
     825        /**
     826         * @summary Flips the image.
     827         *
     828         * @memberof imageEdit
     829         * @since    2.9
     830         *
     831         * @param {number} axis   The axle the image is flipped on.
     832         * @param {number} postid The post id.
     833         * @param {string} nonce  The nonce.
     834         * @param {object} t      The target element.
     835         *
     836         * @returns {boolean}
     837         */
    533838        flip : function (axis, postid, nonce, t) {
    534839                if ( $(t).hasClass('disabled') ) {
    535840                        return false;
    var imageEdit = window.imageEdit = { 
    538843                this.addStep({ 'f': { 'f': axis, 'fw': this.hold.w, 'fh': this.hold.h }}, postid, nonce);
    539844        },
    540845
     846        /**
     847         * @summary Crops the image.
     848         *
     849         * @memberof imageEdit
     850         * @since    2.9
     851         *
     852         * @param {number} postid The post id.
     853         * @param {string} nonce  The nonce.
     854         * @param {object} t      The target object.
     855         *
     856         * @returns {void|boolean} Returns false if the crop button is disabled.
     857         */
    541858        crop : function (postid, nonce, t) {
    542859                var sel = $('#imgedit-selection-' + postid).val(),
    543860                        w = this.intval( $('#imgedit-sel-width-' + postid).val() ),
    var imageEdit = window.imageEdit = { 
    555872                }
    556873        },
    557874
     875        /**
     876         * @summary Undoes a image edit action.
     877         *
     878         * @memberof imageEdit
     879         * @since    2.9
     880         *
     881         * @param {number} postid   The post id.
     882         * @param {string} nonce    The nonce.
     883         *
     884         * @returns {void|false} Returns false if the undo button is disabled.
     885         */
    558886        undo : function (postid, nonce) {
    559887                var t = this, button = $('#image-undo-' + postid), elem = $('#imgedit-undone-' + postid),
    560888                        pop = t.intval( elem.val() ) + 1;
    var imageEdit = window.imageEdit = { 
    577905                });
    578906        },
    579907
     908        /**
     909         * Reverts a undo action.
     910         *
     911         * @memberof imageEdit
     912         * @since    2.9
     913         *
     914         * @param {number} postid The post id.
     915         * @param {string} nonce  The nonce.
     916         *
     917         * @returns {void}
     918         */
    580919        redo : function(postid, nonce) {
    581920                var t = this, button = $('#image-redo-' + postid), elem = $('#imgedit-undone-' + postid),
    582921                        pop = t.intval( elem.val() ) - 1;
    var imageEdit = window.imageEdit = { 
    596935                });
    597936        },
    598937
     938        /**
     939         * @summary Sets the selection for the height and width in pixels.
     940         *
     941         * @memberof imageEdit
     942         * @since    2.9
     943         *
     944         * @param {number} postid The post id.
     945         * @param {jQuery} el     The element containing the values.
     946         *
     947         * @returns {void|boolean} Returns false when the x or y value is lower than 1,
     948         *                         void when the value is not numeric or when the operation
     949         *                         is successful.
     950         */
    599951        setNumSelection : function( postid, el ) {
    600952                var sel, elX = $('#imgedit-sel-width-' + postid), elY = $('#imgedit-sel-height-' + postid),
    601953                        x = this.intval( elX.val() ), y = this.intval( elY.val() ),
    var imageEdit = window.imageEdit = { 
    640992                }
    641993        },
    642994
     995        /**
     996         * Rounds a number to a whole.
     997         *
     998         * @memberof imageEdit
     999         * @since    2.9
     1000         *
     1001         * @param {number} num The number.
     1002         *
     1003         * @returns {number} The number rounded to a whole number.
     1004         */
    6431005        round : function(num) {
    6441006                var s;
    6451007                num = Math.round(num);
    var imageEdit = window.imageEdit = { 
    6591021                return num;
    6601022        },
    6611023
     1024        /**
     1025         * Sets a locked aspect ratio for the selection.
     1026         *
     1027         * @memberof imageEdit
     1028         * @since    2.9
     1029         *
     1030         * @param {number} postid     The post id.
     1031         * @param {number} n          The ratio to set.
     1032         * @param {jQuery} el         The element containing the values.
     1033         *
     1034         * @returns {void}
     1035         */
    6621036        setRatioSelection : function(postid, n, el) {
    6631037                var sel, r, x = this.intval( $('#imgedit-crop-width-' + postid).val() ),
    6641038                        y = this.intval( $('#imgedit-crop-height-' + postid).val() ),
    var imageEdit = window.imageEdit = { 
    6911065                }
    6921066        },
    6931067
     1068        /**
     1069         * Validates if a value in a jQuery.HTMLElement is numeric.
     1070         *
     1071         * @memberof imageEdit
     1072         * @since    4.6
     1073         *
     1074         * @param {jQuery} el The html element.
     1075         *
     1076         * @returns {void|boolean} Returns false if the value is not numeric,
     1077         * void when it is.
     1078         */
    6941079        validateNumeric: function( el ) {
    6951080                if ( ! this.intval( $( el ).val() ) ) {
    6961081                        $( el ).val( '' );