-
Notifications
You must be signed in to change notification settings - Fork 0
/
preload.js
126 lines (104 loc) · 3.66 KB
/
preload.js
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
'use strict';
// Ensure we have bind capabilities
// Source: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
var IMGPreloader = function(options) {
this._unprocessedImagesByHost = {};
this._processingImagesByHost = {};
this._concurrentConnectionsPerHost = 6; //TODO: Choose best option based on browser
};
IMGPreloader.prototype.processQueue = function processQueue() {
var host,
i = 0,
queueItem;
for (host in this._unprocessedImagesByHost) {
if (!this._unprocessedImagesByHost.hasOwnProperty(host)) {
continue;
}
if (this._processingImagesByHost[host] === undefined) {
this._processingImagesByHost[host] = [];
}
if (this._processingImagesByHost[host].length < this._concurrentConnectionsPerHost) {
for (; i < this._concurrentConnectionsPerHost - this._processingImagesByHost[host].length; i++) {
queueItem = this._unprocessedImagesByHost[host].shift();
if (queueItem !== undefined) {
this._processingImagesByHost[host].push(queueItem);
var imgElement = new Image();
imgElement.src = queueItem;
if (imgElement.complete === true) {
this.removeProcessedItem(queueItem);
this.processQueue();
} else {
imgElement.addEventListener('load', function(e) {
this.removeProcessedItem(e.target.src);
this.processQueue();
}.bind(this));
imgElement.addEventListener('error', function(e) {
this.removeProcessedItem(e.target.src, true);
this.processQueue();
}.bind(this));
}
}
}
}
}
};
IMGPreloader.prototype.removeProcessedItem = function removeProcessedItem(item, shouldReprocess) {
var i = 0,
uri = new Uri(item),
host = uri.host(),
hostQueue = this._processingImagesByHost[host],
hostQueueLength = hostQueue.length;
for (; i < hostQueueLength; i++) {
if (hostQueue[i] === item) {
hostQueue.splice(i, 1);
}
}
};
IMGPreloader.prototype.cleanQueue = function cleanQueue() {
var host;
for (host in this._unprocessedImagesByHost) {
if (this._unprocessedImagesByHost.hasOwnProperty(host) && this._unprocessedImagesByHost[host].length === 0) {
delete(this._unprocessedImagesByHost[host]);
}
}
};
IMGPreloader.prototype.push = function push(src) {
if(src){
var uri = new Uri(src);
if (this._unprocessedImagesByHost[uri.host()] === undefined) {
this._unprocessedImagesByHost[uri.host()] = [];
}
this._unprocessedImagesByHost[uri.host()].push(src);
this.cleanQueue();
this.processQueue();
}
};
IMGPreloader.prototype.push_many = function push_many(arrayOfSrc) {
var length = arrayOfSrc.length,
i = 0;
if (length > 0) {
for(; i < length; i++) {
this.push(arrayOfSrc[i]);
}
}
}