mirror of
				https://github.com/MinimalBible/MinimalBible
				synced 2025-11-03 18:10:27 -05:00 
			
		
		
		
	RecyclerView initial demonstration
This commit is contained in:
		@ -8,12 +8,12 @@ apply plugin: 'com.android.application'
 | 
			
		||||
apply plugin: 'kotlin-android'
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    compileSdkVersion 20
 | 
			
		||||
    buildToolsVersion '20.0.0'
 | 
			
		||||
    compileSdkVersion 21
 | 
			
		||||
    buildToolsVersion '21.1.1'
 | 
			
		||||
    defaultConfig {
 | 
			
		||||
        applicationId 'org.bspeice.minimalbible'
 | 
			
		||||
        minSdkVersion 8
 | 
			
		||||
        targetSdkVersion 20
 | 
			
		||||
        targetSdkVersion 21
 | 
			
		||||
        versionCode 1
 | 
			
		||||
        versionName '1.0'
 | 
			
		||||
    }
 | 
			
		||||
@ -47,7 +47,8 @@ dependencies {
 | 
			
		||||
    compile 'com.jakewharton:butterknife:+'
 | 
			
		||||
    compile 'com.readystatesoftware.systembartint:systembartint:+'
 | 
			
		||||
    compile 'com.netflix.rxjava:rxjava-android:+'
 | 
			
		||||
    compile 'com.android.support:appcompat-v7:20.+'
 | 
			
		||||
    compile 'com.android.support:appcompat-v7:21.+'
 | 
			
		||||
    compile 'com.android.support:recyclerview-v7:21.+'
 | 
			
		||||
    compile 'org.apache.commons:commons-lang3:+'
 | 
			
		||||
    compile 'com.google.code.gson:gson:+'
 | 
			
		||||
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
 | 
			
		||||
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
<html lang="en" ng-app="bookApp">
 | 
			
		||||
<head>
 | 
			
		||||
    <script type="text/javascript" src="file:///android_asset/dist/book-bundle.js"></script>
 | 
			
		||||
    <script type="text/javascript" src="file:///android_asset/dist/scroll.js"></script>
 | 
			
		||||
    <script type="text/javascript" src="file:///android_asset/dist/scroll-jqlite.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body ng-controller="BookCtrl" id="bookController">
 | 
			
		||||
<div u-scroll-viewport style="height:200px;">
 | 
			
		||||
    <div ui-scroll="verse in verseSource" style="display: inline;">
 | 
			
		||||
        <h3 style="display: inline;" ng-show="verse.verseNum === 1">
 | 
			
		||||
            {{ verse.chapter }}
 | 
			
		||||
        </h3>
 | 
			
		||||
        <sup ng-show="verse.verseNum !== 1 && verse.verseNum !== 0">{{ verse.verseNum }}</sup>
 | 
			
		||||
        {{ verse.content }}
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										21999
									
								
								app/src/main/assets/dist/book-bundle.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21999
									
								
								app/src/main/assets/dist/book-bundle.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										229
									
								
								app/src/main/assets/dist/scroll-jqlite.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										229
									
								
								app/src/main/assets/dist/scroll-jqlite.js
									
									
									
									
										vendored
									
									
								
							@ -1,229 +0,0 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
angular.module('ui.scroll.jqlite', ['ui.scroll']).service('jqLiteExtras', [
 | 
			
		||||
  '$log', '$window', function(console, window) {
 | 
			
		||||
    return {
 | 
			
		||||
      registerFor: function(element) {
 | 
			
		||||
        var convertToPx, css, getMeasurements, getStyle, getWidthHeight, isWindow, scrollTo;
 | 
			
		||||
        css = angular.element.prototype.css;
 | 
			
		||||
        element.prototype.css = function(name, value) {
 | 
			
		||||
          var elem, self;
 | 
			
		||||
          self = this;
 | 
			
		||||
          elem = self[0];
 | 
			
		||||
          if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) {
 | 
			
		||||
            return css.call(self, name, value);
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
        isWindow = function(obj) {
 | 
			
		||||
          return obj && obj.document && obj.location && obj.alert && obj.setInterval;
 | 
			
		||||
        };
 | 
			
		||||
        scrollTo = function(self, direction, value) {
 | 
			
		||||
          var elem, method, preserve, prop, _ref;
 | 
			
		||||
          elem = self[0];
 | 
			
		||||
          _ref = {
 | 
			
		||||
            top: ['scrollTop', 'pageYOffset', 'scrollLeft'],
 | 
			
		||||
            left: ['scrollLeft', 'pageXOffset', 'scrollTop']
 | 
			
		||||
          }[direction], method = _ref[0], prop = _ref[1], preserve = _ref[2];
 | 
			
		||||
          if (isWindow(elem)) {
 | 
			
		||||
            if (angular.isDefined(value)) {
 | 
			
		||||
              return elem.scrollTo(self[preserve].call(self), value);
 | 
			
		||||
            } else {
 | 
			
		||||
              if (prop in elem) {
 | 
			
		||||
                return elem[prop];
 | 
			
		||||
              } else {
 | 
			
		||||
                return elem.document.documentElement[method];
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          } else {
 | 
			
		||||
            if (angular.isDefined(value)) {
 | 
			
		||||
              return elem[method] = value;
 | 
			
		||||
            } else {
 | 
			
		||||
              return elem[method];
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
        if (window.getComputedStyle) {
 | 
			
		||||
          getStyle = function(elem) {
 | 
			
		||||
            return window.getComputedStyle(elem, null);
 | 
			
		||||
          };
 | 
			
		||||
          convertToPx = function(elem, value) {
 | 
			
		||||
            return parseFloat(value);
 | 
			
		||||
          };
 | 
			
		||||
        } else {
 | 
			
		||||
          getStyle = function(elem) {
 | 
			
		||||
            return elem.currentStyle;
 | 
			
		||||
          };
 | 
			
		||||
          convertToPx = function(elem, value) {
 | 
			
		||||
            var core_pnum, left, result, rnumnonpx, rs, rsLeft, style;
 | 
			
		||||
            core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
 | 
			
		||||
            rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i');
 | 
			
		||||
            if (!rnumnonpx.test(value)) {
 | 
			
		||||
              return parseFloat(value);
 | 
			
		||||
            } else {
 | 
			
		||||
              style = elem.style;
 | 
			
		||||
              left = style.left;
 | 
			
		||||
              rs = elem.runtimeStyle;
 | 
			
		||||
              rsLeft = rs && rs.left;
 | 
			
		||||
              if (rs) {
 | 
			
		||||
                rs.left = style.left;
 | 
			
		||||
              }
 | 
			
		||||
              style.left = value;
 | 
			
		||||
              result = style.pixelLeft;
 | 
			
		||||
              style.left = left;
 | 
			
		||||
              if (rsLeft) {
 | 
			
		||||
                rs.left = rsLeft;
 | 
			
		||||
              }
 | 
			
		||||
              return result;
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
        getMeasurements = function(elem, measure) {
 | 
			
		||||
          var base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB, _ref;
 | 
			
		||||
          if (isWindow(elem)) {
 | 
			
		||||
            base = document.documentElement[{
 | 
			
		||||
              height: 'clientHeight',
 | 
			
		||||
              width: 'clientWidth'
 | 
			
		||||
            }[measure]];
 | 
			
		||||
            return {
 | 
			
		||||
              base: base,
 | 
			
		||||
              padding: 0,
 | 
			
		||||
              border: 0,
 | 
			
		||||
              margin: 0
 | 
			
		||||
            };
 | 
			
		||||
          }
 | 
			
		||||
          _ref = {
 | 
			
		||||
            width: [elem.offsetWidth, 'Left', 'Right'],
 | 
			
		||||
            height: [elem.offsetHeight, 'Top', 'Bottom']
 | 
			
		||||
          }[measure], base = _ref[0], dirA = _ref[1], dirB = _ref[2];
 | 
			
		||||
          computedStyle = getStyle(elem);
 | 
			
		||||
          paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0;
 | 
			
		||||
          paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0;
 | 
			
		||||
          borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0;
 | 
			
		||||
          borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0;
 | 
			
		||||
          computedMarginA = computedStyle['margin' + dirA];
 | 
			
		||||
          computedMarginB = computedStyle['margin' + dirB];
 | 
			
		||||
          marginA = convertToPx(elem, computedMarginA) || 0;
 | 
			
		||||
          marginB = convertToPx(elem, computedMarginB) || 0;
 | 
			
		||||
          return {
 | 
			
		||||
            base: base,
 | 
			
		||||
            padding: paddingA + paddingB,
 | 
			
		||||
            border: borderA + borderB,
 | 
			
		||||
            margin: marginA + marginB
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
        getWidthHeight = function(elem, direction, measure) {
 | 
			
		||||
          var computedStyle, measurements, result;
 | 
			
		||||
          measurements = getMeasurements(elem, direction);
 | 
			
		||||
          if (measurements.base > 0) {
 | 
			
		||||
            return {
 | 
			
		||||
              base: measurements.base - measurements.padding - measurements.border,
 | 
			
		||||
              outer: measurements.base,
 | 
			
		||||
              outerfull: measurements.base + measurements.margin
 | 
			
		||||
            }[measure];
 | 
			
		||||
          } else {
 | 
			
		||||
            computedStyle = getStyle(elem);
 | 
			
		||||
            result = computedStyle[direction];
 | 
			
		||||
            if (result < 0 || result === null) {
 | 
			
		||||
              result = elem.style[direction] || 0;
 | 
			
		||||
            }
 | 
			
		||||
            result = parseFloat(result) || 0;
 | 
			
		||||
            return {
 | 
			
		||||
              base: result - measurements.padding - measurements.border,
 | 
			
		||||
              outer: result,
 | 
			
		||||
              outerfull: result + measurements.padding + measurements.border + measurements.margin
 | 
			
		||||
            }[measure];
 | 
			
		||||
          }
 | 
			
		||||
        };
 | 
			
		||||
        return angular.forEach({
 | 
			
		||||
          before: function(newElem) {
 | 
			
		||||
            var children, elem, i, parent, self, _i, _ref;
 | 
			
		||||
            self = this;
 | 
			
		||||
            elem = self[0];
 | 
			
		||||
            parent = self.parent();
 | 
			
		||||
            children = parent.contents();
 | 
			
		||||
            if (children[0] === elem) {
 | 
			
		||||
              return parent.prepend(newElem);
 | 
			
		||||
            } else {
 | 
			
		||||
              for (i = _i = 1, _ref = children.length - 1; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
 | 
			
		||||
                if (children[i] === elem) {
 | 
			
		||||
                  angular.element(children[i - 1]).after(newElem);
 | 
			
		||||
                  return;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
              throw new Error('invalid DOM structure ' + elem.outerHTML);
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          height: function(value) {
 | 
			
		||||
            var self;
 | 
			
		||||
            self = this;
 | 
			
		||||
            if (angular.isDefined(value)) {
 | 
			
		||||
              if (angular.isNumber(value)) {
 | 
			
		||||
                value = value + 'px';
 | 
			
		||||
              }
 | 
			
		||||
              return css.call(self, 'height', value);
 | 
			
		||||
            } else {
 | 
			
		||||
              return getWidthHeight(this[0], 'height', 'base');
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          outerHeight: function(option) {
 | 
			
		||||
            return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer');
 | 
			
		||||
          },
 | 
			
		||||
          /*
 | 
			
		||||
          UIScroller no longer relies on jQuery method offset. The jQLite implementation of the method
 | 
			
		||||
          is kept here just for the reference. Also the offset setter method was never implemented
 | 
			
		||||
          */
 | 
			
		||||
 | 
			
		||||
          offset: function(value) {
 | 
			
		||||
            var box, doc, docElem, elem, self, win;
 | 
			
		||||
            self = this;
 | 
			
		||||
            if (arguments.length) {
 | 
			
		||||
              if (value === void 0) {
 | 
			
		||||
                return self;
 | 
			
		||||
              } else {
 | 
			
		||||
                throw new Error('offset setter method is not implemented');
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            box = {
 | 
			
		||||
              top: 0,
 | 
			
		||||
              left: 0
 | 
			
		||||
            };
 | 
			
		||||
            elem = self[0];
 | 
			
		||||
            doc = elem && elem.ownerDocument;
 | 
			
		||||
            if (!doc) {
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            docElem = doc.documentElement;
 | 
			
		||||
            if (elem.getBoundingClientRect != null) {
 | 
			
		||||
              box = elem.getBoundingClientRect();
 | 
			
		||||
            }
 | 
			
		||||
            win = doc.defaultView || doc.parentWindow;
 | 
			
		||||
            return {
 | 
			
		||||
              top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
 | 
			
		||||
              left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
 | 
			
		||||
            };
 | 
			
		||||
          },
 | 
			
		||||
          scrollTop: function(value) {
 | 
			
		||||
            return scrollTo(this, 'top', value);
 | 
			
		||||
          },
 | 
			
		||||
          scrollLeft: function(value) {
 | 
			
		||||
            return scrollTo(this, 'left', value);
 | 
			
		||||
          }
 | 
			
		||||
        }, function(value, key) {
 | 
			
		||||
          if (!element.prototype[key]) {
 | 
			
		||||
            return element.prototype[key] = value;
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
]).run([
 | 
			
		||||
  '$log', '$window', 'jqLiteExtras', function(console, window, jqLiteExtras) {
 | 
			
		||||
    if (!window.jQuery) {
 | 
			
		||||
      return jqLiteExtras.registerFor(angular.element);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
//# sourceURL=src/scripts/ui-scroll-jqlite.js
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										576
									
								
								app/src/main/assets/dist/scroll.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										576
									
								
								app/src/main/assets/dist/scroll.js
									
									
									
									
										vendored
									
									
								
							@ -1,576 +0,0 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
/*
 | 
			
		||||
globals: angular, window
 | 
			
		||||
 | 
			
		||||
	List of used element methods available in JQuery but not in JQuery Lite
 | 
			
		||||
 | 
			
		||||
		element.before(elem)
 | 
			
		||||
		element.height()
 | 
			
		||||
		element.outerHeight(true)
 | 
			
		||||
		element.height(value) = only for Top/Bottom padding elements
 | 
			
		||||
		element.scrollTop()
 | 
			
		||||
		element.scrollTop(value)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
angular.module('ui.scroll', []).directive('uiScrollViewport', [
 | 
			
		||||
  '$log', function() {
 | 
			
		||||
    return {
 | 
			
		||||
      controller: [
 | 
			
		||||
        '$scope', '$element', function(scope, element) {
 | 
			
		||||
          return element;
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
]).directive('uiScroll', [
 | 
			
		||||
  '$log', '$injector', '$rootScope', '$timeout', function(console, $injector, $rootScope, $timeout) {
 | 
			
		||||
    return {
 | 
			
		||||
      require: ['?^uiScrollViewport'],
 | 
			
		||||
      transclude: 'element',
 | 
			
		||||
      priority: 1000,
 | 
			
		||||
      terminal: true,
 | 
			
		||||
      compile: function(elementTemplate, attr, linker) {
 | 
			
		||||
        return function($scope, element, $attr, controllers) {
 | 
			
		||||
          var adapter, adjustBuffer, adjustRowHeight, bof, bottomVisiblePos, buffer, bufferPadding, bufferSize, clipBottom, clipTop, datasource, datasourceName, doAdjustment, enqueueFetch, eof, eventListener, fetch, finalize, first, hideElementBeforeAppend, insert, isDatasource, isLoading, itemName, loading, log, match, next, pending, reload, removeFromBuffer, resizeHandler, ridActual, scrollHandler, scrollHeight, shouldLoadBottom, shouldLoadTop, showElementAfterRender, tempScope, topVisible, topVisibleElement, topVisibleItem, topVisiblePos, topVisibleScope, viewport, viewportScope, wheelHandler;
 | 
			
		||||
          log = console.debug || console.log;
 | 
			
		||||
          match = $attr.uiScroll.match(/^\s*(\w+)\s+in\s+(\w+)\s*$/);
 | 
			
		||||
          if (!match) {
 | 
			
		||||
            throw new Error('Expected uiScroll in form of \'_item_ in _datasource_\' but got \'' + $attr.uiScroll + '\'');
 | 
			
		||||
          }
 | 
			
		||||
          itemName = match[1];
 | 
			
		||||
          datasourceName = match[2];
 | 
			
		||||
          isDatasource = function(datasource) {
 | 
			
		||||
            return angular.isObject(datasource) && datasource.get && angular.isFunction(datasource.get);
 | 
			
		||||
          };
 | 
			
		||||
          datasource = $scope[datasourceName];
 | 
			
		||||
          if (!isDatasource(datasource)) {
 | 
			
		||||
            datasource = $injector.get(datasourceName);
 | 
			
		||||
            if (!isDatasource(datasource)) {
 | 
			
		||||
              throw new Error('' + datasourceName + ' is not a valid datasource');
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          bufferSize = Math.max(3, +$attr.bufferSize || 10);
 | 
			
		||||
          bufferPadding = function() {
 | 
			
		||||
            return viewport.outerHeight() * Math.max(0.1, +$attr.padding || 0.1);
 | 
			
		||||
          };
 | 
			
		||||
          scrollHeight = function(elem) {
 | 
			
		||||
            var _ref;
 | 
			
		||||
            return (_ref = elem[0].scrollHeight) != null ? _ref : elem[0].document.documentElement.scrollHeight;
 | 
			
		||||
          };
 | 
			
		||||
          adapter = null;
 | 
			
		||||
          linker(tempScope = $scope.$new(), function(template) {
 | 
			
		||||
            var bottomPadding, createPadding, padding, repeaterType, topPadding, viewport;
 | 
			
		||||
            repeaterType = template[0].localName;
 | 
			
		||||
            if (repeaterType === 'dl') {
 | 
			
		||||
              throw new Error('ui-scroll directive does not support <' + template[0].localName + '> as a repeating tag: ' + template[0].outerHTML);
 | 
			
		||||
            }
 | 
			
		||||
            if (repeaterType !== 'li' && repeaterType !== 'tr') {
 | 
			
		||||
              repeaterType = 'div';
 | 
			
		||||
            }
 | 
			
		||||
            viewport = controllers[0] || angular.element(window);
 | 
			
		||||
            viewport.css({
 | 
			
		||||
              'overflow-y': 'auto',
 | 
			
		||||
              'display': 'block'
 | 
			
		||||
            });
 | 
			
		||||
            padding = function(repeaterType) {
 | 
			
		||||
              var div, result, table;
 | 
			
		||||
              switch (repeaterType) {
 | 
			
		||||
                case 'tr':
 | 
			
		||||
                  table = angular.element('<table><tr><td><div></div></td></tr></table>');
 | 
			
		||||
                  div = table.find('div');
 | 
			
		||||
                  result = table.find('tr');
 | 
			
		||||
                  result.paddingHeight = function() {
 | 
			
		||||
                    return div.height.apply(div, arguments);
 | 
			
		||||
                  };
 | 
			
		||||
                  return result;
 | 
			
		||||
                default:
 | 
			
		||||
                  result = angular.element('<' + repeaterType + '></' + repeaterType + '>');
 | 
			
		||||
                  result.paddingHeight = result.height;
 | 
			
		||||
                  return result;
 | 
			
		||||
              }
 | 
			
		||||
            };
 | 
			
		||||
            createPadding = function(padding, element, direction) {
 | 
			
		||||
              element[{
 | 
			
		||||
                top: 'before',
 | 
			
		||||
                bottom: 'after'
 | 
			
		||||
              }[direction]](padding);
 | 
			
		||||
              return {
 | 
			
		||||
                paddingHeight: function() {
 | 
			
		||||
                  return padding.paddingHeight.apply(padding, arguments);
 | 
			
		||||
                },
 | 
			
		||||
                insert: function(element) {
 | 
			
		||||
                  return padding[{
 | 
			
		||||
                    top: 'after',
 | 
			
		||||
                    bottom: 'before'
 | 
			
		||||
                  }[direction]](element);
 | 
			
		||||
                }
 | 
			
		||||
              };
 | 
			
		||||
            };
 | 
			
		||||
            topPadding = createPadding(padding(repeaterType), element, 'top');
 | 
			
		||||
            bottomPadding = createPadding(padding(repeaterType), element, 'bottom');
 | 
			
		||||
            tempScope.$destroy();
 | 
			
		||||
            return adapter = {
 | 
			
		||||
              viewport: viewport,
 | 
			
		||||
              topPadding: topPadding.paddingHeight,
 | 
			
		||||
              bottomPadding: bottomPadding.paddingHeight,
 | 
			
		||||
              append: bottomPadding.insert,
 | 
			
		||||
              prepend: topPadding.insert,
 | 
			
		||||
              bottomDataPos: function() {
 | 
			
		||||
                return scrollHeight(viewport) - bottomPadding.paddingHeight();
 | 
			
		||||
              },
 | 
			
		||||
              topDataPos: function() {
 | 
			
		||||
                return topPadding.paddingHeight();
 | 
			
		||||
              }
 | 
			
		||||
            };
 | 
			
		||||
          });
 | 
			
		||||
          viewport = adapter.viewport;
 | 
			
		||||
          viewportScope = viewport.scope() || $rootScope;
 | 
			
		||||
          if (angular.isDefined($attr.topVisible)) {
 | 
			
		||||
            topVisibleItem = function(item) {
 | 
			
		||||
              return viewportScope[$attr.topVisible] = item;
 | 
			
		||||
            };
 | 
			
		||||
          }
 | 
			
		||||
          if (angular.isDefined($attr.topVisibleElement)) {
 | 
			
		||||
            topVisibleElement = function(element) {
 | 
			
		||||
              return viewportScope[$attr.topVisibleElement] = element;
 | 
			
		||||
            };
 | 
			
		||||
          }
 | 
			
		||||
          if (angular.isDefined($attr.topVisibleScope)) {
 | 
			
		||||
            topVisibleScope = function(scope) {
 | 
			
		||||
              return viewportScope[$attr.topVisibleScope] = scope;
 | 
			
		||||
            };
 | 
			
		||||
          }
 | 
			
		||||
          topVisible = function(item) {
 | 
			
		||||
            if (topVisibleItem) {
 | 
			
		||||
              topVisibleItem(item.scope[itemName]);
 | 
			
		||||
            }
 | 
			
		||||
            if (topVisibleElement) {
 | 
			
		||||
              topVisibleElement(item.element);
 | 
			
		||||
            }
 | 
			
		||||
            if (topVisibleScope) {
 | 
			
		||||
              topVisibleScope(item.scope);
 | 
			
		||||
            }
 | 
			
		||||
            if (datasource.topVisible) {
 | 
			
		||||
              return datasource.topVisible(item);
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          if (angular.isDefined($attr.isLoading)) {
 | 
			
		||||
            loading = function(value) {
 | 
			
		||||
              viewportScope[$attr.isLoading] = value;
 | 
			
		||||
              if (datasource.loading) {
 | 
			
		||||
                return datasource.loading(value);
 | 
			
		||||
              }
 | 
			
		||||
            };
 | 
			
		||||
          } else {
 | 
			
		||||
            loading = function(value) {
 | 
			
		||||
              if (datasource.loading) {
 | 
			
		||||
                return datasource.loading(value);
 | 
			
		||||
              }
 | 
			
		||||
            };
 | 
			
		||||
          }
 | 
			
		||||
          ridActual = 0;
 | 
			
		||||
          first = 1;
 | 
			
		||||
          next = 1;
 | 
			
		||||
          buffer = [];
 | 
			
		||||
          pending = [];
 | 
			
		||||
          eof = false;
 | 
			
		||||
          bof = false;
 | 
			
		||||
          isLoading = false;
 | 
			
		||||
          removeFromBuffer = function(start, stop) {
 | 
			
		||||
            var i, _i;
 | 
			
		||||
            for (i = _i = start; start <= stop ? _i < stop : _i > stop; i = start <= stop ? ++_i : --_i) {
 | 
			
		||||
              buffer[i].scope.$destroy();
 | 
			
		||||
              buffer[i].element.remove();
 | 
			
		||||
            }
 | 
			
		||||
            return buffer.splice(start, stop - start);
 | 
			
		||||
          };
 | 
			
		||||
          reload = function() {
 | 
			
		||||
            ridActual++;
 | 
			
		||||
            first = 1;
 | 
			
		||||
            next = 1;
 | 
			
		||||
            removeFromBuffer(0, buffer.length);
 | 
			
		||||
            adapter.topPadding(0);
 | 
			
		||||
            adapter.bottomPadding(0);
 | 
			
		||||
            pending = [];
 | 
			
		||||
            eof = false;
 | 
			
		||||
            bof = false;
 | 
			
		||||
            return adjustBuffer(ridActual, false);
 | 
			
		||||
          };
 | 
			
		||||
          bottomVisiblePos = function() {
 | 
			
		||||
            return viewport.scrollTop() + viewport.outerHeight();
 | 
			
		||||
          };
 | 
			
		||||
          topVisiblePos = function() {
 | 
			
		||||
            return viewport.scrollTop();
 | 
			
		||||
          };
 | 
			
		||||
          shouldLoadBottom = function() {
 | 
			
		||||
            return !eof && adapter.bottomDataPos() < bottomVisiblePos() + bufferPadding();
 | 
			
		||||
          };
 | 
			
		||||
          clipBottom = function() {
 | 
			
		||||
            var bottomHeight, i, item, itemHeight, itemTop, newRow, overage, rowTop, _i, _ref;
 | 
			
		||||
            bottomHeight = 0;
 | 
			
		||||
            overage = 0;
 | 
			
		||||
            for (i = _i = _ref = buffer.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
 | 
			
		||||
              item = buffer[i];
 | 
			
		||||
              itemTop = item.element.offset().top;
 | 
			
		||||
              newRow = rowTop !== itemTop;
 | 
			
		||||
              rowTop = itemTop;
 | 
			
		||||
              if (newRow) {
 | 
			
		||||
                itemHeight = item.element.outerHeight(true);
 | 
			
		||||
              }
 | 
			
		||||
              if (adapter.bottomDataPos() - bottomHeight - itemHeight > bottomVisiblePos() + bufferPadding()) {
 | 
			
		||||
                if (newRow) {
 | 
			
		||||
                  bottomHeight += itemHeight;
 | 
			
		||||
                }
 | 
			
		||||
                overage++;
 | 
			
		||||
                eof = false;
 | 
			
		||||
              } else {
 | 
			
		||||
                if (newRow) {
 | 
			
		||||
                  break;
 | 
			
		||||
                }
 | 
			
		||||
                overage++;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            if (overage > 0) {
 | 
			
		||||
              adapter.bottomPadding(adapter.bottomPadding() + bottomHeight);
 | 
			
		||||
              removeFromBuffer(buffer.length - overage, buffer.length);
 | 
			
		||||
              next -= overage;
 | 
			
		||||
              return log('clipped off bottom ' + overage + ' bottom padding ' + (adapter.bottomPadding()));
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          shouldLoadTop = function() {
 | 
			
		||||
            return !bof && (adapter.topDataPos() > topVisiblePos() - bufferPadding());
 | 
			
		||||
          };
 | 
			
		||||
          clipTop = function() {
 | 
			
		||||
            var item, itemHeight, itemTop, newRow, overage, rowTop, topHeight, _i, _len;
 | 
			
		||||
            topHeight = 0;
 | 
			
		||||
            overage = 0;
 | 
			
		||||
            for (_i = 0, _len = buffer.length; _i < _len; _i++) {
 | 
			
		||||
              item = buffer[_i];
 | 
			
		||||
              itemTop = item.element.offset().top;
 | 
			
		||||
              newRow = rowTop !== itemTop;
 | 
			
		||||
              rowTop = itemTop;
 | 
			
		||||
              if (newRow) {
 | 
			
		||||
                itemHeight = item.element.outerHeight(true);
 | 
			
		||||
              }
 | 
			
		||||
              if (adapter.topDataPos() + topHeight + itemHeight < topVisiblePos() - bufferPadding()) {
 | 
			
		||||
                if (newRow) {
 | 
			
		||||
                  topHeight += itemHeight;
 | 
			
		||||
                }
 | 
			
		||||
                overage++;
 | 
			
		||||
                bof = false;
 | 
			
		||||
              } else {
 | 
			
		||||
                if (newRow) {
 | 
			
		||||
                  break;
 | 
			
		||||
                }
 | 
			
		||||
                overage++;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            if (overage > 0) {
 | 
			
		||||
              adapter.topPadding(adapter.topPadding() + topHeight);
 | 
			
		||||
              removeFromBuffer(0, overage);
 | 
			
		||||
              first += overage;
 | 
			
		||||
              return log('clipped off top ' + overage + ' top padding ' + (adapter.topPadding()));
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          enqueueFetch = function(rid, direction, scrolling) {
 | 
			
		||||
            if (!isLoading) {
 | 
			
		||||
              isLoading = true;
 | 
			
		||||
              loading(true);
 | 
			
		||||
            }
 | 
			
		||||
            if (pending.push(direction) === 1) {
 | 
			
		||||
              return fetch(rid, scrolling);
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          hideElementBeforeAppend = function(element) {
 | 
			
		||||
            element.displayTemp = element.css('display');
 | 
			
		||||
            return element.css('display', 'none');
 | 
			
		||||
          };
 | 
			
		||||
          showElementAfterRender = function(element) {
 | 
			
		||||
            if (element.hasOwnProperty('displayTemp')) {
 | 
			
		||||
              return element.css('display', element.displayTemp);
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          insert = function(index, item) {
 | 
			
		||||
            var itemScope, toBeAppended, wrapper;
 | 
			
		||||
            itemScope = $scope.$new();
 | 
			
		||||
            itemScope[itemName] = item;
 | 
			
		||||
            toBeAppended = index > first;
 | 
			
		||||
            itemScope.$index = index;
 | 
			
		||||
            if (toBeAppended) {
 | 
			
		||||
              itemScope.$index--;
 | 
			
		||||
            }
 | 
			
		||||
            wrapper = {
 | 
			
		||||
              scope: itemScope
 | 
			
		||||
            };
 | 
			
		||||
            linker(itemScope, function(clone) {
 | 
			
		||||
              wrapper.element = clone;
 | 
			
		||||
              if (toBeAppended) {
 | 
			
		||||
                if (index === next) {
 | 
			
		||||
                  hideElementBeforeAppend(clone);
 | 
			
		||||
                  adapter.append(clone);
 | 
			
		||||
                  return buffer.push(wrapper);
 | 
			
		||||
                } else {
 | 
			
		||||
                  buffer[index - first].element.after(clone);
 | 
			
		||||
                  return buffer.splice(index - first + 1, 0, wrapper);
 | 
			
		||||
                }
 | 
			
		||||
              } else {
 | 
			
		||||
                hideElementBeforeAppend(clone);
 | 
			
		||||
                adapter.prepend(clone);
 | 
			
		||||
                return buffer.unshift(wrapper);
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
            return {
 | 
			
		||||
              appended: toBeAppended,
 | 
			
		||||
              wrapper: wrapper
 | 
			
		||||
            };
 | 
			
		||||
          };
 | 
			
		||||
          adjustRowHeight = function(appended, wrapper) {
 | 
			
		||||
            var newHeight;
 | 
			
		||||
            if (appended) {
 | 
			
		||||
              return adapter.bottomPadding(Math.max(0, adapter.bottomPadding() - wrapper.element.outerHeight(true)));
 | 
			
		||||
            } else {
 | 
			
		||||
              newHeight = adapter.topPadding() - wrapper.element.outerHeight(true);
 | 
			
		||||
              if (newHeight >= 0) {
 | 
			
		||||
                return adapter.topPadding(newHeight);
 | 
			
		||||
              } else {
 | 
			
		||||
                return viewport.scrollTop(viewport.scrollTop() + wrapper.element.outerHeight(true));
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          doAdjustment = function(rid, scrolling, finalize) {
 | 
			
		||||
            var item, itemHeight, itemTop, newRow, rowTop, topHeight, _i, _len, _results;
 | 
			
		||||
            log('top {actual=' + (adapter.topDataPos()) + ' visible from=' + (topVisiblePos()) + ' bottom {visible through=' + (bottomVisiblePos()) + ' actual=' + (adapter.bottomDataPos()) + '}');
 | 
			
		||||
            if (shouldLoadBottom()) {
 | 
			
		||||
              enqueueFetch(rid, true, scrolling);
 | 
			
		||||
            } else {
 | 
			
		||||
              if (shouldLoadTop()) {
 | 
			
		||||
                enqueueFetch(rid, false, scrolling);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            if (finalize) {
 | 
			
		||||
              finalize(rid);
 | 
			
		||||
            }
 | 
			
		||||
            if (pending.length === 0) {
 | 
			
		||||
              topHeight = 0;
 | 
			
		||||
              _results = [];
 | 
			
		||||
              for (_i = 0, _len = buffer.length; _i < _len; _i++) {
 | 
			
		||||
                item = buffer[_i];
 | 
			
		||||
                itemTop = item.element.offset().top;
 | 
			
		||||
                newRow = rowTop !== itemTop;
 | 
			
		||||
                rowTop = itemTop;
 | 
			
		||||
                if (newRow) {
 | 
			
		||||
                  itemHeight = item.element.outerHeight(true);
 | 
			
		||||
                }
 | 
			
		||||
                if (newRow && (adapter.topDataPos() + topHeight + itemHeight < topVisiblePos())) {
 | 
			
		||||
                  _results.push(topHeight += itemHeight);
 | 
			
		||||
                } else {
 | 
			
		||||
                  if (newRow) {
 | 
			
		||||
                    topVisible(item);
 | 
			
		||||
                  }
 | 
			
		||||
                  break;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
              return _results;
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          adjustBuffer = function(rid, scrolling, newItems, finalize) {
 | 
			
		||||
            if (newItems && newItems.length) {
 | 
			
		||||
              return $timeout(function() {
 | 
			
		||||
                var itemTop, row, rowTop, rows, _i, _j, _len, _len1;
 | 
			
		||||
                rows = [];
 | 
			
		||||
                for (_i = 0, _len = newItems.length; _i < _len; _i++) {
 | 
			
		||||
                  row = newItems[_i];
 | 
			
		||||
                  element = row.wrapper.element;
 | 
			
		||||
                  showElementAfterRender(element);
 | 
			
		||||
                  itemTop = element.offset().top;
 | 
			
		||||
                  if (rowTop !== itemTop) {
 | 
			
		||||
                    rows.push(row);
 | 
			
		||||
                    rowTop = itemTop;
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
                for (_j = 0, _len1 = rows.length; _j < _len1; _j++) {
 | 
			
		||||
                  row = rows[_j];
 | 
			
		||||
                  adjustRowHeight(row.appended, row.wrapper);
 | 
			
		||||
                }
 | 
			
		||||
                return doAdjustment(rid, scrolling, finalize);
 | 
			
		||||
              });
 | 
			
		||||
            } else {
 | 
			
		||||
              return doAdjustment(rid, scrolling, finalize);
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          finalize = function(rid, scrolling, newItems) {
 | 
			
		||||
            return adjustBuffer(rid, scrolling, newItems, function() {
 | 
			
		||||
              pending.shift();
 | 
			
		||||
              if (pending.length === 0) {
 | 
			
		||||
                isLoading = false;
 | 
			
		||||
                return loading(false);
 | 
			
		||||
              } else {
 | 
			
		||||
                return fetch(rid, scrolling);
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
          };
 | 
			
		||||
          fetch = function(rid, scrolling) {
 | 
			
		||||
            var direction;
 | 
			
		||||
            direction = pending[0];
 | 
			
		||||
            if (direction) {
 | 
			
		||||
              if (buffer.length && !shouldLoadBottom()) {
 | 
			
		||||
                return finalize(rid, scrolling);
 | 
			
		||||
              } else {
 | 
			
		||||
                return datasource.get(next, bufferSize, function(result) {
 | 
			
		||||
                  var item, newItems, _i, _len;
 | 
			
		||||
                  if (rid && rid !== ridActual) {
 | 
			
		||||
                    return;
 | 
			
		||||
                  }
 | 
			
		||||
                  newItems = [];
 | 
			
		||||
                  if (result.length < bufferSize) {
 | 
			
		||||
                    eof = true;
 | 
			
		||||
                    adapter.bottomPadding(0);
 | 
			
		||||
                  }
 | 
			
		||||
                  if (result.length > 0) {
 | 
			
		||||
                    clipTop();
 | 
			
		||||
                    for (_i = 0, _len = result.length; _i < _len; _i++) {
 | 
			
		||||
                      item = result[_i];
 | 
			
		||||
                      newItems.push(insert(++next, item));
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  return finalize(rid, scrolling, newItems);
 | 
			
		||||
                });
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              if (buffer.length && !shouldLoadTop()) {
 | 
			
		||||
                return finalize(rid, scrolling);
 | 
			
		||||
              } else {
 | 
			
		||||
                return datasource.get(first - bufferSize, bufferSize, function(result) {
 | 
			
		||||
                  var i, newItems, _i, _ref;
 | 
			
		||||
                  if (rid && rid !== ridActual) {
 | 
			
		||||
                    return;
 | 
			
		||||
                  }
 | 
			
		||||
                  newItems = [];
 | 
			
		||||
                  if (result.length < bufferSize) {
 | 
			
		||||
                    bof = true;
 | 
			
		||||
                    adapter.topPadding(0);
 | 
			
		||||
                  }
 | 
			
		||||
                  if (result.length > 0) {
 | 
			
		||||
                    if (buffer.length) {
 | 
			
		||||
                      clipBottom();
 | 
			
		||||
                    }
 | 
			
		||||
                    for (i = _i = _ref = result.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
 | 
			
		||||
                      newItems.unshift(insert(--first, result[i]));
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  return finalize(rid, scrolling, newItems);
 | 
			
		||||
                });
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          resizeHandler = function() {
 | 
			
		||||
            if (!$rootScope.$$phase && !isLoading) {
 | 
			
		||||
              adjustBuffer(null, false);
 | 
			
		||||
              return $scope.$apply();
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          viewport.bind('resize', resizeHandler);
 | 
			
		||||
          scrollHandler = function() {
 | 
			
		||||
            if (!$rootScope.$$phase && !isLoading) {
 | 
			
		||||
              adjustBuffer(null, true);
 | 
			
		||||
              return $scope.$apply();
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          viewport.bind('scroll', scrollHandler);
 | 
			
		||||
          wheelHandler = function(event) {
 | 
			
		||||
            var scrollTop, yMax;
 | 
			
		||||
            scrollTop = viewport[0].scrollTop;
 | 
			
		||||
            yMax = viewport[0].scrollHeight - viewport[0].clientHeight;
 | 
			
		||||
            if ((scrollTop === 0 && !bof) || (scrollTop === yMax && !eof)) {
 | 
			
		||||
              return event.preventDefault();
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          viewport.bind('mousewheel', wheelHandler);
 | 
			
		||||
          $scope.$watch(datasource.revision, function() {
 | 
			
		||||
            return reload();
 | 
			
		||||
          });
 | 
			
		||||
          if (datasource.scope) {
 | 
			
		||||
            eventListener = datasource.scope.$new();
 | 
			
		||||
          } else {
 | 
			
		||||
            eventListener = $scope.$new();
 | 
			
		||||
          }
 | 
			
		||||
          $scope.$on('$destroy', function() {
 | 
			
		||||
            eventListener.$destroy();
 | 
			
		||||
            viewport.unbind('resize', resizeHandler);
 | 
			
		||||
            viewport.unbind('scroll', scrollHandler);
 | 
			
		||||
            return viewport.unbind('mousewheel', wheelHandler);
 | 
			
		||||
          });
 | 
			
		||||
          eventListener.$on('update.items', function(event, locator, newItem) {
 | 
			
		||||
            var wrapper, _fn, _i, _len, _ref;
 | 
			
		||||
            if (angular.isFunction(locator)) {
 | 
			
		||||
              _fn = function(wrapper) {
 | 
			
		||||
                return locator(wrapper.scope);
 | 
			
		||||
              };
 | 
			
		||||
              for (_i = 0, _len = buffer.length; _i < _len; _i++) {
 | 
			
		||||
                wrapper = buffer[_i];
 | 
			
		||||
                _fn(wrapper);
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              if ((0 <= (_ref = locator - first - 1) && _ref < buffer.length)) {
 | 
			
		||||
                buffer[locator - first - 1].scope[itemName] = newItem;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
          });
 | 
			
		||||
          eventListener.$on('delete.items', function(event, locator) {
 | 
			
		||||
            var i, item, temp, wrapper, _fn, _i, _j, _k, _len, _len1, _len2, _ref;
 | 
			
		||||
            if (angular.isFunction(locator)) {
 | 
			
		||||
              temp = [];
 | 
			
		||||
              for (_i = 0, _len = buffer.length; _i < _len; _i++) {
 | 
			
		||||
                item = buffer[_i];
 | 
			
		||||
                temp.unshift(item);
 | 
			
		||||
              }
 | 
			
		||||
              _fn = function(wrapper) {
 | 
			
		||||
                if (locator(wrapper.scope)) {
 | 
			
		||||
                  removeFromBuffer(temp.length - 1 - i, temp.length - i);
 | 
			
		||||
                  return next--;
 | 
			
		||||
                }
 | 
			
		||||
              };
 | 
			
		||||
              for (i = _j = 0, _len1 = temp.length; _j < _len1; i = ++_j) {
 | 
			
		||||
                wrapper = temp[i];
 | 
			
		||||
                _fn(wrapper);
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              if ((0 <= (_ref = locator - first - 1) && _ref < buffer.length)) {
 | 
			
		||||
                removeFromBuffer(locator - first - 1, locator - first);
 | 
			
		||||
                next--;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            for (i = _k = 0, _len2 = buffer.length; _k < _len2; i = ++_k) {
 | 
			
		||||
              item = buffer[i];
 | 
			
		||||
              item.scope.$index = first + i;
 | 
			
		||||
            }
 | 
			
		||||
            return adjustBuffer(null, false);
 | 
			
		||||
          });
 | 
			
		||||
          return eventListener.$on('insert.item', function(event, locator, item) {
 | 
			
		||||
            var i, inserted, _i, _len, _ref;
 | 
			
		||||
            inserted = [];
 | 
			
		||||
            if (angular.isFunction(locator)) {
 | 
			
		||||
              throw new Error('not implemented - Insert with locator function');
 | 
			
		||||
            } else {
 | 
			
		||||
              if ((0 <= (_ref = locator - first - 1) && _ref < buffer.length)) {
 | 
			
		||||
                inserted.push(insert(locator, item));
 | 
			
		||||
                next++;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            for (i = _i = 0, _len = buffer.length; _i < _len; i = ++_i) {
 | 
			
		||||
              item = buffer[i];
 | 
			
		||||
              item.scope.$index = first + i;
 | 
			
		||||
            }
 | 
			
		||||
            return adjustBuffer(null, false, inserted);
 | 
			
		||||
          });
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
//# sourceURL=src/scripts/ui-scroll.js
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
var gulp = require('gulp');
 | 
			
		||||
var gutil = require('gulp-util');
 | 
			
		||||
var source = require('vinyl-source-stream');
 | 
			
		||||
var watchify = require('watchify');
 | 
			
		||||
var browserify = require('browserify');
 | 
			
		||||
var buffer = require('gulp-buffer');
 | 
			
		||||
 | 
			
		||||
gulp.task('watch', function() {
 | 
			
		||||
  var bundler = watchify(browserify('./src/book.coffee', watchify.args));
 | 
			
		||||
 | 
			
		||||
  // Optionally, you can apply transforms
 | 
			
		||||
  // and other configuration options on the
 | 
			
		||||
  // bundler just as you would with browserify
 | 
			
		||||
  bundler.transform('coffeeify');
 | 
			
		||||
 | 
			
		||||
  bundler.on('update', rebundle);
 | 
			
		||||
 | 
			
		||||
  function rebundle() {
 | 
			
		||||
    return bundler.bundle()
 | 
			
		||||
      // log errors if they happen
 | 
			
		||||
      .on('error', gutil.log.bind(gutil, 'Browserify Error'))
 | 
			
		||||
      .pipe(source('book-bundle.js'))
 | 
			
		||||
	  .pipe(buffer())
 | 
			
		||||
	  //.pipe(uglify()) // Since Android needs to call in, can't minify
 | 
			
		||||
      .pipe(gulp.dest('./dist'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return rebundle();
 | 
			
		||||
});
 | 
			
		||||
@ -1,36 +0,0 @@
 | 
			
		||||
require 'angular'
 | 
			
		||||
 | 
			
		||||
app = angular.module('bookApp', ['ui.scroll', 'ui.scroll.jqlite'])
 | 
			
		||||
 | 
			
		||||
app.controller 'BookCtrl', ['$scope', '$filter', ($scope, $filter) ->
 | 
			
		||||
	$scope.verseSource = 
 | 
			
		||||
		get: (index, count, success) ->
 | 
			
		||||
			console.log "Calling me with " + index
 | 
			
		||||
			success angular.fromJson Android.getVerses(index, count)
 | 
			
		||||
 | 
			
		||||
	$scope.order_verses = ->
 | 
			
		||||
		$scope.verses = $filter('orderBy')($scope.verses, 'id', false)
 | 
			
		||||
 | 
			
		||||
	$scope.appendVerse = (jsonVerseString) ->
 | 
			
		||||
		$scope.verses.push angular.fromJson jsonVerseString
 | 
			
		||||
		$scope.order_verses()
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
# Due to page initialization, we can only store the controller string.
 | 
			
		||||
# The actual element changes, so there's nothing we can do with JQuery
 | 
			
		||||
# etc. to grab the scope ahead of time and re-use it.
 | 
			
		||||
controller = "#bookController"
 | 
			
		||||
 | 
			
		||||
#window.appendVerse = (jsonVerseString) ->
 | 
			
		||||
#scope = angular.element($("#bookController")).scope()
 | 
			
		||||
#scope.appendVerse jsonVerseString
 | 
			
		||||
## Since we're calling outside of angular, we need to manually apply
 | 
			
		||||
#scope.$apply()
 | 
			
		||||
 | 
			
		||||
###
 | 
			
		||||
Future reference: Get the controller scope like so:
 | 
			
		||||
angular.element($("<controller-element>")).scope().<function>
 | 
			
		||||
 | 
			
		||||
For example:
 | 
			
		||||
angular.element($("#bookController")).scope().<function>
 | 
			
		||||
###
 | 
			
		||||
@ -4,11 +4,12 @@ import android.annotation.SuppressLint;
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.support.v7.widget.LinearLayoutManager;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.webkit.WebView;
 | 
			
		||||
import android.support.v7.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
import org.bspeice.minimalbible.Injector;
 | 
			
		||||
import org.bspeice.minimalbible.R;
 | 
			
		||||
@ -40,7 +41,8 @@ public class BookFragment extends BaseFragment {
 | 
			
		||||
    VerseLookup verseLookup;
 | 
			
		||||
 | 
			
		||||
    @InjectView(R.id.book_content)
 | 
			
		||||
    WebView mainContent;
 | 
			
		||||
    RecyclerView bookContent;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    PublishSubject<String> titleReceiver = PublishSubject.create();
 | 
			
		||||
 | 
			
		||||
@ -69,7 +71,6 @@ public class BookFragment extends BaseFragment {
 | 
			
		||||
        this.i = (Injector) getActivity();
 | 
			
		||||
        i.inject(this);
 | 
			
		||||
        ButterKnife.inject(this, rootView);
 | 
			
		||||
        mainContent.getSettings().setJavaScriptEnabled(true);
 | 
			
		||||
 | 
			
		||||
        // TODO: Load initial text from SharedPreferences, rather than getting the actual book.
 | 
			
		||||
        displayBook(mBook);
 | 
			
		||||
@ -93,29 +94,11 @@ public class BookFragment extends BaseFragment {
 | 
			
		||||
     *
 | 
			
		||||
     * @param b The book we want to display
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressLint("AddJavascriptInterface")
 | 
			
		||||
    private void displayBook(Book b) {
 | 
			
		||||
        Log.d("BookFragment", b.getName());
 | 
			
		||||
        ((BibleViewer)getActivity()).setActionBarTitle(b.getInitials());
 | 
			
		||||
        mainContent.loadUrl(getString(R.string.book_html));
 | 
			
		||||
 | 
			
		||||
        BibleViewClient client = new BibleViewClient(b, verseLookup, titleReceiver);
 | 
			
		||||
        titleReceiver
 | 
			
		||||
                .observeOn(AndroidSchedulers.mainThread())
 | 
			
		||||
                .subscribe(new Action1<String>() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void call(String s) {
 | 
			
		||||
                        // TODO: Handle activity potentially null
 | 
			
		||||
                        ((BibleViewer) getActivity()).setActionBarTitle(s);
 | 
			
		||||
                        Log.d("BibleViewClient", s);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
        mainContent.setWebViewClient(client);
 | 
			
		||||
        mainContent.addJavascriptInterface(client, "Android");
 | 
			
		||||
 | 
			
		||||
        // Enable remote debug
 | 
			
		||||
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
 | 
			
		||||
            WebView.setWebContentsDebuggingEnabled(true);
 | 
			
		||||
        }
 | 
			
		||||
        bookContent.setLayoutManager(new LinearLayoutManager(getActivity()));
 | 
			
		||||
        bookContent.setAdapter(new BookAdapter(b));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,49 @@
 | 
			
		||||
package org.bspeice.minimalbible.activity.viewer
 | 
			
		||||
 | 
			
		||||
import android.support.v7.widget.RecyclerView
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
import org.crosswire.jsword.book.Book
 | 
			
		||||
import org.crosswire.jsword.passage.Verse
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
import org.bspeice.minimalbible.R
 | 
			
		||||
import android.widget.TextView
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adapter used for displaying a book
 | 
			
		||||
 * Displays one chapter at a time,
 | 
			
		||||
 * as each TextView widget is it's own line break
 | 
			
		||||
 */
 | 
			
		||||
class BookAdapter(val b: Book) : RecyclerView.Adapter<PassageView>() {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new view
 | 
			
		||||
     */
 | 
			
		||||
    override fun onCreateViewHolder(parent: ViewGroup?,
 | 
			
		||||
                                    position: Int): PassageView? {
 | 
			
		||||
        val emptyView = LayoutInflater.from(parent?.getContext())
 | 
			
		||||
            .inflate(R.layout.viewer_passage_view, parent, false)
 | 
			
		||||
 | 
			
		||||
        val passage = PassageView(emptyView)
 | 
			
		||||
        passage.v setText "1"
 | 
			
		||||
        return passage
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Bind an existing view
 | 
			
		||||
     */
 | 
			
		||||
    override fun onBindViewHolder(view: PassageView, position: Int) {
 | 
			
		||||
        view.v setText "${Integer.parseInt(view.v.getText() as String) + 1}"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of chapters in the book
 | 
			
		||||
     */
 | 
			
		||||
    override fun getItemCount(): Int = 800
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class PassageView(val _v: View) : RecyclerView.ViewHolder(_v) {
 | 
			
		||||
 | 
			
		||||
    val v = _v as TextView
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -2,11 +2,12 @@
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context="org.bspeice.minimalbible.MainActivity$PlaceholderFragment" >
 | 
			
		||||
    tools:context="org.bspeice.minimalbible.activity.viewer.BookFragment" >
 | 
			
		||||
 | 
			
		||||
    <WebView
 | 
			
		||||
    <android.support.v7.widget.RecyclerView
 | 
			
		||||
        android:id="@+id/book_content"
 | 
			
		||||
        android:layout_width="fill_parent"
 | 
			
		||||
        android:layout_height="fill_parent" />
 | 
			
		||||
        android:scrollbars="none"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:layout_width="match_parent" />
 | 
			
		||||
 | 
			
		||||
</RelativeLayout>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								app/src/main/res/layout/viewer_passage_view.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/src/main/res/layout/viewer_passage_view.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:id="@+id/passage" />
 | 
			
		||||
		Reference in New Issue
	
	Block a user