jenkins-bot has submitted this change and it was merged.

Change subject: Array.prototype.splice polyfill for Opera
......................................................................


Array.prototype.splice polyfill for Opera

Apparently they can't get their basic ECMAScript right. In 2013.

It doesn't come up that often, because you don't splice an array with
more than 256 elements every day. Only implemented in ve.batchSplice
for now, as that function does handle thousands of elements routinely.
Other callers of .splice() can simply use that instead.

Bug: 50385
Change-Id: I281a61d55c6f7df5f28627a1df80f2a001110607
---
M modules/ve/ve.js
1 file changed, 66 insertions(+), 22 deletions(-)

Approvals:
  Catrope: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/ve/ve.js b/modules/ve/ve.js
index b0e2b48..d98fd11 100644
--- a/modules/ve/ve.js
+++ b/modules/ve/ve.js
@@ -360,36 +360,80 @@
         * performance tests should be conducted on each use of this method to 
verify this is true for the
         * particular use. Also, browsers change fast, never assume anything, 
always test everything.
         *
-        * @param {Array} arr Array to remove from and insert into. Will be 
modified
+        * Includes a replacement for broken implementation of 
Array.prototype.splice() found in Opera 12.
+        *
+        * @param {Array|ve.dm.BranchNode} arr Object supporting .splice() to 
remove from and insert into. Will be modified
         * @param {number} offset Offset in arr to splice at. This may NOT be 
negative, unlike the
         *  'index' parameter in Array#splice
         * @param {number} remove Number of elements to remove at the offset. 
May be zero
         * @param {Array} data Array of items to insert at the offset. May not 
be empty if remove=0
         * @returns {Array} Array of items removed
         */
-       ve.batchSplice = function ( arr, offset, remove, data ) {
-               // We need to splice insertion in in batches, because of 
parameter list length limits which vary
-               // cross-browser - 1024 seems to be a safe batch size on all 
browsers
-               var index = 0, batchSize = 1024, toRemove = remove, spliced, 
removed = [];
-               if ( data.length === 0 ) {
-                       // Special case: data is empty, so we're just doing a 
removal
-                       // The code below won't handle that properly, so we do 
it here
-                       return arr.splice( offset, remove );
+       ve.batchSplice = ( function () {
+               var arraySplice;
+
+               // This yields 'true' on Opera 12.15.
+               function isSpliceBroken() {
+                       var n = 256, a = [];
+                       a[n] = 'a';
+
+                       a.splice( n + 1, 0, 'b' );
+
+                       return a[n] !== 'a';
                }
-               while ( index < data.length ) {
-                       // Call arr.splice( offset, remove, i0, i1, i2, ..., 
i1023 );
-                       // Only set remove on the first call, and set it to 
zero on subsequent calls
-                       spliced = arr.splice.apply(
-                               arr, [index + offset, toRemove].concat( 
data.slice( index, index + batchSize ) )
-                       );
-                       if ( toRemove > 0 ) {
-                               removed = spliced;
+
+               if ( !isSpliceBroken() ) {
+                       arraySplice = Array.prototype.splice;
+               } else {
+                       // Standard Array.prototype.splice() function 
implemented using .slice() and .push().
+                       arraySplice = function ( offset, remove/*, data... */ ) 
{
+                               var data, begin, removed, end;
+
+                               data = Array.prototype.slice.call( arguments, 2 
);
+
+                               begin = this.slice( 0, offset );
+                               removed = this.slice( offset, remove );
+                               end = this.slice( offset + remove );
+
+                               this.length = 0;
+                               // This polyfill only been discovered to be 
necessary on Opera
+                               // and it seems to handle up to 1048575 
function parameters.
+                               this.push.apply( this, begin );
+                               this.push.apply( this, data );
+                               this.push.apply( this, end );
+
+                               return removed;
+                       };
+               }
+
+               return function ( arr, offset, remove, data ) {
+                       // We need to splice insertion in in batches, because 
of parameter list length limits which vary
+                       // cross-browser - 1024 seems to be a safe batch size 
on all browsers
+                       var splice, index = 0, batchSize = 1024, toRemove = 
remove, spliced, removed = [];
+
+                       splice = ve.isArray( arr ) ? arraySplice : arr.splice;
+
+                       if ( data.length === 0 ) {
+                               // Special case: data is empty, so we're just 
doing a removal
+                               // The code below won't handle that properly, 
so we do it here
+                               return splice.call( arr, offset, remove );
                        }
-                       index += batchSize;
-                       toRemove = 0;
-               }
-               return removed;
-       };
+
+                       while ( index < data.length ) {
+                               // Call arr.splice( offset, remove, i0, i1, i2, 
..., i1023 );
+                               // Only set remove on the first call, and set 
it to zero on subsequent calls
+                               spliced = splice.apply(
+                                       arr, [index + offset, toRemove].concat( 
data.slice( index, index + batchSize ) )
+                               );
+                               if ( toRemove > 0 ) {
+                                       removed = spliced;
+                               }
+                               index += batchSize;
+                               toRemove = 0;
+                       }
+                       return removed;
+               };
+       }() );
 
        /**
         * Insert one array into another.

-- 
To view, visit https://gerrit.wikimedia.org/r/72233
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I281a61d55c6f7df5f28627a1df80f2a001110607
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Matmarex <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Matmarex <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to