Skip to content

Commit 3c89955

Browse files
committed
jqLiteExtras is a part of ui.scroll module now
1 parent 6ed94f2 commit 3c89955

File tree

7 files changed

+273
-277
lines changed

7 files changed

+273
-277
lines changed

Gruntfile.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ module.exports = function (grunt) {
6464
files: [
6565
{expand: true, src: ['*'], cwd: 'temp', dest: 'dist/'},
6666
]
67+
},
68+
jqLiteExtrasFake: {
69+
files: [
70+
{expand: true, src: ['ui-scroll-jqlite.js'], cwd: 'src', dest: 'dist/'},
71+
]
6772
}
6873
},
6974
jshint: {
@@ -130,7 +135,8 @@ module.exports = function (grunt) {
130135
'jshint:sources',
131136
'webpack:prod',
132137
'karma:prod',
133-
'copy:sources'
138+
'copy:sources',
139+
'copy:jqLiteExtrasFake'
134140
]);
135141

136142
grunt.registerTask('travis', [

src/modules/jqLiteExtras.js

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
export default class JQLiteExtras {
2+
3+
registerFor(element) {
4+
let convertToPx, css, getStyle, isWindow;
5+
// angular implementation blows up if elem is the window
6+
css = angular.element.prototype.css;
7+
8+
element.prototype.css = function (name, value) {
9+
let self = this;
10+
let elem = self[0];
11+
if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) {
12+
return css.call(self, name, value);
13+
}
14+
};
15+
16+
// as defined in angularjs v1.0.5
17+
isWindow = (obj) => obj && obj.document && obj.location && obj.alert && obj.setInterval;
18+
19+
function scrollTo(self, direction, value) {
20+
let elem = self[0];
21+
let [method, prop, preserve] = {
22+
top: [
23+
'scrollTop',
24+
'pageYOffset',
25+
'scrollLeft'
26+
],
27+
left: [
28+
'scrollLeft',
29+
'pageXOffset',
30+
'scrollTop'
31+
]
32+
}[direction];
33+
34+
if (isWindow(elem)) {
35+
if (angular.isDefined(value)) {
36+
return elem.scrollTo(self[preserve].call(self), value);
37+
}
38+
return (prop in elem) ? elem[prop] : elem.document.documentElement[method];
39+
} else {
40+
if (angular.isDefined(value)) {
41+
elem[method] = value;
42+
}
43+
return elem[method];
44+
}
45+
}
46+
47+
if (window.getComputedStyle) {
48+
getStyle = (elem) => window.getComputedStyle(elem, null);
49+
convertToPx = (elem, value) => parseFloat(value);
50+
} else {
51+
getStyle = (elem) => elem.currentStyle;
52+
convertToPx = (elem, value) => {
53+
let left, result, rs, rsLeft, style;
54+
let core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
55+
let rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i');
56+
57+
if (!rnumnonpx.test(value)) {
58+
return parseFloat(value);
59+
}
60+
61+
// ported from JQuery
62+
style = elem.style;
63+
left = style.left;
64+
rs = elem.runtimeStyle;
65+
rsLeft = rs && rs.left;
66+
if (rs) {
67+
rs.left = style.left;
68+
}
69+
// put in the new values to get a computed style out
70+
style.left = value;
71+
result = style.pixelLeft;
72+
style.left = left;
73+
if (rsLeft) {
74+
rs.left = rsLeft;
75+
}
76+
return result;
77+
};
78+
}
79+
80+
function getMeasurements(elem, measure) {
81+
let base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB;
82+
83+
if (isWindow(elem)) {
84+
base = document.documentElement[{height: 'clientHeight', width: 'clientWidth'}[measure]];
85+
86+
return {
87+
base: base,
88+
padding: 0,
89+
border: 0,
90+
margin: 0
91+
};
92+
}
93+
94+
// Start with offset property
95+
[
96+
base,
97+
dirA,
98+
dirB
99+
] = {
100+
width: [
101+
elem.offsetWidth,
102+
'Left',
103+
'Right'
104+
],
105+
height: [
106+
elem.offsetHeight,
107+
'Top',
108+
'Bottom'
109+
]
110+
}[measure];
111+
112+
computedStyle = getStyle(elem);
113+
paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0;
114+
paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0;
115+
borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0;
116+
borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0;
117+
computedMarginA = computedStyle['margin' + dirA];
118+
computedMarginB = computedStyle['margin' + dirB];
119+
120+
// I do not care for width for now, so this hack is irrelevant
121+
// if ( !supportsPercentMargin )
122+
// computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA )
123+
// computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB )
124+
marginA = convertToPx(elem, computedMarginA) || 0;
125+
marginB = convertToPx(elem, computedMarginB) || 0;
126+
127+
return {
128+
base: base,
129+
padding: paddingA + paddingB,
130+
border: borderA + borderB,
131+
margin: marginA + marginB
132+
};
133+
}
134+
135+
function getWidthHeight(elem, direction, measure) {
136+
let computedStyle, result;
137+
138+
let measurements = getMeasurements(elem, direction);
139+
140+
if (measurements.base > 0) {
141+
return {
142+
base: measurements.base - measurements.padding - measurements.border,
143+
outer: measurements.base,
144+
outerfull: measurements.base + measurements.margin
145+
}[measure];
146+
}
147+
148+
// Fall back to computed then uncomputed css if necessary
149+
computedStyle = getStyle(elem);
150+
result = computedStyle[direction];
151+
152+
if (result < 0 || result === null) {
153+
result = elem.style[direction] || 0;
154+
}
155+
156+
// Normalize "", auto, and prepare for extra
157+
result = parseFloat(result) || 0;
158+
159+
return {
160+
base: result - measurements.padding - measurements.border,
161+
outer: result,
162+
outerfull: result + measurements.padding + measurements.border + measurements.margin
163+
}[measure];
164+
}
165+
166+
// define missing methods
167+
return angular.forEach({
168+
before(newElem) {
169+
var children, elem, i, j, parent, ref, self;
170+
self = this;
171+
elem = self[0];
172+
parent = self.parent();
173+
children = parent.contents();
174+
if (children[0] === elem) {
175+
return parent.prepend(newElem);
176+
} else {
177+
for (i = j = 1, ref = children.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {
178+
if (children[i] === elem) {
179+
angular.element(children[i - 1]).after(newElem);
180+
return;
181+
}
182+
}
183+
throw new Error('invalid DOM structure ' + elem.outerHTML);
184+
}
185+
},
186+
height (value){
187+
var self;
188+
self = this;
189+
if (angular.isDefined(value)) {
190+
if (angular.isNumber(value)) {
191+
value = value + 'px';
192+
}
193+
return css.call(self, 'height', value);
194+
} else {
195+
return getWidthHeight(this[0], 'height', 'base');
196+
}
197+
},
198+
outerHeight(option) {
199+
return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer');
200+
},
201+
outerWidth(option) {
202+
return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer');
203+
},
204+
205+
/*
206+
The offset setter method is not implemented
207+
*/
208+
offset(value) {
209+
let docElem, win;
210+
let self = this;
211+
let box = {
212+
top: 0,
213+
left: 0
214+
};
215+
let elem = self[0];
216+
let doc = elem && elem.ownerDocument;
217+
218+
if (arguments.length) {
219+
if (value === undefined) {
220+
return self;
221+
}
222+
// TODO: implement setter
223+
throw new Error('offset setter method is not implemented');
224+
}
225+
226+
if (!doc) {
227+
return;
228+
}
229+
230+
docElem = doc.documentElement;
231+
232+
// TODO: Make sure it's not a disconnected DOM node
233+
234+
if (elem.getBoundingClientRect != null) {
235+
box = elem.getBoundingClientRect();
236+
}
237+
238+
win = doc.defaultView || doc.parentWindow;
239+
240+
return {
241+
top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
242+
left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
243+
};
244+
},
245+
scrollTop(value) {
246+
return scrollTo(this, 'top', value);
247+
},
248+
scrollLeft(value) {
249+
return scrollTo(this, 'left', value);
250+
}
251+
}, (value, key) => {
252+
if (!element.prototype[key]) {
253+
return element.prototype[key] = value;
254+
}
255+
});
256+
}
257+
258+
}

0 commit comments

Comments
 (0)