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!!