~canonical-sysadmins/wordpress/4.9.2

« back to all changes in this revision

Viewing changes to wp-admin/js/widgets/media-widgets.js

  • Committer: Barry Price
  • Date: 2017-11-17 04:49:02 UTC
  • mfrom: (1.1.30 upstream)
  • Revision ID: barry.price@canonical.com-20171117044902-5frux4ycbq6g9fyf
Merge WP4.9 from upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
85
85
        component.MediaEmbedView = wp.media.view.Embed.extend({
86
86
 
87
87
                /**
 
88
                 * Initialize.
 
89
                 *
 
90
                 * @since 4.9.0
 
91
                 *
 
92
                 * @param {object} options - Options.
 
93
                 * @returns {void}
 
94
                 */
 
95
                initialize: function( options ) {
 
96
                        var view = this, embedController; // eslint-disable-line consistent-this
 
97
                        wp.media.view.Embed.prototype.initialize.call( view, options );
 
98
                        if ( 'image' !== view.controller.options.mimeType ) {
 
99
                                embedController = view.controller.states.get( 'embed' );
 
100
                                embedController.off( 'scan', embedController.scanImage, embedController );
 
101
                        }
 
102
                },
 
103
 
 
104
                /**
88
105
                 * Refresh embed view.
89
106
                 *
90
107
                 * Forked override of {wp.media.view.Embed#refresh()} to suppress irrelevant "link text" field.
140
157
                                        },
141
158
 
142
159
                                        /**
 
160
                                         * Update oEmbed.
 
161
                                         *
 
162
                                         * @since 4.9.0
 
163
                                         *
 
164
                                         * @returns {void}
 
165
                                         */
 
166
                                        updateoEmbed: function() {
 
167
                                                var embedLinkView = this, url; // eslint-disable-line consistent-this
 
168
 
 
169
                                                url = embedLinkView.model.get( 'url' );
 
170
 
 
171
                                                // Abort if the URL field was emptied out.
 
172
                                                if ( ! url ) {
 
173
                                                        embedLinkView.setErrorNotice( '' );
 
174
                                                        embedLinkView.setAddToWidgetButtonDisabled( true );
 
175
                                                        return;
 
176
                                                }
 
177
 
 
178
                                                if ( ! url.match( /^(http|https):\/\/.+\// ) ) {
 
179
                                                        embedLinkView.controller.$el.find( '#embed-url-field' ).addClass( 'invalid' );
 
180
                                                        embedLinkView.setAddToWidgetButtonDisabled( true );
 
181
                                                }
 
182
 
 
183
                                                wp.media.view.EmbedLink.prototype.updateoEmbed.call( embedLinkView );
 
184
                                        },
 
185
 
 
186
                                        /**
143
187
                                         * Fetch media.
144
188
                                         *
145
189
                                         * @returns {void}
146
190
                                         */
147
191
                                        fetch: function() {
148
 
                                                var embedLinkView = this, fetchSuccess, matches, fileExt, urlParser; // eslint-disable-line consistent-this
 
192
                                                var embedLinkView = this, fetchSuccess, matches, fileExt, urlParser, url, re, youTubeEmbedMatch; // eslint-disable-line consistent-this
 
193
                                                url = embedLinkView.model.get( 'url' );
149
194
 
150
195
                                                if ( embedLinkView.dfd && 'pending' === embedLinkView.dfd.state() ) {
151
196
                                                        embedLinkView.dfd.abort();
152
197
                                                }
153
198
 
154
 
                                                // Abort if the URL field was emptied out.
155
 
                                                if ( ! embedLinkView.model.get( 'url' ) ) {
156
 
                                                        embedLinkView.setErrorNotice( '' );
157
 
                                                        return;
158
 
                                                }
159
 
 
160
199
                                                fetchSuccess = function( response ) {
161
200
                                                        embedLinkView.renderoEmbed({
162
201
                                                                data: {
164
203
                                                                }
165
204
                                                        });
166
205
 
167
 
                                                        $( '#embed-url-field' ).removeClass( 'invalid' );
 
206
                                                        embedLinkView.controller.$el.find( '#embed-url-field' ).removeClass( 'invalid' );
168
207
                                                        embedLinkView.setErrorNotice( '' );
169
208
                                                        embedLinkView.setAddToWidgetButtonDisabled( false );
170
209
                                                };
171
210
 
172
211
                                                urlParser = document.createElement( 'a' );
173
 
                                                urlParser.href = embedLinkView.model.get( 'url' );
 
212
                                                urlParser.href = url;
174
213
                                                matches = urlParser.pathname.toLowerCase().match( /\.(\w+)$/ );
175
214
                                                if ( matches ) {
176
215
                                                        fileExt = matches[1];
184
223
                                                        return;
185
224
                                                }
186
225
 
187
 
                                                // If video, test for Vimeo and YouTube, otherwise, renderFail(). This should be removed once #34115 is resolved.
188
 
                                                if ( 'video' === this.controller.options.mimeType && ! /vimeo|youtu\.?be/.test( urlParser.host ) ) {
189
 
                                                        embedLinkView.renderFail();
190
 
                                                        return;
 
226
                                                // Support YouTube embed links.
 
227
                                                re = /https?:\/\/www\.youtube\.com\/embed\/([^/]+)/;
 
228
                                                youTubeEmbedMatch = re.exec( url );
 
229
                                                if ( youTubeEmbedMatch ) {
 
230
                                                        url = 'https://www.youtube.com/watch?v=' + youTubeEmbedMatch[ 1 ];
 
231
                                                        // silently change url to proper oembed-able version.
 
232
                                                        embedLinkView.model.attributes.url = url;
191
233
                                                }
192
234
 
193
 
                                                embedLinkView.dfd = $.ajax({
 
235
                                                embedLinkView.dfd = wp.apiRequest({
194
236
                                                        url: wp.media.view.settings.oEmbedProxyUrl,
195
237
                                                        data: {
196
 
                                                                url: embedLinkView.model.get( 'url' ),
 
238
                                                                url: url,
197
239
                                                                maxwidth: embedLinkView.model.get( 'width' ),
198
240
                                                                maxheight: embedLinkView.model.get( 'height' ),
199
 
                                                                _wpnonce: wp.media.view.settings.nonce.wpRestApi,
200
241
                                                                discover: false
201
242
                                                        },
202
243
                                                        type: 'GET',
225
266
                                         */
226
267
                                        renderFail: function renderFail() {
227
268
                                                var embedLinkView = this; // eslint-disable-line consistent-this
228
 
                                                $( '#embed-url-field' ).addClass( 'invalid' );
 
269
                                                embedLinkView.controller.$el.find( '#embed-url-field' ).addClass( 'invalid' );
229
270
                                                embedLinkView.setErrorNotice( embedLinkView.controller.options.invalidEmbedTypeError || 'ERROR' );
230
271
                                                embedLinkView.setAddToWidgetButtonDisabled( true );
231
272
                                        }
420
461
                events: {
421
462
                        'click .notice-missing-attachment a': 'handleMediaLibraryLinkClick',
422
463
                        'click .select-media': 'selectMedia',
 
464
                        'click .placeholder': 'selectMedia',
423
465
                        'click .edit-media': 'editMedia'
424
466
                },
425
467
 
503
545
                                });
504
546
                        });
505
547
 
 
548
                        // Update link_url attribute.
 
549
                        control.$el.on( 'input change', '.link', function updateLinkUrl() {
 
550
                                var linkUrl = $.trim( $( this ).val() ), linkType = 'custom';
 
551
                                if ( control.selectedAttachment.get( 'linkUrl' ) === linkUrl || control.selectedAttachment.get( 'link' ) === linkUrl ) {
 
552
                                        linkType = 'post';
 
553
                                } else if ( control.selectedAttachment.get( 'url' ) === linkUrl ) {
 
554
                                        linkType = 'file';
 
555
                                }
 
556
                                control.model.set( {
 
557
                                        link_url: linkUrl,
 
558
                                        link_type: linkType
 
559
                                });
 
560
 
 
561
                                // Update display settings for the next time the user opens to select from the media library.
 
562
                                control.displaySettings.set( {
 
563
                                        link: linkType,
 
564
                                        linkUrl: linkUrl
 
565
                                });
 
566
                        });
 
567
 
506
568
                        /*
507
569
                         * Copy current display settings from the widget model to serve as basis
508
570
                         * of customized display settings for the current media frame session.
562
624
                syncModelToInputs: function syncModelToInputs() {
563
625
                        var control = this;
564
626
                        control.syncContainer.find( '.media-widget-instance-property' ).each( function() {
565
 
                                var input = $( this ), value;
566
 
                                value = control.model.get( input.data( 'property' ) );
 
627
                                var input = $( this ), value, propertyName;
 
628
                                propertyName = input.data( 'property' );
 
629
                                value = control.model.get( propertyName );
567
630
                                if ( _.isUndefined( value ) ) {
568
631
                                        return;
569
632
                                }
570
 
                                value = String( value );
571
 
                                if ( input.val() === value ) {
572
 
                                        return;
573
 
                                }
574
 
                                input.val( value );
575
 
                                input.trigger( 'change' );
 
633
 
 
634
                                if ( 'array' === control.model.schema[ propertyName ].type && _.isArray( value ) ) {
 
635
                                        value = value.join( ',' );
 
636
                                } else if ( 'boolean' === control.model.schema[ propertyName ].type ) {
 
637
                                        value = value ? '1' : ''; // Because in PHP, strval( true ) === '1' && strval( false ) === ''.
 
638
                                } else {
 
639
                                        value = String( value );
 
640
                                }
 
641
 
 
642
                                if ( input.val() !== value ) {
 
643
                                        input.val( value );
 
644
                                        input.trigger( 'change' );
 
645
                                }
576
646
                        });
577
647
                },
578
648
 
699
769
                                control.model.set( control.getModelPropsFromMediaFrame( mediaFrame ) );
700
770
                        });
701
771
 
702
 
                        // Disable syncing of attachment changes back to server. See <https://core.trac.wordpress.org/ticket/40403>.
 
772
                        // Disable syncing of attachment changes back to server (except for deletions). See <https://core.trac.wordpress.org/ticket/40403>.
703
773
                        defaultSync = wp.media.model.Attachment.prototype.sync;
704
 
                        wp.media.model.Attachment.prototype.sync = function rejectedSync() {
705
 
                                return $.Deferred().rejectWith( this ).promise();
 
774
                        wp.media.model.Attachment.prototype.sync = function( method ) {
 
775
                                if ( 'delete' === method ) {
 
776
                                        return defaultSync.apply( this, arguments );
 
777
                                } else {
 
778
                                        return $.Deferred().rejectWith( this ).promise();
 
779
                                }
706
780
                        };
707
781
                        mediaFrame.on( 'close', function onClose() {
708
782
                                wp.media.model.Attachment.prototype.sync = defaultSync;
809
883
                        }
810
884
 
811
885
                        if ( 'post' === mediaFrameProps.link ) {
812
 
                                modelProps.link_url = mediaFrameProps.postUrl;
 
886
                                modelProps.link_url = mediaFrameProps.postUrl || mediaFrameProps.linkUrl;
813
887
                        } else if ( 'file' === mediaFrameProps.link ) {
814
888
                                modelProps.link_url = mediaFrameProps.url;
815
889
                        }
969
1043
                                        return;
970
1044
                                }
971
1045
                                type = model.schema[ name ].type;
972
 
                                if ( 'integer' === type ) {
 
1046
                                if ( 'array' === type ) {
 
1047
                                        castedAttrs[ name ] = value;
 
1048
                                        if ( ! _.isArray( castedAttrs[ name ] ) ) {
 
1049
                                                castedAttrs[ name ] = castedAttrs[ name ].split( /,/ ); // Good enough for parsing an ID list.
 
1050
                                        }
 
1051
                                        if ( model.schema[ name ].items && 'integer' === model.schema[ name ].items.type ) {
 
1052
                                                castedAttrs[ name ] = _.filter(
 
1053
                                                        _.map( castedAttrs[ name ], function( id ) {
 
1054
                                                                return parseInt( id, 10 );
 
1055
                                                        },
 
1056
                                                        function( id ) {
 
1057
                                                                return 'number' === typeof id;
 
1058
                                                        }
 
1059
                                                ) );
 
1060
                                        }
 
1061
                                } else if ( 'integer' === type ) {
973
1062
                                        castedAttrs[ name ] = parseInt( value, 10 );
974
1063
                                } else if ( 'boolean' === type ) {
975
1064
                                        castedAttrs[ name ] = ! ( ! value || '0' === value || 'false' === value );
1017
1106
         * @returns {void}
1018
1107
         */
1019
1108
        component.handleWidgetAdded = function handleWidgetAdded( event, widgetContainer ) {
1020
 
                var fieldContainer, syncContainer, widgetForm, idBase, ControlConstructor, ModelConstructor, modelAttributes, widgetControl, widgetModel, widgetId, widgetInside, animatedCheckDelay = 50, renderWhenAnimationDone;
 
1109
                var fieldContainer, syncContainer, widgetForm, idBase, ControlConstructor, ModelConstructor, modelAttributes, widgetControl, widgetModel, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone;
1021
1110
                widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen.
1022
1111
                idBase = widgetForm.find( '> .id_base' ).val();
1023
1112
                widgetId = widgetForm.find( '> .widget-id' ).val();
1036
1125
 
1037
1126
                /*
1038
1127
                 * Create a container element for the widget control (Backbone.View).
1039
 
                 * This is inserted into the DOM immediately before the the .widget-content
 
1128
                 * This is inserted into the DOM immediately before the .widget-content
1040
1129
                 * element because the contents of this element are essentially "managed"
1041
1130
                 * by PHP, where each widget update cause the entire element to be emptied
1042
1131
                 * and replaced with the rendered output of WP_Widget::form() which is
1075
1164
                 * This ensures that the container's dimensions are fixed so that ME.js
1076
1165
                 * can initialize with the proper dimensions.
1077
1166
                 */
1078
 
                widgetInside = widgetContainer.parent();
1079
1167
                renderWhenAnimationDone = function() {
1080
 
                        if ( widgetInside.is( ':animated' ) ) {
 
1168
                        if ( ! widgetContainer.hasClass( 'open' ) ) {
1081
1169
                                setTimeout( renderWhenAnimationDone, animatedCheckDelay );
1082
1170
                        } else {
1083
1171
                                widgetControl.render();