ocLazyLoad.loaders.common.js
5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
(function (angular) {
'use strict';
angular.module('oc.lazyLoad').config(["$provide", function ($provide) {
$provide.decorator('$ocLazyLoad', ["$delegate", "$q", "$window", "$interval", function ($delegate, $q, $window, $interval) {
var uaCssChecked = false,
useCssLoadPatch = false,
anchor = $window.document.getElementsByTagName('head')[0] || $window.document.getElementsByTagName('body')[0];
/**
* Load a js/css file
* @param type
* @param path
* @param params
* @returns promise
*/
$delegate.buildElement = function buildElement(type, path, params) {
var deferred = $q.defer(),
el,
loaded,
filesCache = $delegate._getFilesCache(),
cacheBuster = function cacheBuster(url) {
var dc = new Date().getTime();
if (url.indexOf('?') >= 0) {
if (url.substring(0, url.length - 1) === '&') {
return url + '_dc=' + dc;
}
return url + '&_dc=' + dc;
} else {
return url + '?_dc=' + dc;
}
};
// Store the promise early so the file load can be detected by other parallel lazy loads
// (ie: multiple routes on one page) a 'true' value isn't sufficient
// as it causes false positive load results.
if (angular.isUndefined(filesCache.get(path))) {
filesCache.put(path, deferred.promise);
}
// Switch in case more content types are added later
switch (type) {
case 'css':
el = $window.document.createElement('link');
el.type = 'text/css';
el.rel = 'stylesheet';
el.href = params.cache === false ? cacheBuster(path) : path;
break;
case 'js':
el = $window.document.createElement('script');
el.src = params.cache === false ? cacheBuster(path) : path;
break;
default:
filesCache.remove(path);
deferred.reject(new Error('Requested type "' + type + '" is not known. Could not inject "' + path + '"'));
break;
}
el.onload = el['onreadystatechange'] = function (e) {
if (el['readyState'] && !/^c|loade/.test(el['readyState']) || loaded) return;
el.onload = el['onreadystatechange'] = null;
loaded = 1;
$delegate._broadcast('ocLazyLoad.fileLoaded', path);
deferred.resolve();
};
el.onerror = function () {
filesCache.remove(path);
deferred.reject(new Error('Unable to load ' + path));
};
el.async = params.serie ? 0 : 1;
var insertBeforeElem = anchor.lastChild;
if (params.insertBefore) {
var element = angular.element(angular.isDefined(window.jQuery) ? params.insertBefore : document.querySelector(params.insertBefore));
if (element && element.length > 0) {
insertBeforeElem = element[0];
}
}
insertBeforeElem.parentNode.insertBefore(el, insertBeforeElem);
/*
The event load or readystatechange doesn't fire in:
- iOS < 6 (default mobile browser)
- Android < 4.4 (default mobile browser)
- Safari < 6 (desktop browser)
*/
if (type == 'css') {
if (!uaCssChecked) {
var ua = $window.navigator.userAgent.toLowerCase();
// iOS < 6
if (/iP(hone|od|ad)/.test($window.navigator.platform)) {
var v = $window.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/);
var iOSVersion = parseFloat([parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)].join('.'));
useCssLoadPatch = iOSVersion < 6;
} else if (ua.indexOf("android") > -1) {
// Android < 4.4
var androidVersion = parseFloat(ua.slice(ua.indexOf("android") + 8));
useCssLoadPatch = androidVersion < 4.4;
} else if (ua.indexOf('safari') > -1) {
var versionMatch = ua.match(/version\/([\.\d]+)/i);
useCssLoadPatch = versionMatch && versionMatch[1] && parseFloat(versionMatch[1]) < 6;
}
}
if (useCssLoadPatch) {
var tries = 1000; // * 20 = 20000 miliseconds
var interval = $interval(function () {
try {
el.sheet.cssRules;
$interval.cancel(interval);
el.onload();
} catch (e) {
if (--tries <= 0) {
el.onerror();
}
}
}, 20);
}
}
return deferred.promise;
};
return $delegate;
}]);
}]);
})(angular);