{"action":"created","comment":{"url":"https://api.github.com/repos/dhilt/HILT/pulls/comments/35867953","id":35867953,"diff_hunk":"@@ -0,0 +1,511 @@\n+###!\n+globals: angular, window\n+\n+\tList of used element methods available in JQuery but not in JQuery Lite\n+\n+\t\telement.before(elem)\n+\t\telement.height()\n+\t\telement.outerHeight(true)\n+\t\telement.height(value) = only for Top/Bottom padding elements\n+\t\telement.scrollTop()\n+\t\telement.scrollTop(value)\n+\n+###\n+\n+angular.module('ui.scroll', [])\n+\n+.directive( 'uiScrollViewport', ->\n+\tcontroller: [\n+\t\t'$scope', '$element'\n+\t\t(scope, element) ->\n+\t\t\tthis.viewport = element\n+\t\t\tthis\n+\t]\n+)\n+\n+.directive( 'uiScroll', [\n+\t'$log', '$injector', '$rootScope', '$timeout', '$q', '$parse'\n+\t(console, $injector, $rootScope, $timeout, $q, $parse) ->\n+\n+\t\t$animate = $injector.get('$animate') if $injector.has && $injector.has('$animate')\n+\n+\t\trequire: ['?^uiScrollViewport']\n+\t\ttransclude: 'element'\n+\t\tpriority: 1000\n+\t\tterminal: true\n+\n+\t\tcompile: (elementTemplate, attr, linker) ->\n+\t\t\t($scope, element, $attr, controllers) ->\n+\n+\t\t\t\tlog = console.debug || console.log\n+\n+\t\t\t\tunless match = $attr.uiScroll.match(/^\\s*(\\w+)\\s+in\\s+([\\w\\.]+)\\s*$/)\n+\t\t\t\t\tthrow new Error 'Expected uiScroll in form of \\'_item_ in _datasource_\\' but got \\' + $attr.uiScroll + \\''\n+\t\t\t\titemName = match[1]\n+\t\t\t\tdatasourceName = match[2]\n+\n+\t\t\t\todd = null\n+\n+\t\t\t\tdatasource = $parse(datasourceName)($scope)\n+\t\t\t\tisDatasourceValid = () -> angular.isObject(datasource) and angular.isFunction(datasource.get)\n+\t\t\t\tif !isDatasourceValid() # then try to inject datasource as service\n+\t\t\t\t\tdatasource = $injector.get(datasourceName)\n+\t\t\t\t\tif !isDatasourceValid()\n+\t\t\t\t\t\tthrow new Error datasourceName + ' is not a valid datasource'\n+\n+\t\t\t\tbufferSize = Math.max(3, +$attr.bufferSize || 10)\n+\t\t\t\tbufferPadding = -> viewport.outerHeight() * Math.max(0.1, +$attr.padding || 0.1) # some extra space to initiate preload\n+\n+\t\t\t\tscrollHeight = (elem)->\n+\t\t\t\t\telem[0].scrollHeight ? elem[0].document.documentElement.scrollHeight\n+\n+\t\t\t\t# initial settings\n+\n+\t\t\t\tbuilder = null\n+\t\t\t\tridActual = 0 # current data revision id\n+\t\t\t\tfirst = 1\n+\t\t\t\tnext = 1\n+\t\t\t\tbuffer = []\n+\t\t\t\tpending = []\n+\t\t\t\teof = false\n+\t\t\t\tbof = false\n+\n+\t\t\t\t# Element manipulation routines\n+\n+\t\t\t\tremoveItem =\n+\t\t\t\t\tif $animate\n+\t\t\t\t\t\tif angular.version.minor == 2\n+\t\t\t\t\t\t\t(wrapper) ->\n+\t\t\t\t\t\t\t\tbuffer.splice buffer.indexOf(wrapper), 1\n+\t\t\t\t\t\t\t\tdeferred = $q.defer()\n+\t\t\t\t\t\t\t\t$animate.leave wrapper.element, ->\n+\t\t\t\t\t\t\t\t\twrapper.scope.$destroy()\n+\t\t\t\t\t\t\t\t\tdeferred.resolve()\n+\t\t\t\t\t\t\t\t[deferred.promise]\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t(wrapper) ->\n+\t\t\t\t\t\t\t\tbuffer.splice buffer.indexOf(wrapper), 1\n+\t\t\t\t\t\t\t\t[($animate.leave wrapper.element).then ->\n+\t\t\t\t\t\t\t\t\twrapper.scope.$destroy()\n+\t\t\t\t\t\t\t\t]\n+\t\t\t\t\telse\n+\t\t\t\t\t\t(wrapper) ->\n+\t\t\t\t\t\t\tbuffer.splice buffer.indexOf(wrapper), 1\n+\t\t\t\t\t\t\twrapper.element.remove()\n+\t\t\t\t\t\t\twrapper.scope.$destroy()\n+\t\t\t\t\t\t\t[]\n+\n+\t\t\t\tinsertElement =\n+\t\t\t\t\t(newElement, previousElement) ->\n+\t\t\t\t\t\telement.after.apply(previousElement, newElement)\n+\t\t\t\t\t\t[]\n+\n+\t\t\t\tinsertElementAnimated =\n+\t\t\t\t\tif $animate\n+\t\t\t\t\t\tif angular.version.minor == 2\n+\t\t\t\t\t\t\t(newElement, previousElement) ->\n+\t\t\t\t\t\t\t\tdeferred = $q.defer()\n+\t\t\t\t\t\t\t\t$animate.enter newElement, element, previousElement, -> deferred.resolve()\n+\t\t\t\t\t\t\t\t[deferred.promise]\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t(newElement, previousElement) ->\n+\t\t\t\t\t\t\t\t[$animate.enter newElement, element, previousElement]\n+\n+\t\t\t\t\telse insertElement\n+\n+\t\t\t\t# Element builder\n+\t\t\t\t#\n+\t\t\t\t# Calling linker is the only way I found to get access to the tag name of the template\n+\t\t\t\t# to prevent the directive scope from pollution a new scope is created and destroyed\n+\t\t\t\t# right after the repeaterHandler creation is completed\n+\t\t\t\tlinker $scope.$new(), (template) ->\n+\n+\t\t\t\t\trepeaterType = template[0].localName\n+\t\t\t\t\tif repeaterType in ['dl']\n+\t\t\t\t\t\tthrow new Error 'ui-scroll directive does not support <' + template[0].localName + '> as a repeating tag: ' + template[0].outerHTML\n+\t\t\t\t\trepeaterType = 'div' if repeaterType not in ['li', 'tr']\n+\n+\t\t\t\t\tviewport = if controllers[0] and controllers[0].viewport then controllers[0].viewport else angular.element(window)\n+\t\t\t\t\tviewport.css({'overflow-y': 'auto', 'display': 'block'})\n+\n+\t\t\t\t\tpadding = (repeaterType)->\n+\t\t\t\t\t\tswitch repeaterType\n+\t\t\t\t\t\t\twhen 'tr'\n+\t\t\t\t\t\t\t\ttable = angular.element('<table><tr><td><div></div></td></tr></table>')\n+\t\t\t\t\t\t\t\tdiv = table.find('div')\n+\t\t\t\t\t\t\t\tresult = table.find('tr')\n+\t\t\t\t\t\t\t\tresult.paddingHeight = -> div.height.apply(div, arguments)\n+\t\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t\tresult = angular.element('<' + repeaterType + '></' + repeaterType + '>')\n+\t\t\t\t\t\t\t\tresult.paddingHeight = result.height\n+\t\t\t\t\t\tresult\n+\n+\t\t\t\t\ttopPadding = padding(repeaterType)\n+\t\t\t\t\telement.before topPadding\n+\n+\t\t\t\t\tbottomPadding = padding(repeaterType)\n+\t\t\t\t\telement.after bottomPadding\n+\n+\t\t\t\t\t$scope.$on '$destroy', -> template.remove()\n+\n+\t\t\t\t\tbuilder =\n+\t\t\t\t\t\tviewport: viewport\n+\t\t\t\t\t\ttopPadding: -> topPadding.paddingHeight.apply(topPadding, arguments)\n+\t\t\t\t\t\tbottomPadding: -> bottomPadding.paddingHeight.apply(bottomPadding, arguments)\n+\t\t\t\t\t\tinsertElement: (e, sibling) -> insertElement(e, sibling || topPadding)\n+\t\t\t\t\t\tinsertElementAnimated: (e, sibling) -> insertElementAnimated(e, sibling || topPadding)\n+\t\t\t\t\t\tbottomDataPos: ->\n+\t\t\t\t\t\t\tscrollHeight(viewport) - bottomPadding.paddingHeight()\n+\t\t\t\t\t\ttopDataPos: ->\n+\t\t\t\t\t\t\ttopPadding.paddingHeight()\n+\n+\t\t\t\tviewport = builder.viewport\n+\n+\t\t\t\tviewportScope = viewport.scope() || $rootScope\n+\n+\t\t\t\ttopVisible = (item) ->\n+\t\t\t\t\tadapter.topVisible = item.scope[itemName]\n+\t\t\t\t\tadapter.topVisibleElement = item.element\n+\t\t\t\t\tadapter.topVisibleScope = item.scope\n+\t\t\t\t\t$parse($attr.topVisible).assign(viewportScope, adapter.topVisible) if $attr.topVisible\n+\t\t\t\t\t$parse($attr.topVisibleElement).assign(viewportScope, adapter.topVisibleElement) if $attr.topVisibleElement\n+\t\t\t\t\t$parse($attr.topVisibleScope).assign(viewportScope, adapter.topVisibleScope) if $attr.topVisibleScope\n+\t\t\t\t\tdatasource.topVisible(item) if angular.isFunction(datasource.topVisible)\n+\n+\t\t\t\tloading = (value) ->\n+\t\t\t\t\tadapter.isLoading = value\n+\t\t\t\t\t$parse($attr.isLoading).assign($scope, value) if $attr.isLoading\n+\t\t\t\t\tdatasource.loading(value) if angular.isFunction(datasource.loading)\n+\n+\t\t\t\t#removes items from start (including) through stop (excluding)\n+\t\t\t\tremoveFromBuffer = (start, stop)->\n+\t\t\t\t\tfor i in [start...stop]\n+\t\t\t\t\t\tbuffer[i].scope.$destroy()\n+\t\t\t\t\t\tbuffer[i].element.remove()\n+\t\t\t\t\tbuffer.splice start, stop - start\n+\n+\t\t\t\tdismissPendingRequests = () ->\n+\t\t\t\t\tridActual++\n+\t\t\t\t\tpending = []\n+\n+\t\t\t\treload = ->\n+\t\t\t\t\tdismissPendingRequests()\n+\t\t\t\t\tfirst = 1\n+\t\t\t\t\tnext = 1\n+\t\t\t\t\tremoveFromBuffer(0, buffer.length)\n+\t\t\t\t\tbuilder.topPadding(0)\n+\t\t\t\t\tbuilder.bottomPadding(0)\n+\t\t\t\t\teof = false\n+\t\t\t\t\tbof = false\n+\t\t\t\t\tadjustBuffer ridActual\n+\n+\t\t\t\tbottomVisiblePos = ->\n+\t\t\t\t\tviewport.scrollTop() + viewport.outerHeight()\n+\n+\t\t\t\ttopVisiblePos = ->\n+\t\t\t\t\tviewport.scrollTop()\n+\n+\t\t\t\tshouldLoadBottom = ->\n+\t\t\t\t\t!eof && builder.bottomDataPos() < bottomVisiblePos() + bufferPadding()\n+\n+\t\t\t\tclipBottom = ->\n+\t\t\t\t\t# clip the invisible items off the bottom\n+\t\t\t\t\tbottomHeight = 0 #builder.bottomPadding()\n+\t\t\t\t\toverage = 0\n+\n+\t\t\t\t\tfor i in [buffer.length-1..0]\n+\t\t\t\t\t\titem = buffer[i]\n+\t\t\t\t\t\titemTop = item.element.offset().top\n+\t\t\t\t\t\tnewRow = rowTop isnt itemTop\n+\t\t\t\t\t\trowTop = itemTop\n+\t\t\t\t\t\titemHeight = item.element.outerHeight(true) if newRow\n+\t\t\t\t\t\tif (builder.bottomDataPos() - bottomHeight - itemHeight > bottomVisiblePos() + bufferPadding())\n+\t\t\t\t\t\t\tbottomHeight += itemHeight if newRow\n+\t\t\t\t\t\t\toverage++\n+\t\t\t\t\t\t\teof = false\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\tbreak if newRow\n+\t\t\t\t\t\t\toverage++\n+\n+\t\t\t\t\tif overage > 0\n+\t\t\t\t\t\tbuilder.bottomPadding(builder.bottomPadding() + bottomHeight)\n+\t\t\t\t\t\tremoveFromBuffer(buffer.length - overage, buffer.length)\n+\t\t\t\t\t\tnext -= overage\n+\t\t\t\t\t\t#log 'clipped off bottom ' + overage + ' bottom padding ' + builder.bottomPadding()\n+\n+\t\t\t\tshouldLoadTop = ->\n+\t\t\t\t\t!bof && (builder.topDataPos() > topVisiblePos() - bufferPadding())\n+\n+\t\t\t\tclipTop = ->\n+\t\t\t\t\t# clip the invisible items off the top\n+\t\t\t\t\ttopHeight = 0\n+\t\t\t\t\toverage = 0\n+\t\t\t\t\tfor item in buffer\n+\t\t\t\t\t\titemTop = item.element.offset().top\n+\t\t\t\t\t\tnewRow = rowTop isnt itemTop\n+\t\t\t\t\t\trowTop = itemTop\n+\t\t\t\t\t\titemHeight = item.element.outerHeight(true) if newRow\n+\t\t\t\t\t\tif (builder.topDataPos() + topHeight + itemHeight < topVisiblePos() - bufferPadding())\n+\t\t\t\t\t\t\ttopHeight += itemHeight if newRow\n+\t\t\t\t\t\t\toverage++\n+\t\t\t\t\t\t\tbof = false\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\tbreak if newRow\n+\t\t\t\t\t\t\toverage++\n+\t\t\t\t\tif overage > 0\n+\t\t\t\t\t\tbuilder.topPadding(builder.topPadding() + topHeight)\n+\t\t\t\t\t\tremoveFromBuffer(0, overage)\n+\t\t\t\t\t\tfirst += overage\n+\t\t\t\t\t\t#log 'clipped off top ' + overage + ' top padding ' + builder.topPadding()\n+\n+\t\t\t\tenqueueFetch = (rid, direction)->\n+\t\t\t\t\tif (!adapter.isLoading)\n+\t\t\t\t\t\tloading(true)\n+\t\t\t\t\tif pending.push(direction) == 1\n+\t\t\t\t\t\tfetch(rid)\n+\n+\t\t\t\tinsertItem = (operation, item) ->\n+\t\t\t\t\titemScope = $scope.$new()\n+\t\t\t\t\titemScope[itemName] = item\n+\t\t\t\t\twrapper =\n+\t\t\t\t\t\tscope: itemScope\n+\n+\t\t\t\t\tlinker itemScope, (clone) ->\n+\t\t\t\t\t\twrapper.element = clone\n+\n+\t\t\t\t\t# operations: 'append', 'prepend', 'insert', 'remove', 'update', 'none'\n+\t\t\t\t\tif (operation%1 == 0) # it is an insert\n+\t\t\t\t\t\twrapper.op = 'insert'\n+\t\t\t\t\t\tbuffer.splice operation, 0, wrapper\n+\t\t\t\t\telse\n+\t\t\t\t\t\twrapper.op = operation\n+\t\t\t\t\t\tswitch operation\n+\t\t\t\t\t\t\twhen 'append' then buffer.push wrapper\n+\t\t\t\t\t\t\twhen 'prepend' then buffer.unshift wrapper\n+\n+\t\t\t\tadjustBuffer = (rid, finalize) ->\n+\n+\t\t\t\t\tpromises = []\n+\t\t\t\t\ttoBePrepended = []\n+\t\t\t\t\ttoBeRemoved = []\n+\n+\t\t\t\t\tfor wrapper, i in buffer\n+\t\t\t\t\t\tswitch wrapper.op\n+\t\t\t\t\t\t\twhen 'prepend' then toBePrepended.unshift wrapper\n+\t\t\t\t\t\t\twhen 'append'\n+\t\t\t\t\t\t\t\tif (i == 0)\n+\t\t\t\t\t\t\t\t\tbuilder.insertElement wrapper.element\n+\t\t\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t\t\tbuilder.insertElement wrapper.element, buffer[i-1].element\n+\t\t\t\t\t\t\t\tbuilder.bottomPadding(Math.max(0,builder.bottomPadding() - wrapper.element.outerHeight(true)))\n+\t\t\t\t\t\t\t\twrapper.op = 'none'\n+\t\t\t\t\t\t\twhen 'insert'\n+\t\t\t\t\t\t\t\tif (i == 0)\n+\t\t\t\t\t\t\t\t\tpromises = promises.concat (builder.insertElementAnimated wrapper.element)\n+\t\t\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t\t\tpromises = promises.concat (builder.insertElementAnimated wrapper.element, buffer[i-1].element)\n+\t\t\t\t\t\t\t\tbuilder.bottomPadding(Math.max(0,builder.bottomPadding() - wrapper.element.outerHeight(true)))\n+\t\t\t\t\t\t\t\twrapper.op = 'none'\n+\t\t\t\t\t\t\twhen 'remove' then toBeRemoved.push wrapper\n+\n+\t\t\t\t\t# We need the item bindings to be processed before we can do adjustment\n+\t\t\t\t\t$timeout ->\n+\n+\t\t\t\t\t\tif toBePrepended.length\n+\t\t\t\t\t\t\tbottomPos = buffer[buffer.length-1].element.offset().top;\n+\n+\t\t\t\t\t\tfor wrapper in toBePrepended\n+\t\t\t\t\t\t\tbuilder.insertElement wrapper.element\n+\t\t\t\t\t\t\twrapper.op = 'none'\n+\n+\t\t\t\t\t\tif toBePrepended.length\n+\t\t\t\t\t\t\theightIncrement = buffer[buffer.length-1].element.offset().top - bottomPos\n+\t\t\t\t\t\t\t# adjust padding to prevent it from visually pushing everything down\n+\t\t\t\t\t\t\tif builder.topPadding() >= heightIncrement\n+\t\t\t\t\t\t\t\t# if possible, reduce topPadding\n+\t\t\t\t\t\t\t\tbuilder.topPadding(builder.topPadding() - heightIncrement)\n+\t\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t\t# if not, increment scrollTop\n+\t\t\t\t\t\t\t\tviewport.scrollTop(viewport.scrollTop() + heightIncrement)\n+\n+\t\t\t\t\t\tfor wrapper in toBeRemoved\n+\t\t\t\t\t\t\tpromises = promises.concat (removeItem wrapper)\n+\n+\t\t\t\t\t\t# re-index the buffer\n+\t\t\t\t\t\titem.scope.$index = first + i for item,i in buffer\n+\n+\t\t\t\t\t\t#log \"top {actual=#{builder.topDataPos()} visible from=#{topVisiblePos()} bottom {visible through=#{bottomVisiblePos()} actual=#{builder.bottomDataPos()}}\"\n+\t\t\t\t\t\tif shouldLoadBottom()\n+\t\t\t\t\t\t\tenqueueFetch(rid, true)\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\tenqueueFetch(rid, false) if shouldLoadTop()\n+\t\t\t\t\t\tfinalize(rid) if finalize\n+\t\t\t\t\t\tif pending.length == 0\n+\t\t\t\t\t\t\ttopHeight = 0\n+\t\t\t\t\t\t\tfor item in buffer\n+\t\t\t\t\t\t\t\titemTop = item.element.offset().top\n+\t\t\t\t\t\t\t\tnewRow = rowTop isnt itemTop\n+\t\t\t\t\t\t\t\trowTop = itemTop\n+\t\t\t\t\t\t\t\titemHeight = item.element.outerHeight(true) if newRow\n+\t\t\t\t\t\t\t\tif newRow and (builder.topDataPos() + topHeight + itemHeight < topVisiblePos())\n+\t\t\t\t\t\t\t\t\ttopHeight += itemHeight\n+\t\t\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t\t\ttopVisible(item) if newRow\n+\t\t\t\t\t\t\t\t\tbreak\n+\t\t\t\t\t\t# the promise from the timeout should be added to promises array\n+\t\t\t\t\t\t# I just could not make promises work with the jasmine tests\n+\t\t\t\t\t\tif (promises.length)\n+\t\t\t\t\t\t\t$q.all(promises).then ->\n+\t\t\t\t\t\t\t\t#log \"Animation completed rid #{rid}\"\n+\t\t\t\t\t\t\t\tadjustBuffer rid\n+\n+\t\t\t\tfinalize = (rid) ->\n+\t\t\t\t\tadjustBuffer rid, ->\n+\t\t\t\t\t\tpending.shift()\n+\t\t\t\t\t\tif pending.length == 0\n+\t\t\t\t\t\t\tloading(false)\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\tfetch(rid)\n+\n+\t\t\t\tfetch = (rid) ->\n+\t\t\t\t\t#log \"Running fetch... #{{true:'bottom', false: 'top'}[direction]} pending #{pending.length}\"\n+\t\t\t\t\tif pending[0] # scrolling down\n+\t\t\t\t\t\tif buffer.length && !shouldLoadBottom()\n+\t\t\t\t\t\t\tfinalize rid\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t#log \"appending... requested #{bufferSize} records starting from #{next}\"\n+\t\t\t\t\t\t\tdatasource.get next, bufferSize,\n+\t\t\t\t\t\t\t(result) ->\n+\t\t\t\t\t\t\t\treturn if (rid and rid isnt ridActual) or $scope.$$destroyed\n+\t\t\t\t\t\t\t\tif result.length < bufferSize\n+\t\t\t\t\t\t\t\t\teof = true\n+\t\t\t\t\t\t\t\t\tbuilder.bottomPadding(0)\n+\t\t\t\t\t\t\t\t\t#log 'eof is reached'\n+\t\t\t\t\t\t\t\tif result.length > 0\n+\t\t\t\t\t\t\t\t\tclipTop()\n+\t\t\t\t\t\t\t\t\tfor item in result\n+\t\t\t\t\t\t\t\t\t\t++next\n+\t\t\t\t\t\t\t\t\t\tinsertItem 'append', item\n+\t\t\t\t\t\t\t\t\t\t#log 'appended: requested ' + bufferSize + ' received ' + result.length + ' buffer size ' + buffer.length + ' first ' + first + ' next ' + next\n+\t\t\t\t\t\t\t\tfinalize rid\n+\t\t\t\t\telse\n+\t\t\t\t\t\tif buffer.length && !shouldLoadTop()\n+\t\t\t\t\t\t\tfinalize rid\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t#log \"prepending... requested #{size} records starting from #{start}\"\n+\t\t\t\t\t\t\tdatasource.get first-bufferSize, bufferSize,\n+\t\t\t\t\t\t\t(result) ->\n+\t\t\t\t\t\t\t\treturn if (rid and rid isnt ridActual) or $scope.$$destroyed\n+\t\t\t\t\t\t\t\tif result.length < bufferSize\n+\t\t\t\t\t\t\t\t\tbof = true\n+\t\t\t\t\t\t\t\t\tbuilder.topPadding(0)\n+\t\t\t\t\t\t\t\t\t#log 'bof is reached'\n+\t\t\t\t\t\t\t\tif result.length > 0\n+\t\t\t\t\t\t\t\t\tclipBottom() if buffer.length\n+\t\t\t\t\t\t\t\t\tfor i in [result.length-1..0]\n+\t\t\t\t\t\t\t\t\t\t--first\n+\t\t\t\t\t\t\t\t\t\tinsertItem 'prepend', result[i]\n+\t\t\t\t\t\t\t\t\t#log 'prepended: requested ' + bufferSize + ' received ' + result.length + ' buffer size ' + buffer.length + ' first ' + first + ' next ' + next\n+\t\t\t\t\t\t\t\tfinalize rid\n+\n+\n+\t\t\t\t# events and bindings\n+\n+\t\t\t\tresizeAndScrollHandler = ->\n+\t\t\t\t\tif !$rootScope.$$phase && !adapter.isLoading\n+\t\t\t\t\t\tadjustBuffer()\n+\t\t\t\t\t\t$scope.$apply()\n+\n+\t\t\t\twheelHandler = (event) ->\n+\t\t\t\t\tscrollTop = viewport[0].scrollTop\n+\t\t\t\t\tyMax = viewport[0].scrollHeight - viewport[0].clientHeight\n+\t\t\t\t\tif (scrollTop is 0 and not bof) or (scrollTop is yMax and not eof)\n+\t\t\t\t\t\tevent.preventDefault()\n+\n+\t\t\t\tviewport.bind 'resize', resizeAndScrollHandler\n+\t\t\t\tviewport.bind 'scroll', resizeAndScrollHandler\n+\t\t\t\tviewport.bind 'mousewheel', wheelHandler\n+\n+\t\t\t\t$scope.$watch datasource.revision, reload\n+\n+\t\t\t\t$scope.$on '$destroy', ->\n+\t\t\t\t\tfor item in buffer\n+\t\t\t\t\t\titem.scope.$destroy()\n+\t\t\t\t\t\titem.element.remove()\n+\t\t\t\t\tviewport.unbind 'resize', resizeAndScrollHandler\n+\t\t\t\t\tviewport.unbind 'scroll', resizeAndScrollHandler\n+\t\t\t\t\tviewport.unbind 'mousewheel', wheelHandler\n+\n+\n+\t\t\t\t# adapter setup\n+\n+\t\t\t\tadapter = {}\n+\t\t\t\tadapter.isLoading = false\n+\t\t\t\tadapter.reload = reload\n+\n+\t\t\t\tapplyUpdate = (wrapper, newItems) ->\n+\t\t\t\t\tif angular.isArray newItems\n+\t\t\t\t\t\tpos = (buffer.indexOf wrapper) + 1\n+\t\t\t\t\t\tfor newItem,i in newItems.reverse()\n+\t\t\t\t\t\t\tif newItem == wrapper.scope[itemName]\n+\t\t\t\t\t\t\t\tkeepIt = true;\n+\t\t\t\t\t\t\t\tpos--\n+\t\t\t\t\t\t\telse\n+\t\t\t\t\t\t\t\tinsertItem pos, newItem\n+\t\t\t\t\t\tunless keepIt\n+\t\t\t\t\t\t\twrapper.op = 'remove'\n+\n+\t\t\t\tadapter.applyUpdates = (arg1, arg2) ->\n+\t\t\t\t\tdismissPendingRequests()\n+\t\t\t\t\tif angular.isFunction arg1\n+\t\t\t\t\t\t# arg1 is the updater function, arg2 is ignored\n+\t\t\t\t\t\tbufferClone = buffer.slice(0)\n+\t\t\t\t\t\tfor wrapper,i in bufferClone  # we need to do it on the buffer clone, because buffer content\n+\t\t\t\t\t\t\t# may change as we iterate through\n+\t\t\t\t\t\t\tapplyUpdate wrapper, arg1(wrapper.scope[itemName], wrapper.scope, wrapper.element)\n+\t\t\t\t\telse\n+\t\t\t\t\t\t# arg1 is item index, arg2 is the newItems array\n+\t\t\t\t\t\tif arg1%1 == 0 # checking if it is an integer\n+\t\t\t\t\t\t\tif 0 <= arg1-first < buffer.length\n+\t\t\t\t\t\t\t\tapplyUpdate buffer[arg1 - first], arg2\n+\t\t\t\t\t\telse\n+\t\t\t\t\t\t\tthrow new Error 'applyUpdates - ' + arg1 + ' is not a valid index'\n+\t\t\t\t\tadjustBuffer ridActual\n+\n+\t\t\t\tadapter.append = (newItems) ->\n+\t\t\t\t\tdismissPendingRequests()\n+\t\t\t\t\tfor item in newItems\n+\t\t\t\t\t\t++next\n+\t\t\t\t\t\tinsertItem 'append', item\n+\t\t\t\t\tadjustBuffer ridActual\n+\n+\t\t\t\tadapter.prepend = (newItems) ->\n+\t\t\t\t\tdismissPendingRequests()\n+\t\t\t\t\tfor item in newItems.reverse()\n+\t\t\t\t\t\t--first\n+\t\t\t\t\t\tinsertItem 'prepend', item\n+\t\t\t\t\tadjustBuffer ridActual\n+\n+\t\t\t\tif $attr.adapter # so we have an adapter on $scope\n+\t\t\t\t\tadapterOnScope = $parse($attr.adapter)($scope)\n+\t\t\t\t\tif not adapterOnScope\n+\t\t\t\t\t\t$parse($attr.adapter).assign($scope, {})\n+\t\t\t\t\t\tadapterOnScope = $parse($attr.adapter)($scope)\n+\t\t\t\t\tangular.extend(adapterOnScope, adapter)","path":"ui-scroll.coffee","position":494,"original_position":494,"commit_id":"41b6270f30eba38614042d79d0e31aea2bf60b6b","original_commit_id":"41b6270f30eba38614042d79d0e31aea2bf60b6b","user":{"login":"houndci","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci","html_url":"https://github.com/houndci","followers_url":"https://api.github.com/users/houndci/followers","following_url":"https://api.github.com/users/houndci/following{/other_user}","gists_url":"https://api.github.com/users/houndci/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci/subscriptions","organizations_url":"https://api.github.com/users/houndci/orgs","repos_url":"https://api.github.com/users/houndci/repos","events_url":"https://api.github.com/users/houndci/events{/privacy}","received_events_url":"https://api.github.com/users/houndci/received_events","type":"User","site_admin":false},"body":"Line contains tab indentation","created_at":"2015-07-30T13:06:30Z","updated_at":"2015-07-30T13:06:30Z","html_url":"https://github.com/dhilt/HILT/pull/1#discussion_r35867953","pull_request_url":"https://api.github.com/repos/dhilt/HILT/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/dhilt/HILT/pulls/comments/35867953"},"html":{"href":"https://github.com/dhilt/HILT/pull/1#discussion_r35867953"},"pull_request":{"href":"https://api.github.com/repos/dhilt/HILT/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/dhilt/HILT/pulls/1","id":41231287,"html_url":"https://github.com/dhilt/HILT/pull/1","diff_url":"https://github.com/dhilt/HILT/pull/1.diff","patch_url":"https://github.com/dhilt/HILT/pull/1.patch","issue_url":"https://api.github.com/repos/dhilt/HILT/issues/1","number":1,"state":"open","locked":false,"title":"try","user":{"login":"dhilt","id":4365660,"avatar_url":"https://avatars.githubusercontent.com/u/4365660?v=3","gravatar_id":"","url":"https://api.github.com/users/dhilt","html_url":"https://github.com/dhilt","followers_url":"https://api.github.com/users/dhilt/followers","following_url":"https://api.github.com/users/dhilt/following{/other_user}","gists_url":"https://api.github.com/users/dhilt/gists{/gist_id}","starred_url":"https://api.github.com/users/dhilt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhilt/subscriptions","organizations_url":"https://api.github.com/users/dhilt/orgs","repos_url":"https://api.github.com/users/dhilt/repos","events_url":"https://api.github.com/users/dhilt/events{/privacy}","received_events_url":"https://api.github.com/users/dhilt/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-07-30T13:06:21Z","updated_at":"2015-07-30T13:06:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"dea5df4292d3e5c463352b69d8bd4bee927c7270","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dhilt/HILT/pulls/1/commits","review_comments_url":"https://api.github.com/repos/dhilt/HILT/pulls/1/comments","review_comment_url":"https://api.github.com/repos/dhilt/HILT/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dhilt/HILT/issues/1/comments","statuses_url":"https://api.github.com/repos/dhilt/HILT/statuses/41b6270f30eba38614042d79d0e31aea2bf60b6b","head":{"label":"dhilt:div","ref":"div","sha":"41b6270f30eba38614042d79d0e31aea2bf60b6b","user":{"login":"dhilt","id":4365660,"avatar_url":"https://avatars.githubusercontent.com/u/4365660?v=3","gravatar_id":"","url":"https://api.github.com/users/dhilt","html_url":"https://github.com/dhilt","followers_url":"https://api.github.com/users/dhilt/followers","following_url":"https://api.github.com/users/dhilt/following{/other_user}","gists_url":"https://api.github.com/users/dhilt/gists{/gist_id}","starred_url":"https://api.github.com/users/dhilt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhilt/subscriptions","organizations_url":"https://api.github.com/users/dhilt/orgs","repos_url":"https://api.github.com/users/dhilt/repos","events_url":"https://api.github.com/users/dhilt/events{/privacy}","received_events_url":"https://api.github.com/users/dhilt/received_events","type":"User","site_admin":false},"repo":{"id":34674875,"name":"HILT","full_name":"dhilt/HILT","owner":{"login":"dhilt","id":4365660,"avatar_url":"https://avatars.githubusercontent.com/u/4365660?v=3","gravatar_id":"","url":"https://api.github.com/users/dhilt","html_url":"https://github.com/dhilt","followers_url":"https://api.github.com/users/dhilt/followers","following_url":"https://api.github.com/users/dhilt/following{/other_user}","gists_url":"https://api.github.com/users/dhilt/gists{/gist_id}","starred_url":"https://api.github.com/users/dhilt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhilt/subscriptions","organizations_url":"https://api.github.com/users/dhilt/orgs","repos_url":"https://api.github.com/users/dhilt/repos","events_url":"https://api.github.com/users/dhilt/events{/privacy}","received_events_url":"https://api.github.com/users/dhilt/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dhilt/HILT","description":"","fork":false,"url":"https://api.github.com/repos/dhilt/HILT","forks_url":"https://api.github.com/repos/dhilt/HILT/forks","keys_url":"https://api.github.com/repos/dhilt/HILT/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dhilt/HILT/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dhilt/HILT/teams","hooks_url":"https://api.github.com/repos/dhilt/HILT/hooks","issue_events_url":"https://api.github.com/repos/dhilt/HILT/issues/events{/number}","events_url":"https://api.github.com/repos/dhilt/HILT/events","assignees_url":"https://api.github.com/repos/dhilt/HILT/assignees{/user}","branches_url":"https://api.github.com/repos/dhilt/HILT/branches{/branch}","tags_url":"https://api.github.com/repos/dhilt/HILT/tags","blobs_url":"https://api.github.com/repos/dhilt/HILT/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dhilt/HILT/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dhilt/HILT/git/refs{/sha}","trees_url":"https://api.github.com/repos/dhilt/HILT/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dhilt/HILT/statuses/{sha}","languages_url":"https://api.github.com/repos/dhilt/HILT/languages","stargazers_url":"https://api.github.com/repos/dhilt/HILT/stargazers","contributors_url":"https://api.github.com/repos/dhilt/HILT/contributors","subscribers_url":"https://api.github.com/repos/dhilt/HILT/subscribers","subscription_url":"https://api.github.com/repos/dhilt/HILT/subscription","commits_url":"https://api.github.com/repos/dhilt/HILT/commits{/sha}","git_commits_url":"https://api.github.com/repos/dhilt/HILT/git/commits{/sha}","comments_url":"https://api.github.com/repos/dhilt/HILT/comments{/number}","issue_comment_url":"https://api.github.com/repos/dhilt/HILT/issues/comments{/number}","contents_url":"https://api.github.com/repos/dhilt/HILT/contents/{+path}","compare_url":"https://api.github.com/repos/dhilt/HILT/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dhilt/HILT/merges","archive_url":"https://api.github.com/repos/dhilt/HILT/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dhilt/HILT/downloads","issues_url":"https://api.github.com/repos/dhilt/HILT/issues{/number}","pulls_url":"https://api.github.com/repos/dhilt/HILT/pulls{/number}","milestones_url":"https://api.github.com/repos/dhilt/HILT/milestones{/number}","notifications_url":"https://api.github.com/repos/dhilt/HILT/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dhilt/HILT/labels{/name}","releases_url":"https://api.github.com/repos/dhilt/HILT/releases{/id}","created_at":"2015-04-27T15:31:11Z","updated_at":"2015-04-27T15:41:20Z","pushed_at":"2015-07-30T13:06:21Z","git_url":"git://github.com/dhilt/HILT.git","ssh_url":"git@github.com:dhilt/HILT.git","clone_url":"https://github.com/dhilt/HILT.git","svn_url":"https://github.com/dhilt/HILT","homepage":null,"size":328,"stargazers_count":0,"watchers_count":0,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"dhilt:master","ref":"master","sha":"d89fde72bba8a5a056b436ba4a49c0e1d4f02375","user":{"login":"dhilt","id":4365660,"avatar_url":"https://avatars.githubusercontent.com/u/4365660?v=3","gravatar_id":"","url":"https://api.github.com/users/dhilt","html_url":"https://github.com/dhilt","followers_url":"https://api.github.com/users/dhilt/followers","following_url":"https://api.github.com/users/dhilt/following{/other_user}","gists_url":"https://api.github.com/users/dhilt/gists{/gist_id}","starred_url":"https://api.github.com/users/dhilt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhilt/subscriptions","organizations_url":"https://api.github.com/users/dhilt/orgs","repos_url":"https://api.github.com/users/dhilt/repos","events_url":"https://api.github.com/users/dhilt/events{/privacy}","received_events_url":"https://api.github.com/users/dhilt/received_events","type":"User","site_admin":false},"repo":{"id":34674875,"name":"HILT","full_name":"dhilt/HILT","owner":{"login":"dhilt","id":4365660,"avatar_url":"https://avatars.githubusercontent.com/u/4365660?v=3","gravatar_id":"","url":"https://api.github.com/users/dhilt","html_url":"https://github.com/dhilt","followers_url":"https://api.github.com/users/dhilt/followers","following_url":"https://api.github.com/users/dhilt/following{/other_user}","gists_url":"https://api.github.com/users/dhilt/gists{/gist_id}","starred_url":"https://api.github.com/users/dhilt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhilt/subscriptions","organizations_url":"https://api.github.com/users/dhilt/orgs","repos_url":"https://api.github.com/users/dhilt/repos","events_url":"https://api.github.com/users/dhilt/events{/privacy}","received_events_url":"https://api.github.com/users/dhilt/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dhilt/HILT","description":"","fork":false,"url":"https://api.github.com/repos/dhilt/HILT","forks_url":"https://api.github.com/repos/dhilt/HILT/forks","keys_url":"https://api.github.com/repos/dhilt/HILT/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dhilt/HILT/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dhilt/HILT/teams","hooks_url":"https://api.github.com/repos/dhilt/HILT/hooks","issue_events_url":"https://api.github.com/repos/dhilt/HILT/issues/events{/number}","events_url":"https://api.github.com/repos/dhilt/HILT/events","assignees_url":"https://api.github.com/repos/dhilt/HILT/assignees{/user}","branches_url":"https://api.github.com/repos/dhilt/HILT/branches{/branch}","tags_url":"https://api.github.com/repos/dhilt/HILT/tags","blobs_url":"https://api.github.com/repos/dhilt/HILT/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dhilt/HILT/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dhilt/HILT/git/refs{/sha}","trees_url":"https://api.github.com/repos/dhilt/HILT/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dhilt/HILT/statuses/{sha}","languages_url":"https://api.github.com/repos/dhilt/HILT/languages","stargazers_url":"https://api.github.com/repos/dhilt/HILT/stargazers","contributors_url":"https://api.github.com/repos/dhilt/HILT/contributors","subscribers_url":"https://api.github.com/repos/dhilt/HILT/subscribers","subscription_url":"https://api.github.com/repos/dhilt/HILT/subscription","commits_url":"https://api.github.com/repos/dhilt/HILT/commits{/sha}","git_commits_url":"https://api.github.com/repos/dhilt/HILT/git/commits{/sha}","comments_url":"https://api.github.com/repos/dhilt/HILT/comments{/number}","issue_comment_url":"https://api.github.com/repos/dhilt/HILT/issues/comments{/number}","contents_url":"https://api.github.com/repos/dhilt/HILT/contents/{+path}","compare_url":"https://api.github.com/repos/dhilt/HILT/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dhilt/HILT/merges","archive_url":"https://api.github.com/repos/dhilt/HILT/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dhilt/HILT/downloads","issues_url":"https://api.github.com/repos/dhilt/HILT/issues{/number}","pulls_url":"https://api.github.com/repos/dhilt/HILT/pulls{/number}","milestones_url":"https://api.github.com/repos/dhilt/HILT/milestones{/number}","notifications_url":"https://api.github.com/repos/dhilt/HILT/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dhilt/HILT/labels{/name}","releases_url":"https://api.github.com/repos/dhilt/HILT/releases{/id}","created_at":"2015-04-27T15:31:11Z","updated_at":"2015-04-27T15:41:20Z","pushed_at":"2015-07-30T13:06:21Z","git_url":"git://github.com/dhilt/HILT.git","ssh_url":"git@github.com:dhilt/HILT.git","clone_url":"https://github.com/dhilt/HILT.git","svn_url":"https://github.com/dhilt/HILT","homepage":null,"size":328,"stargazers_count":0,"watchers_count":0,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dhilt/HILT/pulls/1"},"html":{"href":"https://github.com/dhilt/HILT/pull/1"},"issue":{"href":"https://api.github.com/repos/dhilt/HILT/issues/1"},"comments":{"href":"https://api.github.com/repos/dhilt/HILT/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/dhilt/HILT/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/dhilt/HILT/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dhilt/HILT/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/dhilt/HILT/statuses/41b6270f30eba38614042d79d0e31aea2bf60b6b"}}}}