PageSourceSearch

https://www.fumotousa.com/skins/common/js/lazyload.js?1788549650

js fumotousa.com collected 2026-09-26 02:17:04 UTC 13,424 bytes, 368 lines download raw bytes

1/*jslint browser: true, eqeqeq: true, bitwise: true, newcap: true, immed: true, regexp: false */
2
3/**
4LazyLoad makes it easy and painless to lazily load one or more external
5JavaScript or CSS files on demand either during or after the rendering of a web
6page.
7
8Supported browsers include Firefox 3.6+, IE9+, Safari 5.1.4+ (untested) (including Mobile
9Safari), Google Chrome 10+, and Opera 12+. Other browsers may or may not work and
10are not officially supported, including the browsers supported by the original LazyLoad:
11Firefox 2+, IE6+, Safari 3+, Google Chrome 0.8+, and Opera 9+ (not yet tested).
12
13Visit https://github.com/lewisje/lazyload/ for more info.
14
15Copyright (c) 2011 Ryan Grove <[email protected]>
16All rights reserved.
17Changes made by Cezary Daniel Nowak, 2014, and James Edward Lewis II, 2015.
18
19Permission is hereby granted, free of charge, to any person obtaining a copy of
20this software and associated documentation files (the 'Software'), to deal in
21the Software without restriction, including without limitation the rights to
22use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23the Software, and to permit persons to whom the Software is furnished to do so,
24subject to the following conditions:
25
26The above copyright notice and this permission notice shall be included in all
27copies or substantial portions of the Software.
28
29THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
36@module lazyload
37@class LazyLoad
38@static
39*/
40
41var LazyLoad = (function (doc) {
42  'use strict';
43  // -- Private Variables ------------------------------------------------------
44
45  // Reference to the <head> element (populated lazily).
46  var head,
47
48  // Requests currently in progress, if any.
49  pending = {},
50
51  // Number of times we've polled to check whether a pending stylesheet has
52  // finished loading. If this gets too high, we're probably stalled.
53  pollCount = 0,
54
55  // Cached requests.
56  cache = {},
57
58  // Queued requests.
59  queue = {css: [], js: []},
60  
61  // Whether Function#bind exists.
62  canBind = typeof Function.prototype.bind === 'function',
63
64  // Reference to the browser's list of stylesheets.
65  styleSheets = doc.styleSheets,
66  finishCSS = canBind ? finish.bind(doc, 'css') : function finishCSS() {finish('css');},
67  ua = navigator.userAgent,
68  // User agent and feature test information.
69  env = {
70    // True if this browser supports disabling async mode on dynamically
71    // created script nodes. See
72    // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
73    async: createNode('script').async === true
74  };
75
76  if (/AppleWebKit\//.test(ua)) env.webkit = true;
77  else if (/MSIE|Trident/.test(ua)) env.ie = true;
78  else if (/Opera/.test(ua)) env.opera = true;
79  else if (/Gecko\//.test(ua)) env.gecko = true;
80  else env.unknown = true;
81  // -- Private Methods --------------------------------------------------------
82
83  /**
84  Creates and returns an HTML element with the specified name and attributes.
85
86  @method createNode
87  @param {String} name element name
88  @param {Object} attrs name/value mapping of element attributes
89  @return {HTMLElement}
90  @private
91  */
92  function createNode(name, attrs) {
93    var attr,
94        node = doc.createElement(name);
95
96    if(attrs) {
97      for (attr in attrs) {
98        if (attrs.hasOwnProperty(attr)) {
99          node.setAttribute(attr, attrs[attr]);
100        }
101      }
102    }
103
104    return node;
105  }
106
107  /**
108  Called when the current pending resource of the specified type has finished
109  loading. Executes the associated callback (if any) and loads the next
110  resource in the queue.
111
112  @method finish
113  @param {String} type resource type ('css' or 'js')
114  @private
115  */
116  function finish(type) {
117    var p = pending[type], callback, urls;
118
119    if (p) {
120      callback = p.callback;
121      urls = p.urls;
122
123      cache[urls.shift()] = true;
124      pollCount = 0;
125
126      // If this is the last of the pending URLs, execute the callback and
127      // start the next request in the queue (if any).
128      if (!urls.length) {
129        if (typeof callback === 'function') callback.call(p.context, p.obj);
130        pending[type] = 0;
131        if (queue[type].length) load(type);
132      }
133    }
134  }
135
136  /**
137  Loads the specified resources, or the next resource of the specified type
138  in the queue if no resources are specified. If a resource of the specified
139  type is already being loaded, the new request will be queued until the
140  first request has been finished.
141
142  When an array of resource URLs is specified, those URLs will be loaded in
143  parallel if it is possible to do so while preserving execution order. All
144  browsers support parallel loading of CSS, but only Firefox and Opera
145  support parallel loading of scripts. In other browsers, scripts will be
146  queued and loaded one at a time to ensure correct execution order.
147
148  @method load
149  @param {String} type resource type ('css' or 'js')
150  @param {String|Array} urls (optional) URL or array of URLs to load
151  @param {Function} callback (optional) callback function to execute when the
152    resource is loaded
153  @param {Object} obj (optional) object to pass to the callback function
154  @param {Object} context (optional) if provided, the callback function will
155    be executed in this object's context
156  @private
157  */
158  function load(type, urls, callback, obj, context) {
159    var _finish = canBind ? finish.bind(doc, type) : function _finish() {finish(type);},
160        isCSS = type === 'css', nodes = [], i, len, node, p, pendingUrls, url;
161
162    if (urls) {
163      // If urls is a string, wrap it in an array. Otherwise assume it's an
164      // array and create a copy of it so modifications won't be made to the
165      // original.
166      urls = typeof urls === 'string' ? [urls] : urls.slice();
167
168      // Create a request object for each URL. If multiple URLs are specified,
169      // the callback will only be executed after all URLs have been loaded.
170      //
171      // Sadly, Firefox and Opera are the only browsers capable of loading
172      // scripts in parallel while preserving execution order. In all other
173      // browsers, scripts must be loaded sequentially.
174      //
175      // All browsers respect CSS specificity based on the order of the link
176      // elements in the DOM, regardless of the order in which the stylesheets
177      // are actually downloaded.
178      if (isCSS || env.async || env.gecko || env.opera) {
179        // Load in parallel.
180        queue[type].push({
181          urls : urls,
182          callback: callback,
183          obj : obj,
184          context : context
185        });
186      } else {
187        // Load sequentially.
188        for (i = 0, len = urls.length; i < len; ++i) {
189          queue[type].push({
190            urls : [urls[i]],
191            callback: i === len - 1 ? callback : 0, // callback is only added to the last URL
192            obj : obj,
193            context : context
194          });
195        }
196      }
197    }
198
199    // If a previous load request of this type is currently in progress, we'll
200    // wait our turn. Otherwise, grab the next item in the queue.
201    if (pending[type] || !(p = pending[type] = queue[type].shift())) return;
202    head = head || doc.head || doc.getElementsByTagName('head')[0];
203    pendingUrls = p.urls.slice();
204
205    var nodeReady = function nodeReady() {
206      if (/^(?:loaded|complete)$/i.test(node.readyState)) {
207        node.onreadystatechange = null;
208        _finish();
209      }
210    };
211    for (i = 0, len = pendingUrls.length; i < len; ++i) {
212      url = pendingUrls[i];
213      if(cache[url] != null && !url.startsWith("var/theme/custom.css")) {
214        // _finish here can cause unexpected behavior when cache[url] === false but
215        // I won't figure out solution, since first issue on github :-)
216        _finish();
217        continue; //prevent scripts/css from being loaded multiple times
218      } else {
219        cache[url] = false;
220      }
221      if (isCSS) {
222        node = env.gecko ? createNode('style') : createNode('link', {
223          href: url,
224          rel : 'stylesheet'
225        });
226      } else {
227        node = createNode('script', {src: url});
228        node.async = false;
229      }
230
231      node.className = 'lazyload';
232      node.setAttribute('charset', 'utf-8');
233
234      if (env.ie && !isCSS && 'onreadystatechange' in node && !('draggable' in node)) {
235        node.onreadystatechange = nodeReady;
236      } else if (isCSS && (env.gecko || env.webkit)) {
237        // Gecko and WebKit don't support the onload event on link nodes.
238        if (env.webkit) {
239          // In WebKit, we can poll for changes to document.styleSheets to
240          // figure out when stylesheets have loaded.
241          p.urls[i] = node.href; // resolve relative URLs (or polling won't work)
242          pollWebKit();
243        } else {
244          // In Gecko, we can import the requested URL into a <style> node and
245          // poll for the existence of node.sheet.cssRules. Props to Zach
246          // Leatherman for calling my attention to this technique.
247          node.innerHTML = '@import "' + url + '";';
248          pollGecko(node);
249        }
250      } else {
251        node.onload = node.onerror = _finish;
252      }
253      nodes.push(node);
254    }
255    for (i = 0, len = nodes.length; i < len; ++i) {
256      head.appendChild(nodes[i]);
257    }
258  }
259
260  /**
261  Begins polling to determine when the specified stylesheet has finished loading
262  in Gecko. Polling stops when all pending stylesheets have loaded or after 10
263  seconds (to prevent stalls).
264
265  Thanks to Zach Leatherman for calling my attention to the @import-based
266  cross-domain technique used here, and to Oleg Slobodskoi for an earlier
267  same-domain implementation. See Zach's blog for more details:
268  http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
269
270  @method pollGecko
271  @param {HTMLElement} node Style node to poll.
272  @private
273  */
274  function pollGecko(node) {
275    var hasRules = 'sheet' in node && node.sheet && 'cssRules' in node.sheet;
276
277    if (!hasRules) {
278      // The stylesheet is still loading.
279      ++pollCount;
280      if (pollCount < 200) {
281        setTimeout(canBind ? pollGecko.bind(doc, node) : function pollBind() {pollGecko(node);}, 50);
282      } else {
283        // We've been polling for 10 seconds and nothing's happened. Stop
284        // polling and finish the pending requests to avoid blocking further
285        // requests.
286        if (hasRules) finishCSS();
287      }
288      return;
289    }
290    // If we get here, the stylesheet has loaded.
291    finishCSS();
292  }
293
294  /**
295  Begins polling to determine when pending stylesheets have finished loading
296  in WebKit. Polling stops when all pending stylesheets have loaded or after 10
297  seconds (to prevent stalls).
298
299  @method pollWebKit
300  @private
301  */
302  function pollWebKit() {
303    var css = pending.css, i;
304
305    if (css) {
306      i = styleSheets.length;
307      // Look for a stylesheet matching the pending URL.
308      while (--i >= 0) {
309        if (styleSheets[i].href === css.urls[0]) {
310          finishCSS();
311          break;
312        }
313      }
314
315      ++pollCount;
316      if (css) {
317        if (pollCount < 200) {
318          setTimeout(pollWebKit, 50);
319        } else {
320          // We've been polling for 10 seconds and nothing's happened, which may
321          // indicate that the stylesheet has been removed from the document
322          // before it had a chance to load. Stop polling and finish the pending
323          // request to prevent blocking further requests.
324          finishCSS();
325        }
326      }
327    }
328  }
329
330  return {
331    /**
332    Requests the specified CSS URL or URLs and executes the specified
333    callback (if any) when they have finished loading. If an array of URLs is
334    specified, the stylesheets will be loaded in parallel and the callback
335    will be executed after all stylesheets have finished loading.
336
337    @method css
338    @param {String|Array} urls CSS URL or array of CSS URLs to load
339    @param {Function} callback (optional) callback function to execute when
340      the specified stylesheets are loaded
341    @static
342    */
343    css: canBind ? load.bind(load, 'css') : function css(urls, callback, obj, context) {
344      load('css', urls, callback, obj, context);
345    },
346
347    /**
348    Requests the specified JavaScript URL or URLs and executes the specified
349    callback (if any) when they have finished loading. If an array of URLs is
350    specified and the browser supports it, the scripts will be loaded in
351    parallel and the callback will be executed after all scripts have
352    finished loading.
353
354    Currently, only Firefox and Opera support parallel loading of scripts while
355    preserving execution order. In other browsers, scripts will be
356    queued and loaded one at a time to ensure correct execution order.
357
358    @method js
359    @param {String|Array} urls JS URL or array of JS URLs to load
360    @param {Function} callback (optional) callback function to execute when
361      the specified scripts are loaded
362    @static
363    */
364    js: canBind ? load.bind(load, 'js') : function js(urls, callback, obj, context) {
365      load('js', urls, callback, obj, context);
366    }
367  };
368})(this.document);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.