Skip to content

Commit a52a0c6

Browse files
committed
ui-scroll sources manual merging ('master' -> 'modules')
1 parent c1c043b commit a52a0c6

File tree

8 files changed

+1952
-1773
lines changed

8 files changed

+1952
-1773
lines changed

dist/ui-scroll.js

Lines changed: 1004 additions & 906 deletions
Large diffs are not rendered by default.

dist/ui-scroll.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/modules/adapter.js

Lines changed: 165 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,166 @@
1-
export default function Adapter($parse, $attr, viewport, buffer, adjustBuffer) {
2-
const viewportScope = viewport.scope() || $rootScope;
3-
const setTopVisible = $attr.topVisible ? $parse($attr.topVisible).assign : angular.noop;
4-
const setTopVisibleElement = $attr.topVisibleElement ? $parse($attr.topVisibleElement).assign : angular.noop;
5-
const setTopVisibleScope = $attr.topVisibleScope ? $parse($attr.topVisibleScope).assign : angular.noop;
6-
const setIsLoading = $attr.isLoading ? $parse($attr.isLoading).assign : angular.noop;
7-
8-
this.isLoading = false;
9-
10-
function applyUpdate(wrapper, newItems) {
11-
if (!angular.isArray(newItems)) {
12-
return;
13-
}
14-
15-
let keepIt;
16-
let pos = (buffer.indexOf(wrapper)) + 1;
17-
18-
newItems.reverse().forEach((newItem) => {
19-
if (newItem === wrapper.item) {
20-
keepIt = true;
21-
pos--;
22-
} else {
23-
buffer.insert(pos, newItem);
24-
}
25-
});
26-
27-
if (!keepIt) {
28-
wrapper.op = 'remove';
29-
}
30-
}
31-
32-
this.applyUpdates = (arg1, arg2) => {
33-
if (angular.isFunction(arg1)) {
34-
// arg1 is the updater function, arg2 is ignored
35-
buffer.slice(0).forEach((wrapper) => {
36-
// we need to do it on the buffer clone, because buffer content
37-
// may change as we iterate through
38-
applyUpdate(wrapper, arg1(wrapper.item, wrapper.scope, wrapper.element));
39-
});
40-
} else {
41-
// arg1 is item index, arg2 is the newItems array
42-
if (arg1 % 1 !== 0) {// checking if it is an integer
43-
throw new Error('applyUpdates - ' + arg1 + ' is not a valid index');
44-
}
45-
46-
const index = arg1 - buffer.first;
47-
if ((index >= 0 && index < buffer.length)) {
48-
applyUpdate(buffer[index], arg2);
49-
}
50-
}
51-
52-
adjustBuffer();
53-
};
54-
55-
this.append = (newItems) => {
56-
buffer.append(newItems);
57-
adjustBuffer();
58-
};
59-
60-
this.prepend = (newItems) => {
61-
buffer.prepend(newItems);
62-
adjustBuffer();
63-
};
64-
65-
this.loading = function (value) {
66-
this.isLoading = value;
67-
setIsLoading(viewportScope, value);
68-
};
69-
70-
this.calculateProperties = function () {
71-
let i, item, itemHeight, itemTop, isNewRow, rowTop;
72-
let topHeight = 0;
73-
for (i = 0; i < buffer.length; i++) {
74-
item = buffer[i];
75-
itemTop = item.element.offset().top;
76-
isNewRow = rowTop !== itemTop;
77-
rowTop = itemTop;
78-
if (isNewRow) {
79-
itemHeight = item.element.outerHeight(true);
80-
}
81-
if (isNewRow && (viewport.topDataPos() + topHeight + itemHeight <= viewport.topVisiblePos())) {
82-
topHeight += itemHeight;
83-
} else {
84-
if (isNewRow) {
85-
this.topVisible = item.item;
86-
this.topVisibleElement = item.element;
87-
this.topVisibleScope = item.scope;
88-
setTopVisible(viewportScope, item.item);
89-
setTopVisibleElement(viewportScope, item.element);
90-
setTopVisibleScope(viewportScope, item.scope);
91-
}
92-
break;
93-
94-
}
95-
}
96-
};
1+
export default function Adapter($rootScope, $parse, $attr, viewport, buffer, adjustBuffer, element) {
2+
const viewportScope = viewport.scope() || $rootScope;
3+
let disabled = false;
4+
let self = this;
5+
6+
createValueInjector('adapter')(self);
7+
let topVisibleInjector = createValueInjector('topVisible');
8+
let topVisibleElementInjector = createValueInjector('topVisibleElement');
9+
let topVisibleScopeInjector = createValueInjector('topVisibleScope');
10+
let isLoadingInjector = createValueInjector('isLoading');
11+
12+
// Adapter API definition
13+
14+
Object.defineProperty(this, 'disabled', {
15+
get: () => disabled,
16+
set: (value) => (!(disabled = value)) ? adjustBuffer() : null
17+
});
18+
19+
this.isLoading = false;
20+
this.isBOF = () => buffer.bof;
21+
this.isEOF = () => buffer.eof;
22+
23+
this.applyUpdates = (arg1, arg2) => {
24+
if (angular.isFunction(arg1)) {
25+
// arg1 is the updater function, arg2 is ignored
26+
buffer.slice(0).forEach((wrapper) => {
27+
// we need to do it on the buffer clone, because buffer content
28+
// may change as we iterate through
29+
applyUpdate(wrapper, arg1(wrapper.item, wrapper.scope, wrapper.element));
30+
});
31+
} else {
32+
// arg1 is item index, arg2 is the newItems array
33+
if (arg1 % 1 !== 0) {// checking if it is an integer
34+
throw new Error('applyUpdates - ' + arg1 + ' is not a valid index');
35+
}
36+
37+
const index = arg1 - buffer.first;
38+
if ((index >= 0 && index < buffer.length)) {
39+
applyUpdate(buffer[index], arg2);
40+
}
41+
}
42+
43+
adjustBuffer();
44+
};
45+
46+
this.append = (newItems) => {
47+
buffer.append(newItems);
48+
adjustBuffer();
49+
};
50+
51+
this.prepend = (newItems) => {
52+
buffer.prepend(newItems);
53+
adjustBuffer();
54+
};
55+
56+
this.loading = (value) => {
57+
isLoadingInjector(value);
58+
};
59+
60+
this.calculateProperties = () => {
61+
let item, itemHeight, itemTop, isNewRow, rowTop = null;
62+
let topHeight = 0;
63+
for (let i = 0; i < buffer.length; i++) {
64+
item = buffer[i];
65+
itemTop = item.element.offset().top;
66+
isNewRow = rowTop !== itemTop;
67+
rowTop = itemTop;
68+
if (isNewRow) {
69+
itemHeight = item.element.outerHeight(true);
70+
}
71+
if (isNewRow && (viewport.topDataPos() + topHeight + itemHeight <= viewport.topVisiblePos())) {
72+
topHeight += itemHeight;
73+
} else {
74+
if (isNewRow) {
75+
topVisibleInjector(item.item);
76+
topVisibleElementInjector(item.element);
77+
topVisibleScopeInjector(item.scope);
78+
}
79+
break;
80+
}
81+
}
82+
};
83+
84+
// private function definitions
85+
86+
function createValueInjector(attribute) {
87+
let expression = $attr[attribute];
88+
let scope = viewportScope;
89+
let assign;
90+
if (expression) {
91+
// it is ok to have relaxed validation for the first part of the 'on' expression.
92+
// additional validation will be done by the $parse service below
93+
let match = expression.match(/^(\S+)(?:\s+on\s+(\w(?:\w|\d)*))?/);
94+
if (!match)
95+
throw new Error('Expected injection expression in form of \'target\' or \'target on controller\' but got \'' + expression + '\'');
96+
let target = match[1];
97+
let onControllerName = match[2];
98+
99+
let parseController = (controllerName, on) => {
100+
let candidate = element;
101+
while (candidate.length) {
102+
let candidateScope = candidate.scope();
103+
// ng-controller's "Controller As" parsing
104+
let candidateName = (candidate.attr('ng-controller') || '').match(/(\w(?:\w|\d)*)(?:\s+as\s+(\w(?:\w|\d)*))?/);
105+
if (candidateName && candidateName[on ? 1 : 2] === controllerName) {
106+
scope = candidateScope;
107+
return true;
108+
}
109+
// directive's/component's "Controller As" parsing
110+
if (!on && candidateScope && candidateScope.hasOwnProperty(controllerName) && Object.getPrototypeOf(candidateScope[controllerName]).constructor.hasOwnProperty('$inject')) {
111+
scope = candidateScope;
112+
return true;
113+
}
114+
candidate = candidate.parent();
115+
}
116+
};
117+
118+
if (onControllerName) { // 'on' syntax DOM parsing (adapter="adapter on ctrl")
119+
scope = null;
120+
parseController(onControllerName, true);
121+
if (!scope) {
122+
throw new Error('Failed to locate target controller \'' + onControllerName + '\' to inject \'' + target + '\'');
123+
}
124+
}
125+
else { // try to parse DOM with 'Controller As' syntax (adapter="ctrl.adapter")
126+
let controllerAsName;
127+
let dotIndex = target.indexOf('.');
128+
if (dotIndex > 0) {
129+
controllerAsName = target.substr(0, dotIndex);
130+
parseController(controllerAsName, false);
131+
}
132+
}
133+
134+
assign = $parse(target).assign;
135+
}
136+
return (value) => {
137+
if (self !== value) // just to avoid injecting adapter reference in the adapter itself. Kludgy, I know.
138+
self[attribute] = value;
139+
if (assign)
140+
assign(scope, value);
141+
};
142+
}
143+
144+
function applyUpdate(wrapper, newItems) {
145+
if (!angular.isArray(newItems)) {
146+
return;
147+
}
148+
149+
let keepIt;
150+
let pos = (buffer.indexOf(wrapper)) + 1;
151+
152+
newItems.reverse().forEach((newItem) => {
153+
if (newItem === wrapper.item) {
154+
keepIt = true;
155+
pos--;
156+
} else {
157+
buffer.insert(pos, newItem);
158+
}
159+
});
160+
161+
if (!keepIt) {
162+
wrapper.op = 'remove';
163+
}
164+
}
165+
97166
}

0 commit comments

Comments
 (0)