Best Python code snippet using slash
virtualRepeat.js
Source:virtualRepeat.js  
1/*!2 * Angular Material Design3 * https://github.com/angular/material4 * @license MIT5 * v1.1.16 */7goog.provide('ngmaterial.components.virtualRepeat');8goog.require('ngmaterial.components.showHide');9goog.require('ngmaterial.core');10/**11 * @ngdoc module12 * @name material.components.virtualRepeat13 */14VirtualRepeatContainerController.$inject = ["$$rAF", "$mdUtil", "$parse", "$rootScope", "$window", "$scope", "$element", "$attrs"];15VirtualRepeatController.$inject = ["$scope", "$element", "$attrs", "$browser", "$document", "$rootScope", "$$rAF", "$mdUtil"];16VirtualRepeatDirective.$inject = ["$parse"];17angular.module('material.components.virtualRepeat', [18  'material.core',19  'material.components.showHide'20])21.directive('mdVirtualRepeatContainer', VirtualRepeatContainerDirective)22.directive('mdVirtualRepeat', VirtualRepeatDirective);23/**24 * @ngdoc directive25 * @name mdVirtualRepeatContainer26 * @module material.components.virtualRepeat27 * @restrict E28 * @description29 * `md-virtual-repeat-container` provides the scroll container for md-virtual-repeat.30 *31 * VirtualRepeat is a limited substitute for ng-repeat that renders only32 * enough DOM nodes to fill the container and recycling them as the user scrolls.33 *34 * Once an element is not visible anymore, the VirtualRepeat recycles it and will reuse it for35 * another visible item by replacing the previous dataset with the new one.36 *37 * ### Common Issues38 *39 * > When having one-time bindings inside of the view template, the VirtualRepeat will not properly40 * > update the bindings for new items, since the view will be recycled.41 *42 * ### Notes43 *44 * > The VirtualRepeat is a similar implementation to the Android45 * [RecyclerView](https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html)46 *47 * <!-- This comment forces a break between blockquotes //-->48 *49 * > Please also review the <a ng-href="api/directive/mdVirtualRepeat">VirtualRepeat</a>50 * documentation for more information.51 *52 *53 * @usage54 * <hljs lang="html">55 *56 * <md-virtual-repeat-container md-top-index="topIndex">57 *   <div md-virtual-repeat="i in items" md-item-size="20">Hello {{i}}!</div>58 * </md-virtual-repeat-container>59 * </hljs>60 *61 * @param {number=} md-top-index Binds the index of the item that is at the top of the scroll62 *     container to $scope. It can both read and set the scroll position.63 * @param {boolean=} md-orient-horizontal Whether the container should scroll horizontally64 *     (defaults to orientation and scrolling vertically).65 * @param {boolean=} md-auto-shrink When present, the container will shrink to fit66 *     the number of items when that number is less than its original size.67 * @param {number=} md-auto-shrink-min Minimum number of items that md-auto-shrink68 *     will shrink to (default: 0).69 */70function VirtualRepeatContainerDirective() {71  return {72    controller: VirtualRepeatContainerController,73    template: virtualRepeatContainerTemplate,74    compile: function virtualRepeatContainerCompile($element, $attrs) {75      $element76          .addClass('md-virtual-repeat-container')77          .addClass($attrs.hasOwnProperty('mdOrientHorizontal')78              ? 'md-orient-horizontal'79              : 'md-orient-vertical');80    }81  };82}83function virtualRepeatContainerTemplate($element) {84  return '<div class="md-virtual-repeat-scroller">' +85    '<div class="md-virtual-repeat-sizer"></div>' +86    '<div class="md-virtual-repeat-offsetter">' +87      $element[0].innerHTML +88    '</div></div>';89}90/**91 * Maximum size, in pixels, that can be explicitly set to an element. The actual value varies92 * between browsers, but IE11 has the very lowest size at a mere 1,533,917px. Ideally we could93 * *compute* this value, but Firefox always reports an element to have a size of zero if it94 * goes over the max, meaning that we'd have to binary search for the value.95 * @const {number}96 */97var MAX_ELEMENT_SIZE = 1533917;98/**99 * Number of additional elements to render above and below the visible area inside100 * of the virtual repeat container. A higher number results in less flicker when scrolling101 * very quickly in Safari, but comes with a higher rendering and dirty-checking cost.102 * @const {number}103 */104var NUM_EXTRA = 3;105/** ngInject */106function VirtualRepeatContainerController(107    $$rAF, $mdUtil, $parse, $rootScope, $window, $scope, $element, $attrs) {108  this.$rootScope = $rootScope;109  this.$scope = $scope;110  this.$element = $element;111  this.$attrs = $attrs;112  /** @type {number} The width or height of the container */113  this.size = 0;114  /** @type {number} The scroll width or height of the scroller */115  this.scrollSize = 0;116  /** @type {number} The scrollLeft or scrollTop of the scroller */117  this.scrollOffset = 0;118  /** @type {boolean} Whether the scroller is oriented horizontally */119  this.horizontal = this.$attrs.hasOwnProperty('mdOrientHorizontal');120  /** @type {!VirtualRepeatController} The repeater inside of this container */121  this.repeater = null;122  /** @type {boolean} Whether auto-shrink is enabled */123  this.autoShrink = this.$attrs.hasOwnProperty('mdAutoShrink');124  /** @type {number} Minimum number of items to auto-shrink to */125  this.autoShrinkMin = parseInt(this.$attrs.mdAutoShrinkMin, 10) || 0;126  /** @type {?number} Original container size when shrank */127  this.originalSize = null;128  /** @type {number} Amount to offset the total scroll size by. */129  this.offsetSize = parseInt(this.$attrs.mdOffsetSize, 10) || 0;130  /** @type {?string} height or width element style on the container prior to auto-shrinking. */131  this.oldElementSize = null;132  if (this.$attrs.mdTopIndex) {133    /** @type {function(angular.Scope): number} Binds to topIndex on Angular scope */134    this.bindTopIndex = $parse(this.$attrs.mdTopIndex);135    /** @type {number} The index of the item that is at the top of the scroll container */136    this.topIndex = this.bindTopIndex(this.$scope);137    if (!angular.isDefined(this.topIndex)) {138      this.topIndex = 0;139      this.bindTopIndex.assign(this.$scope, 0);140    }141    this.$scope.$watch(this.bindTopIndex, angular.bind(this, function(newIndex) {142      if (newIndex !== this.topIndex) {143        this.scrollToIndex(newIndex);144      }145    }));146  } else {147    this.topIndex = 0;148  }149  this.scroller = $element[0].querySelector('.md-virtual-repeat-scroller');150  this.sizer = this.scroller.querySelector('.md-virtual-repeat-sizer');151  this.offsetter = this.scroller.querySelector('.md-virtual-repeat-offsetter');152  // After the dom stablizes, measure the initial size of the container and153  // make a best effort at re-measuring as it changes.154  var boundUpdateSize = angular.bind(this, this.updateSize);155  $$rAF(angular.bind(this, function() {156    boundUpdateSize();157    var debouncedUpdateSize = $mdUtil.debounce(boundUpdateSize, 10, null, false);158    var jWindow = angular.element($window);159    // Make one more attempt to get the size if it is 0.160    // This is not by any means a perfect approach, but there's really no161    // silver bullet here.162    if (!this.size) {163      debouncedUpdateSize();164    }165    jWindow.on('resize', debouncedUpdateSize);166    $scope.$on('$destroy', function() {167      jWindow.off('resize', debouncedUpdateSize);168    });169    $scope.$emit('$md-resize-enable');170    $scope.$on('$md-resize', boundUpdateSize);171  }));172}173/** Called by the md-virtual-repeat inside of the container at startup. */174VirtualRepeatContainerController.prototype.register = function(repeaterCtrl) {175  this.repeater = repeaterCtrl;176  angular.element(this.scroller)177      .on('scroll wheel touchmove touchend', angular.bind(this, this.handleScroll_));178};179/** @return {boolean} Whether the container is configured for horizontal scrolling. */180VirtualRepeatContainerController.prototype.isHorizontal = function() {181  return this.horizontal;182};183/** @return {number} The size (width or height) of the container. */184VirtualRepeatContainerController.prototype.getSize = function() {185  return this.size;186};187/**188 * Resizes the container.189 * @private190 * @param {number} size The new size to set.191 */192VirtualRepeatContainerController.prototype.setSize_ = function(size) {193  var dimension = this.getDimensionName_();194  this.size = size;195  this.$element[0].style[dimension] = size + 'px';196};197VirtualRepeatContainerController.prototype.unsetSize_ = function() {198  this.$element[0].style[this.getDimensionName_()] = this.oldElementSize;199  this.oldElementSize = null;200};201/** Instructs the container to re-measure its size. */202VirtualRepeatContainerController.prototype.updateSize = function() {203  // If the original size is already determined, we can skip the update.204  if (this.originalSize) return;205  this.size = this.isHorizontal()206      ? this.$element[0].clientWidth207      : this.$element[0].clientHeight;208  // Recheck the scroll position after updating the size. This resolves209  // problems that can result if the scroll position was measured while the210  // element was display: none or detached from the document.211  this.handleScroll_();212  this.repeater && this.repeater.containerUpdated();213};214/** @return {number} The container's scrollHeight or scrollWidth. */215VirtualRepeatContainerController.prototype.getScrollSize = function() {216  return this.scrollSize;217};218VirtualRepeatContainerController.prototype.getDimensionName_ = function() {219  return this.isHorizontal() ? 'width' : 'height';220};221/**222 * Sets the scroller element to the specified size.223 * @private224 * @param {number} size The new size.225 */226VirtualRepeatContainerController.prototype.sizeScroller_ = function(size) {227  var dimension =  this.getDimensionName_();228  var crossDimension = this.isHorizontal() ? 'height' : 'width';229  // Clear any existing dimensions.230  this.sizer.innerHTML = '';231  // If the size falls within the browser's maximum explicit size for a single element, we can232  // set the size and be done. Otherwise, we have to create children that add up the the desired233  // size.234  if (size < MAX_ELEMENT_SIZE) {235    this.sizer.style[dimension] = size + 'px';236  } else {237    this.sizer.style[dimension] = 'auto';238    this.sizer.style[crossDimension] = 'auto';239    // Divide the total size we have to render into N max-size pieces.240    var numChildren = Math.floor(size / MAX_ELEMENT_SIZE);241    // Element template to clone for each max-size piece.242    var sizerChild = document.createElement('div');243    sizerChild.style[dimension] = MAX_ELEMENT_SIZE + 'px';244    sizerChild.style[crossDimension] = '1px';245    for (var i = 0; i < numChildren; i++) {246      this.sizer.appendChild(sizerChild.cloneNode(false));247    }248    // Re-use the element template for the remainder.249    sizerChild.style[dimension] = (size - (numChildren * MAX_ELEMENT_SIZE)) + 'px';250    this.sizer.appendChild(sizerChild);251  }252};253/**254 * If auto-shrinking is enabled, shrinks or unshrinks as appropriate.255 * @private256 * @param {number} size The new size.257 */258VirtualRepeatContainerController.prototype.autoShrink_ = function(size) {259  var shrinkSize = Math.max(size, this.autoShrinkMin * this.repeater.getItemSize());260  if (this.autoShrink && shrinkSize !== this.size) {261    if (this.oldElementSize === null) {262      this.oldElementSize = this.$element[0].style[this.getDimensionName_()];263    }264    var currentSize = this.originalSize || this.size;265    if (!currentSize || shrinkSize < currentSize) {266      if (!this.originalSize) {267        this.originalSize = this.size;268      }269      // Now we update the containers size, because shrinking is enabled.270      this.setSize_(shrinkSize);271    } else if (this.originalSize !== null) {272      // Set the size back to our initial size.273      this.unsetSize_();274      var _originalSize = this.originalSize;275      this.originalSize = null;276      // We determine the repeaters size again, if the original size was zero.277      // The originalSize needs to be null, to be able to determine the size.278      if (!_originalSize) this.updateSize();279      // Apply the original size or the determined size back to the container, because280      // it has been overwritten before, in the shrink block.281      this.setSize_(_originalSize || this.size);282    }283    this.repeater.containerUpdated();284  }285};286/**287 * Sets the scrollHeight or scrollWidth. Called by the repeater based on288 * its item count and item size.289 * @param {number} itemsSize The total size of the items.290 */291VirtualRepeatContainerController.prototype.setScrollSize = function(itemsSize) {292  var size = itemsSize + this.offsetSize;293  if (this.scrollSize === size) return;294  this.sizeScroller_(size);295  this.autoShrink_(size);296  this.scrollSize = size;297};298/** @return {number} The container's current scroll offset. */299VirtualRepeatContainerController.prototype.getScrollOffset = function() {300  return this.scrollOffset;301};302/**303 * Scrolls to a given scrollTop position.304 * @param {number} position305 */306VirtualRepeatContainerController.prototype.scrollTo = function(position) {307  this.scroller[this.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = position;308  this.handleScroll_();309};310/**311 * Scrolls the item with the given index to the top of the scroll container.312 * @param {number} index313 */314VirtualRepeatContainerController.prototype.scrollToIndex = function(index) {315  var itemSize = this.repeater.getItemSize();316  var itemsLength = this.repeater.itemsLength;317  if(index > itemsLength) {318    index = itemsLength - 1;319  }320  this.scrollTo(itemSize * index);321};322VirtualRepeatContainerController.prototype.resetScroll = function() {323  this.scrollTo(0);324};325VirtualRepeatContainerController.prototype.handleScroll_ = function() {326  var doc = angular.element(document)[0];327  var ltr = doc.dir != 'rtl' && doc.body.dir != 'rtl';328  if(!ltr && !this.maxSize) {329    this.scroller.scrollLeft = this.scrollSize;330    this.maxSize = this.scroller.scrollLeft;331  }332  var offset = this.isHorizontal() ?333      (ltr?this.scroller.scrollLeft : this.maxSize - this.scroller.scrollLeft)334      : this.scroller.scrollTop;335  if (offset === this.scrollOffset || offset > this.scrollSize - this.size) return;336  var itemSize = this.repeater.getItemSize();337  if (!itemSize) return;338  var numItems = Math.max(0, Math.floor(offset / itemSize) - NUM_EXTRA);339  var transform = (this.isHorizontal() ? 'translateX(' : 'translateY(') +340      (!this.isHorizontal() || ltr ? (numItems * itemSize) : - (numItems * itemSize))  + 'px)';341  this.scrollOffset = offset;342  this.offsetter.style.webkitTransform = transform;343  this.offsetter.style.transform = transform;344  if (this.bindTopIndex) {345    var topIndex = Math.floor(offset / itemSize);346    if (topIndex !== this.topIndex && topIndex < this.repeater.getItemCount()) {347      this.topIndex = topIndex;348      this.bindTopIndex.assign(this.$scope, topIndex);349      if (!this.$rootScope.$$phase) this.$scope.$digest();350    }351  }352  this.repeater.containerUpdated();353};354/**355 * @ngdoc directive356 * @name mdVirtualRepeat357 * @module material.components.virtualRepeat358 * @restrict A359 * @priority 1000360 * @description361 * `md-virtual-repeat` specifies an element to repeat using virtual scrolling.362 *363 * Virtual repeat is a limited substitute for ng-repeat that renders only364 * enough dom nodes to fill the container and recycling them as the user scrolls.365 * Arrays, but not objects are supported for iteration.366 * Track by, as alias, and (key, value) syntax are not supported.367 *368 * > <b>Note:</b> Please also review the369 *   <a ng-href="api/directive/mdVirtualRepeatContainer">VirtualRepeatContainer</a> documentation370 *   for more information.371 *372 * @usage373 * <hljs lang="html">374 * <md-virtual-repeat-container>375 *   <div md-virtual-repeat="i in items">Hello {{i}}!</div>376 * </md-virtual-repeat-container>377 *378 * <md-virtual-repeat-container md-orient-horizontal>379 *   <div md-virtual-repeat="i in items" md-item-size="20">Hello {{i}}!</div>380 * </md-virtual-repeat-container>381 * </hljs>382 *383 * @param {number=} md-item-size The height or width of the repeated elements (which must be384 *   identical for each element). Optional. Will attempt to read the size from the dom if missing,385 *   but still assumes that all repeated nodes have same height or width.386 * @param {string=} md-extra-name Evaluates to an additional name to which the current iterated item387 *   can be assigned on the repeated scope (needed for use in `md-autocomplete`).388 * @param {boolean=} md-on-demand When present, treats the md-virtual-repeat argument as an object389 *   that can fetch rows rather than an array.390 *391 *   **NOTE:** This object must implement the following interface with two (2) methods:392 *393 *   - `getItemAtIndex: function(index) [object]` The item at that index or null if it is not yet394 *     loaded (it should start downloading the item in that case).395 *   - `getLength: function() [number]` The data length to which the repeater container396 *     should be sized. Ideally, when the count is known, this method should return it.397 *     Otherwise, return a higher number than the currently loaded items to produce an398 *     infinite-scroll behavior.399 */400function VirtualRepeatDirective($parse) {401  return {402    controller: VirtualRepeatController,403    priority: 1000,404    require: ['mdVirtualRepeat', '^^mdVirtualRepeatContainer'],405    restrict: 'A',406    terminal: true,407    transclude: 'element',408    compile: function VirtualRepeatCompile($element, $attrs) {409      var expression = $attrs.mdVirtualRepeat;410      var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)\s*$/);411      var repeatName = match[1];412      var repeatListExpression = $parse(match[2]);413      var extraName = $attrs.mdExtraName && $parse($attrs.mdExtraName);414      return function VirtualRepeatLink($scope, $element, $attrs, ctrl, $transclude) {415        ctrl[0].link_(ctrl[1], $transclude, repeatName, repeatListExpression, extraName);416      };417    }418  };419}420/** ngInject */421function VirtualRepeatController($scope, $element, $attrs, $browser, $document, $rootScope,422    $$rAF, $mdUtil) {423  this.$scope = $scope;424  this.$element = $element;425  this.$attrs = $attrs;426  this.$browser = $browser;427  this.$document = $document;428  this.$rootScope = $rootScope;429  this.$$rAF = $$rAF;430  /** @type {boolean} Whether we are in on-demand mode. */431  this.onDemand = $mdUtil.parseAttributeBoolean($attrs.mdOnDemand);432  /** @type {!Function} Backup reference to $browser.$$checkUrlChange */433  this.browserCheckUrlChange = $browser.$$checkUrlChange;434  /** @type {number} Most recent starting repeat index (based on scroll offset) */435  this.newStartIndex = 0;436  /** @type {number} Most recent ending repeat index (based on scroll offset) */437  this.newEndIndex = 0;438  /** @type {number} Most recent end visible index (based on scroll offset) */439  this.newVisibleEnd = 0;440  /** @type {number} Previous starting repeat index (based on scroll offset) */441  this.startIndex = 0;442  /** @type {number} Previous ending repeat index (based on scroll offset) */443  this.endIndex = 0;444  // TODO: measure width/height of first element from dom if not provided.445  // getComputedStyle?446  /** @type {?number} Height/width of repeated elements. */447  this.itemSize = $scope.$eval($attrs.mdItemSize) || null;448  /** @type {boolean} Whether this is the first time that items are rendered. */449  this.isFirstRender = true;450  /**451   * @private {boolean} Whether the items in the list are already being updated. Used to prevent452   *     nested calls to virtualRepeatUpdate_.453   */454  this.isVirtualRepeatUpdating_ = false;455  /** @type {number} Most recently seen length of items. */456  this.itemsLength = 0;457  /**458   * @type {!Function} Unwatch callback for item size (when md-items-size is459   *     not specified), or angular.noop otherwise.460   */461  this.unwatchItemSize_ = angular.noop;462  /**463   * Presently rendered blocks by repeat index.464   * @type {Object<number, !VirtualRepeatController.Block}465   */466  this.blocks = {};467  /** @type {Array<!VirtualRepeatController.Block>} A pool of presently unused blocks. */468  this.pooledBlocks = [];469  $scope.$on('$destroy', angular.bind(this, this.cleanupBlocks_));470}471/**472 * An object representing a repeated item.473 * @typedef {{element: !jqLite, new: boolean, scope: !angular.Scope}}474 */475VirtualRepeatController.Block;476/**477 * Called at startup by the md-virtual-repeat postLink function.478 * @param {!VirtualRepeatContainerController} container The container's controller.479 * @param {!Function} transclude The repeated element's bound transclude function.480 * @param {string} repeatName The left hand side of the repeat expression, indicating481 *     the name for each item in the array.482 * @param {!Function} repeatListExpression A compiled expression based on the right hand side483 *     of the repeat expression. Points to the array to repeat over.484 * @param {string|undefined} extraName The optional extra repeatName.485 */486VirtualRepeatController.prototype.link_ =487    function(container, transclude, repeatName, repeatListExpression, extraName) {488  this.container = container;489  this.transclude = transclude;490  this.repeatName = repeatName;491  this.rawRepeatListExpression = repeatListExpression;492  this.extraName = extraName;493  this.sized = false;494  this.repeatListExpression = angular.bind(this, this.repeatListExpression_);495  this.container.register(this);496};497/** @private Cleans up unused blocks. */498VirtualRepeatController.prototype.cleanupBlocks_ = function() {499  angular.forEach(this.pooledBlocks, function cleanupBlock(block) {500    block.element.remove();501  });502};503/** @private Attempts to set itemSize by measuring a repeated element in the dom */504VirtualRepeatController.prototype.readItemSize_ = function() {505  if (this.itemSize) {506    // itemSize was successfully read in a different asynchronous call.507    return;508  }509  this.items = this.repeatListExpression(this.$scope);510  this.parentNode = this.$element[0].parentNode;511  var block = this.getBlock_(0);512  if (!block.element[0].parentNode) {513    this.parentNode.appendChild(block.element[0]);514  }515  this.itemSize = block.element[0][516      this.container.isHorizontal() ? 'offsetWidth' : 'offsetHeight'] || null;517  this.blocks[0] = block;518  this.poolBlock_(0);519  if (this.itemSize) {520    this.containerUpdated();521  }522};523/**524 * Returns the user-specified repeat list, transforming it into an array-like525 * object in the case of infinite scroll/dynamic load mode.526 * @param {!angular.Scope} The scope.527 * @return {!Array|!Object} An array or array-like object for iteration.528 */529VirtualRepeatController.prototype.repeatListExpression_ = function(scope) {530  var repeatList = this.rawRepeatListExpression(scope);531  if (this.onDemand && repeatList) {532    var virtualList = new VirtualRepeatModelArrayLike(repeatList);533    virtualList.$$includeIndexes(this.newStartIndex, this.newVisibleEnd);534    return virtualList;535  } else {536    return repeatList;537  }538};539/**540 * Called by the container. Informs us that the containers scroll or size has541 * changed.542 */543VirtualRepeatController.prototype.containerUpdated = function() {544  // If itemSize is unknown, attempt to measure it.545  if (!this.itemSize) {546    // Make sure to clean up watchers if we can (see #8178)547    if(this.unwatchItemSize_ && this.unwatchItemSize_ !== angular.noop){548      this.unwatchItemSize_();549    }550    this.unwatchItemSize_ = this.$scope.$watchCollection(551        this.repeatListExpression,552        angular.bind(this, function(items) {553          if (items && items.length) {554            this.readItemSize_();555          }556        }));557    if (!this.$rootScope.$$phase) this.$scope.$digest();558    return;559  } else if (!this.sized) {560    this.items = this.repeatListExpression(this.$scope);561  }562  if (!this.sized) {563    this.unwatchItemSize_();564    this.sized = true;565    this.$scope.$watchCollection(this.repeatListExpression,566        angular.bind(this, function(items, oldItems) {567          if (!this.isVirtualRepeatUpdating_) {568            this.virtualRepeatUpdate_(items, oldItems);569          }570        }));571  }572  this.updateIndexes_();573  if (this.newStartIndex !== this.startIndex ||574      this.newEndIndex !== this.endIndex ||575      this.container.getScrollOffset() > this.container.getScrollSize()) {576    if (this.items instanceof VirtualRepeatModelArrayLike) {577      this.items.$$includeIndexes(this.newStartIndex, this.newEndIndex);578    }579    this.virtualRepeatUpdate_(this.items, this.items);580  }581};582/**583 * Called by the container. Returns the size of a single repeated item.584 * @return {?number} Size of a repeated item.585 */586VirtualRepeatController.prototype.getItemSize = function() {587  return this.itemSize;588};589/**590 * Called by the container. Returns the size of a single repeated item.591 * @return {?number} Size of a repeated item.592 */593VirtualRepeatController.prototype.getItemCount = function() {594  return this.itemsLength;595};596/**597 * Updates the order and visible offset of repeated blocks in response to scrolling598 * or items updates.599 * @private600 */601VirtualRepeatController.prototype.virtualRepeatUpdate_ = function(items, oldItems) {602  this.isVirtualRepeatUpdating_ = true;603  var itemsLength = items && items.length || 0;604  var lengthChanged = false;605  // If the number of items shrank, keep the scroll position.606  if (this.items && itemsLength < this.items.length && this.container.getScrollOffset() !== 0) {607    this.items = items;608    var previousScrollOffset = this.container.getScrollOffset();609    this.container.resetScroll();610    this.container.scrollTo(previousScrollOffset);611  }612  if (itemsLength !== this.itemsLength) {613    lengthChanged = true;614    this.itemsLength = itemsLength;615  }616  this.items = items;617  if (items !== oldItems || lengthChanged) {618    this.updateIndexes_();619  }620  this.parentNode = this.$element[0].parentNode;621  if (lengthChanged) {622    this.container.setScrollSize(itemsLength * this.itemSize);623  }624  if (this.isFirstRender) {625    this.isFirstRender = false;626    var startIndex = this.$attrs.mdStartIndex ?627      this.$scope.$eval(this.$attrs.mdStartIndex) :628      this.container.topIndex;629    this.container.scrollToIndex(startIndex);630  }631  // Detach and pool any blocks that are no longer in the viewport.632  Object.keys(this.blocks).forEach(function(blockIndex) {633    var index = parseInt(blockIndex, 10);634    if (index < this.newStartIndex || index >= this.newEndIndex) {635      this.poolBlock_(index);636    }637  }, this);638  // Add needed blocks.639  // For performance reasons, temporarily block browser url checks as we digest640  // the restored block scopes ($$checkUrlChange reads window.location to641  // check for changes and trigger route change, etc, which we don't need when642  // trying to scroll at 60fps).643  this.$browser.$$checkUrlChange = angular.noop;644  var i, block,645      newStartBlocks = [],646      newEndBlocks = [];647  // Collect blocks at the top.648  for (i = this.newStartIndex; i < this.newEndIndex && this.blocks[i] == null; i++) {649    block = this.getBlock_(i);650    this.updateBlock_(block, i);651    newStartBlocks.push(block);652  }653  // Update blocks that are already rendered.654  for (; this.blocks[i] != null; i++) {655    this.updateBlock_(this.blocks[i], i);656  }657  var maxIndex = i - 1;658  // Collect blocks at the end.659  for (; i < this.newEndIndex; i++) {660    block = this.getBlock_(i);661    this.updateBlock_(block, i);662    newEndBlocks.push(block);663  }664  // Attach collected blocks to the document.665  if (newStartBlocks.length) {666    this.parentNode.insertBefore(667        this.domFragmentFromBlocks_(newStartBlocks),668        this.$element[0].nextSibling);669  }670  if (newEndBlocks.length) {671    this.parentNode.insertBefore(672        this.domFragmentFromBlocks_(newEndBlocks),673        this.blocks[maxIndex] && this.blocks[maxIndex].element[0].nextSibling);674  }675  // Restore $$checkUrlChange.676  this.$browser.$$checkUrlChange = this.browserCheckUrlChange;677  this.startIndex = this.newStartIndex;678  this.endIndex = this.newEndIndex;679  this.isVirtualRepeatUpdating_ = false;680};681/**682 * @param {number} index Where the block is to be in the repeated list.683 * @return {!VirtualRepeatController.Block} A new or pooled block to place at the specified index.684 * @private685 */686VirtualRepeatController.prototype.getBlock_ = function(index) {687  if (this.pooledBlocks.length) {688    return this.pooledBlocks.pop();689  }690  var block;691  this.transclude(angular.bind(this, function(clone, scope) {692    block = {693      element: clone,694      new: true,695      scope: scope696    };697    this.updateScope_(scope, index);698    this.parentNode.appendChild(clone[0]);699  }));700  return block;701};702/**703 * Updates and if not in a digest cycle, digests the specified block's scope to the data704 * at the specified index.705 * @param {!VirtualRepeatController.Block} block The block whose scope should be updated.706 * @param {number} index The index to set.707 * @private708 */709VirtualRepeatController.prototype.updateBlock_ = function(block, index) {710  this.blocks[index] = block;711  if (!block.new &&712      (block.scope.$index === index && block.scope[this.repeatName] === this.items[index])) {713    return;714  }715  block.new = false;716  // Update and digest the block's scope.717  this.updateScope_(block.scope, index);718  // Perform digest before reattaching the block.719  // Any resulting synchronous dom mutations should be much faster as a result.720  // This might break some directives, but I'm going to try it for now.721  if (!this.$rootScope.$$phase) {722    block.scope.$digest();723  }724};725/**726 * Updates scope to the data at the specified index.727 * @param {!angular.Scope} scope The scope which should be updated.728 * @param {number} index The index to set.729 * @private730 */731VirtualRepeatController.prototype.updateScope_ = function(scope, index) {732  scope.$index = index;733  scope[this.repeatName] = this.items && this.items[index];734  if (this.extraName) scope[this.extraName(this.$scope)] = this.items[index];735};736/**737 * Pools the block at the specified index (Pulls its element out of the dom and stores it).738 * @param {number} index The index at which the block to pool is stored.739 * @private740 */741VirtualRepeatController.prototype.poolBlock_ = function(index) {742  this.pooledBlocks.push(this.blocks[index]);743  this.parentNode.removeChild(this.blocks[index].element[0]);744  delete this.blocks[index];745};746/**747 * Produces a dom fragment containing the elements from the list of blocks.748 * @param {!Array<!VirtualRepeatController.Block>} blocks The blocks whose elements749 *     should be added to the document fragment.750 * @return {DocumentFragment}751 * @private752 */753VirtualRepeatController.prototype.domFragmentFromBlocks_ = function(blocks) {754  var fragment = this.$document[0].createDocumentFragment();755  blocks.forEach(function(block) {756    fragment.appendChild(block.element[0]);757  });758  return fragment;759};760/**761 * Updates start and end indexes based on length of repeated items and container size.762 * @private763 */764VirtualRepeatController.prototype.updateIndexes_ = function() {765  var itemsLength = this.items ? this.items.length : 0;766  var containerLength = Math.ceil(this.container.getSize() / this.itemSize);767  this.newStartIndex = Math.max(0, Math.min(768      itemsLength - containerLength,769      Math.floor(this.container.getScrollOffset() / this.itemSize)));770  this.newVisibleEnd = this.newStartIndex + containerLength + NUM_EXTRA;771  this.newEndIndex = Math.min(itemsLength, this.newVisibleEnd);772  this.newStartIndex = Math.max(0, this.newStartIndex - NUM_EXTRA);773};774/**775 * This VirtualRepeatModelArrayLike class enforces the interface requirements776 * for infinite scrolling within a mdVirtualRepeatContainer. An object with this777 * interface must implement the following interface with two (2) methods:778 *779 * getItemAtIndex: function(index) -> item at that index or null if it is not yet780 *     loaded (It should start downloading the item in that case).781 *782 * getLength: function() -> number The data legnth to which the repeater container783 *     should be sized. Ideally, when the count is known, this method should return it.784 *     Otherwise, return a higher number than the currently loaded items to produce an785 *     infinite-scroll behavior.786 *787 * @usage788 * <hljs lang="html">789 *  <md-virtual-repeat-container md-orient-horizontal>790 *    <div md-virtual-repeat="i in items" md-on-demand>791 *      Hello {{i}}!792 *    </div>793 *  </md-virtual-repeat-container>794 * </hljs>795 *796 */797function VirtualRepeatModelArrayLike(model) {798  if (!angular.isFunction(model.getItemAtIndex) ||799      !angular.isFunction(model.getLength)) {800    throw Error('When md-on-demand is enabled, the Object passed to md-virtual-repeat must implement ' +801        'functions getItemAtIndex() and getLength() ');802  }803  this.model = model;804}805VirtualRepeatModelArrayLike.prototype.$$includeIndexes = function(start, end) {806  for (var i = start; i < end; i++) {807    if (!this.hasOwnProperty(i)) {808      this[i] = this.model.getItemAtIndex(i);809    }810  }811  this.length = this.model.getLength();812};813function abstractMethod() {814  throw Error('Non-overridden abstract method called.');815}...es3fSamplerObjectTests.js
Source:es3fSamplerObjectTests.js  
1/*-------------------------------------------------------------------------2 * drawElements Quality Program OpenGL ES Utilities3 * ------------------------------------------------4 *5 * Copyright 2014 The Android Open Source Project6 *7 * Licensed under the Apache License, Version 2.0 (the 'License');8 * you may not use this file except in compliance with the License.9 * You may obtain a copy of the License at10 *11 *      http://www.apache.org/licenses/LICENSE-2.012 *13 * Unless required by applicable law or agreed to in writing, software14 * distributed under the License is distributed on an 'AS IS' BASIS,15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.16 * See the License for the specific language governing permissions and17 * limitations under the License.18 *19 */20'use strict';21goog.provide('functional.gles3.es3fSamplerObjectTests');22goog.require('framework.common.tcuTestCase');23goog.require('modules.shared.glsSamplerObjectTest');24goog.scope(function() {25var es3fSamplerObjectTests = functional.gles3.es3fSamplerObjectTests;26var tcuTestCase = framework.common.tcuTestCase;27var glsSamplerObjectTest = modules.shared.glsSamplerObjectTest;28    /** @type {WebGL2RenderingContext} */ var gl;29    // TODO: implement glsSamplerObjectTest and validate constructors30    es3fSamplerObjectTests.init = function() {31        var testGroup = tcuTestCase.runner.testCases;32        /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var simpleTestCases = [33            new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_2D,34                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),35                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)36            ),37            new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_2D,38                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),39                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)40            ),41            new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_2D,42                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),43                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)44            ),45            new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_2D,46                new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),47                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)48            ),49            new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_2D,50                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),51                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)52            ),53            new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_2D,54                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),55                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)56            ),57            new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_2D,58                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),59                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)60            )61        ];62        /** @type {tcuTestCase.DeqpTest} */ var simpleTexture2D = tcuTestCase.newTest('single_tex_2d', 'Simple 2D texture with sampler');63        for (var testNdx = 0; testNdx < simpleTestCases.length; testNdx++)64            simpleTexture2D.addChild(new glsSamplerObjectTest.TextureSamplerTest(simpleTestCases[testNdx]));65        testGroup.addChild(simpleTexture2D);66        /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var multiTestCases = [67            new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_2D,68                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),69                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),70                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)71            ),72            new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_2D,73                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),74                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),75                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)76            ),77            new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_2D,78                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),79                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),80                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)81            ),82            new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_2D,83                    new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),84                    new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),85                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)86            ),87            new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_2D,88                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),89                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),90                    new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)91            ),92            new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_2D,93                    new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),94                    new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),95                    new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)96            ),97            new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_2D,98                    new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),99                    new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),100                    new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)101            )102        ];103        /** @type {tcuTestCase.DeqpTest} */ var multiTexture2D = tcuTestCase.newTest('multi_tex_2d', 'Multiple texture units 2D texture with sampler');104        for (var testNdx = 0; testNdx < multiTestCases.length; testNdx++)105            multiTexture2D.addChild(new glsSamplerObjectTest.MultiTextureSamplerTest(multiTestCases[testNdx]));106        testGroup.addChild(multiTexture2D);107        /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var simpleTestCases3D = [108        new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_3D,109                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),110                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)111            ),112            new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_3D,113                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),114                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)115            ),116            new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_3D,117                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),118                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)119            ),120            new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_3D,121                new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),122                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)123            ),124            new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_3D,125                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),126                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)127            ),128            new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_3D,129                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),130                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)131            ),132            new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_3D,133                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),134                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)135            )136        ];137        /** @type {tcuTestCase.DeqpTest} */ var simpleTexture3D = tcuTestCase.newTest('single_tex_3d', 'Simple 3D texture with sampler');138        for (var testNdx = 0; testNdx < simpleTestCases3D.length; testNdx++)139            simpleTexture3D.addChild(new glsSamplerObjectTest.TextureSamplerTest(simpleTestCases3D[testNdx]));140        testGroup.addChild(simpleTexture3D);141        /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var multiTestCases3D = [142            new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_3D,143                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),144                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),145                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)146            ),147            new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_3D,148                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),149                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),150                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)151            ),152            new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_3D,153                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),154                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),155                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)156            ),157            new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_3D,158                new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),159                new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),160                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)161            ),162            new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_3D,163                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),164                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),165                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)166            ),167            new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_3D,168                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),169                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),170                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)171            ),172            new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_3D,173                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),174                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),175                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)176            )177        ];178        /** @type {tcuTestCase.DeqpTest} */ var multiTexture3D = tcuTestCase.newTest('multi_tex_3d', 'Multiple texture units 3D texture with sampler');179        for (var testNdx = 0; testNdx < multiTestCases3D.length; testNdx++)180            multiTexture3D.addChild(new glsSamplerObjectTest.MultiTextureSamplerTest(multiTestCases3D[testNdx]));181        testGroup.addChild(multiTexture3D);182        /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var simpleTestCasesCube = [183            new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_CUBE_MAP,184                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),185                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)186            ),187            new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_CUBE_MAP,188                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),189                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)190            ),191            new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_CUBE_MAP,192                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),193                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)194            ),195            new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_CUBE_MAP,196                new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),197                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)198            ),199            new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_CUBE_MAP,200                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),201                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)202            ),203            new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_CUBE_MAP,204                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),205                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)206            ),207            new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_CUBE_MAP,208                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),209                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)210            )211        ];212        /** @type {tcuTestCase.DeqpTest} */ var simpleTextureCube = tcuTestCase.newTest('single_cubemap', 'Simple cubemap texture with sampler');213        for (var testNdx = 0; testNdx < simpleTestCasesCube.length; testNdx++)214            simpleTextureCube.addChild(new glsSamplerObjectTest.TextureSamplerTest(simpleTestCasesCube[testNdx]));215        testGroup.addChild(simpleTextureCube);216        /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var multiTestCasesCube = [217            new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_CUBE_MAP,218                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),219                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),220                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)221            ),222            new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_CUBE_MAP,223                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),224                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),225                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)226            ),227            new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_CUBE_MAP,228                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),229                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),230                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)231            ),232            new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_CUBE_MAP,233                new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),234                new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),235                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)236            ),237            new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_CUBE_MAP,238                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),239                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),240                new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)241            ),242            new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_CUBE_MAP,243                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),244                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),245                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)246            ),247            new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_CUBE_MAP,248                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),249                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),250                new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)251            )252        ];253        /** @type {tcuTestCase.DeqpTest} */ var multiTextureCube = tcuTestCase.newTest('multi_cubemap', 'Multiple texture units cubemap textures with sampler');254        for (var testNdx = 0; testNdx < multiTestCasesCube.length; testNdx++)255            multiTextureCube.addChild(new glsSamplerObjectTest.MultiTextureSamplerTest(multiTestCasesCube[testNdx]));256        testGroup.addChild(multiTextureCube);257    };258    es3fSamplerObjectTests.run = function(context) {259        gl = context;260        //Set up Test Root parameters261        var testName = 'sampler_object';262        var testDescription = 'Sampler Object Tests';263        var state = tcuTestCase.runner;264        state.testName = testName;265        state.setRoot(tcuTestCase.newTest(testName, testDescription, null));266        //Set up name and description of this test series.267        setCurrentTestName(testName);268        description(testDescription);269        try {270            //Create test cases271            es3fSamplerObjectTests.init();272            //Run test cases273            tcuTestCase.runTestCases();274        }275        catch (err) {276            testFailedOptions('Failed to es3fSamplerObjectTests.run tests', false);277            tcuTestCase.runner.terminate();278        }279    };...knockout-repeat.js
Source:knockout-repeat.js  
1// REPEAT binding for Knockout http://knockoutjs.com/2// (c) Michael Best3// License: MIT (http://www.opensource.org/licenses/mit-license.php)4// Version 2.1.05(function(factory) {6    if (typeof define === 'function' && define.amd) {7        // [1] AMD anonymous module8        define(['knockout'], factory);9    } else if (typeof exports === 'object') {10        // [2] commonJS11        factory(require('knockout'));12    } else {13        // [3] No module loader (plain <script> tag) - put directly in global namespace14        factory(window.ko);15    }16})(function(ko) {17if (!ko.virtualElements)18    throw Error('Repeat requires at least Knockout 2.1');19var ko_bindingFlags = ko.bindingFlags || {};20var ko_unwrap = ko.utils.unwrapObservable;21var koProtoName = '__ko_proto__';22if (ko.version >= "3.0.0") {23    // In Knockout 3.0.0, use the node preprocessor to replace a node with a repeat binding with a virtual element24    var provider = ko.bindingProvider.instance, previousPreprocessFn = provider.preprocessNode;25    provider.preprocessNode = function(node) {26        var newNodes, nodeBinding;27        if (!previousPreprocessFn || !(newNodes = previousPreprocessFn.call(this, node))) {28            if (node.nodeType === 1 && (nodeBinding = node.getAttribute('data-bind'))) {29                if (/^\s*repeat\s*:/.test(nodeBinding)) {30                    var leadingComment = node.ownerDocument.createComment('ko ' + nodeBinding),31                        trailingComment = node.ownerDocument.createComment('/ko');32                    node.parentNode.insertBefore(leadingComment, node);33                    node.parentNode.insertBefore(trailingComment, node.nextSibling);34                    node.removeAttribute('data-bind');35                    newNodes = [leadingComment, node, trailingComment];36                }37            }38        }39        return newNodes;40    };41}42ko.virtualElements.allowedBindings.repeat = true;43ko.bindingHandlers.repeat = {44    flags: ko_bindingFlags.contentBind | ko_bindingFlags.canUseVirtual,45    init: function(element, valueAccessor, allBindingsAccessor, xxx, bindingContext) {46        // Read and set fixed options--these options cannot be changed47        var repeatParam = ko_unwrap(valueAccessor());48        if (repeatParam && typeof repeatParam == 'object' && !('length' in repeatParam)) {49            var repeatIndex = repeatParam.index,50                repeatData = repeatParam.item,51                repeatStep = repeatParam.step,52                repeatReversed = repeatParam.reverse,53                repeatBind = repeatParam.bind,54                repeatInit = repeatParam.init,55                repeatUpdate = repeatParam.update;56        }57        // Set default values for options that need it58        repeatIndex = repeatIndex || '$index';59        repeatData = repeatData || ko.bindingHandlers.repeat.itemName || '$item';60        repeatStep = repeatStep || 1;61        repeatReversed = repeatReversed || false;62        var parent = element.parentNode, placeholder;63        if (element.nodeType == 8) {    // virtual element64            // Extract the "children" and find the single element node65            var childNodes = ko.utils.arrayFilter(ko.virtualElements.childNodes(element), function(node) { return node.nodeType == 1;});66            if (childNodes.length !== 1) {67                throw Error("Repeat binding requires a single element to repeat");68            }69            ko.virtualElements.emptyNode(element);70            // The placeholder is the closing comment normally, or the opening comment if reversed71            placeholder = repeatReversed ? element : element.nextSibling;72            // The element to repeat is the contained element73            element = childNodes[0];74        } else {    // regular element75            // First clean the element node and remove node's binding76            var origBindString = element.getAttribute('data-bind');77            ko.cleanNode(element);78            element.removeAttribute('data-bind');79            // Original element is no longer needed: delete it and create a placeholder comment80            placeholder = element.ownerDocument.createComment('ko_repeatplaceholder ' + origBindString);81            parent.replaceChild(placeholder, element);82        }83        // extract and remove a data-repeat-bind attribute, if present84        if (!repeatBind) {85            repeatBind = element.getAttribute('data-repeat-bind');86            if (repeatBind) {87                element.removeAttribute('data-repeat-bind');88            }89        }90        // Make a copy of the element node to be copied for each repetition91        var cleanNode = element.cloneNode(true);92        if (typeof repeatBind == "string") {93            cleanNode.setAttribute('data-bind', repeatBind);94            repeatBind = null;95        }96        // Set up persistent data97        var lastRepeatCount = 0,98            notificationObservable = ko.observable(),99            repeatArray, arrayObservable;100        if (repeatInit) {101            repeatInit(parent);102        }103        var subscribable = ko.computed(function() {104            function makeArrayItemAccessor(index) {105                var f = function(newValue) {106                    var item = repeatArray[index];107                    // Reading the value of the item108                    if (!arguments.length) {109                        notificationObservable();   // for dependency tracking110                        return ko_unwrap(item);111                    }112                    // Writing a value to the item113                    if (ko.isObservable(item)) {114                        item(newValue);115                    } else if (arrayObservable && arrayObservable.splice) {116                        arrayObservable.splice(index, 1, newValue);117                    } else {118                        repeatArray[index] = newValue;119                    }120                    return this;121                };122                // Pretend that our accessor function is an observable123                f[koProtoName] = ko.observable;124                return f;125            }126            function makeBinding(item, index, context) {127                return repeatArray128                    ? function() { return repeatBind.call(bindingContext.$data, item, index, context); }129                    : function() { return repeatBind.call(bindingContext.$data, index, context); }130            }131            // Read and set up variable options--these options can change and will update the binding132            var paramObservable = valueAccessor(), repeatParam = ko_unwrap(paramObservable), repeatCount = 0;133            if (repeatParam && typeof repeatParam == 'object') {134                if ('length' in repeatParam) {135                    repeatArray = repeatParam;136                    repeatCount = repeatArray.length;137                } else {138                    if ('foreach' in repeatParam) {139                        repeatArray = ko_unwrap(paramObservable = repeatParam.foreach);140                        if (repeatArray && typeof repeatArray == 'object' && 'length' in repeatArray) {141                            repeatCount = repeatArray.length || 0;142                        } else {143                            repeatCount = repeatArray || 0;144                            repeatArray = null;145                        }146                    }147                    // If a count value is provided (>0), always output that number of items148                    if ('count' in repeatParam)149                        repeatCount = ko_unwrap(repeatParam.count) || repeatCount;150                    // If a limit is provided, don't output more than the limit151                    if ('limit' in repeatParam)152                        repeatCount = Math.min(repeatCount, ko_unwrap(repeatParam.limit)) || repeatCount;153                }154                arrayObservable = repeatArray && ko.isObservable(paramObservable) ? paramObservable : null;155            } else {156                repeatCount = repeatParam || 0;157            }158            // Remove nodes from end if array is shorter159            for (; lastRepeatCount > repeatCount; lastRepeatCount-=repeatStep) {160                ko.removeNode(repeatReversed ? placeholder.nextSibling : placeholder.previousSibling);161            }162            // Notify existing nodes of change163            notificationObservable.notifySubscribers();164            // Add nodes to end if array is longer (also initially populates nodes)165            for (; lastRepeatCount < repeatCount; lastRepeatCount+=repeatStep) {166                // Clone node and add to document167                var newNode = cleanNode.cloneNode(true);168                parent.insertBefore(newNode, repeatReversed ? placeholder.nextSibling : placeholder);169                newNode.setAttribute('data-repeat-index', lastRepeatCount);170                // Apply bindings to inserted node171                if (repeatArray && repeatData == '$data') {172                    var newContext = bindingContext.createChildContext(makeArrayItemAccessor(lastRepeatCount));173                } else {174                    var newContext = bindingContext.extend();175                    if (repeatArray)176                        newContext[repeatData] = makeArrayItemAccessor(lastRepeatCount);177                }178                newContext[repeatIndex] = lastRepeatCount;179                if (repeatBind) {180                    var result = ko.applyBindingsToNode(newNode, makeBinding(newContext[repeatData], lastRepeatCount, newContext), newContext, true),181                        shouldBindDescendants = result && result.shouldBindDescendants;182                }183                if (!repeatBind || (result && shouldBindDescendants !== false)) {184                    ko.applyBindings(newContext, newNode);185                }186            }187            if (repeatUpdate) {188                repeatUpdate(parent);189            }190        }, null, {disposeWhenNodeIsRemoved: placeholder});191        return { controlsDescendantBindings: true, subscribable: subscribable };192    }193};...string-repeat.js
Source:string-repeat.js  
...40assertEquals("1,2,3", String.prototype.repeat.apply([1, 2, 3], [1]));41assertEquals("true", String.prototype.repeat.apply(true, [1]));42assertEquals("false", String.prototype.repeat.apply(false, [1]));43assertEquals("[object Object]", String.prototype.repeat.apply({}, [1]));44assertEquals("\u10D8\u10D8\u10D8", "\u10D8".repeat(3));45assertThrows('String.prototype.repeat.call(null, 1)', TypeError);46assertThrows('String.prototype.repeat.call(undefined, 1)', TypeError);47assertThrows('String.prototype.repeat.apply(null, [1])', TypeError);48assertThrows('String.prototype.repeat.apply(undefined, [1])', TypeError);49// Test cases found in FF50assertEquals("abc", "abc".repeat(1));51assertEquals("abcabc", "abc".repeat(2));52assertEquals("abcabcabc", "abc".repeat(3));53assertEquals("aaaaaaaaaa", "a".repeat(10));54assertEquals("", "".repeat(5));55assertEquals("", "abc".repeat(0));56assertEquals("abcabc", "abc".repeat(2.0));57assertThrows('"a".repeat(-1)', RangeError);58assertThrows('"a".repeat(Number.POSITIVE_INFINITY)', RangeError);59var myobj = {60  toString: function() {61    return "abc";62  },63  repeat : String.prototype.repeat64};65assertEquals("abc", myobj.repeat(1));...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
