Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
693 steven 1
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
2
 * @license MIT */
3
 
4
;(function(root, factory) {
5
 
6
  if (typeof define === 'function' && define.amd) {
7
    define(factory);
8
  } else if (typeof exports === 'object') {
9
    module.exports = factory();
10
  } else {
11
    root.NProgress = factory();
12
  }
13
 
14
})(this, function() {
15
  var NProgress = {};
16
 
17
  NProgress.version = '0.2.0';
18
 
19
  var Settings = NProgress.settings = {
20
    minimum: 0.08,
21
    easing: 'linear',
22
    positionUsing: '',
23
    speed: 200,
24
    trickle: true,
25
    trickleSpeed: 200,
26
    showSpinner: true,
27
    barSelector: '[role="bar"]',
28
    spinnerSelector: '[role="spinner"]',
29
    parent: 'body',
30
    template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
31
  };
32
 
33
  /**
34
   * Updates configuration.
35
   *
36
   *     NProgress.configure({
37
   *       minimum: 0.1
38
   *     });
39
   */
40
  NProgress.configure = function(options) {
41
    var key, value;
42
    for (key in options) {
43
      value = options[key];
44
      if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
45
    }
46
 
47
    return this;
48
  };
49
 
50
  /**
51
   * Last number.
52
   */
53
 
54
  NProgress.status = null;
55
 
56
  /**
57
   * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
58
   *
59
   *     NProgress.set(0.4);
60
   *     NProgress.set(1.0);
61
   */
62
 
63
  NProgress.set = function(n) {
64
    var started = NProgress.isStarted();
65
 
66
    n = clamp(n, Settings.minimum, 1);
67
    NProgress.status = (n === 1 ? null : n);
68
 
69
    var progress = NProgress.render(!started),
70
        bar      = progress.querySelector(Settings.barSelector),
71
        speed    = Settings.speed,
72
        ease     = Settings.easing;
73
 
74
    progress.offsetWidth; /* Repaint */
75
 
76
    queue(function(next) {
77
      // Set positionUsing if it hasn't already been set
78
      if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
79
 
80
      // Add transition
81
      css(bar, barPositionCSS(n, speed, ease));
82
 
83
      if (n === 1) {
84
        // Fade out
85
        css(progress, {
86
          transition: 'none',
87
          opacity: 1
88
        });
89
        progress.offsetWidth; /* Repaint */
90
 
91
        setTimeout(function() {
92
          css(progress, {
93
            transition: 'all ' + speed + 'ms linear',
94
            opacity: 0
95
          });
96
          setTimeout(function() {
97
            NProgress.remove();
98
            next();
99
          }, speed);
100
        }, speed);
101
      } else {
102
        setTimeout(next, speed);
103
      }
104
    });
105
 
106
    return this;
107
  };
108
 
109
  NProgress.isStarted = function() {
110
    return typeof NProgress.status === 'number';
111
  };
112
 
113
  /**
114
   * Shows the progress bar.
115
   * This is the same as setting the status to 0%, except that it doesn't go backwards.
116
   *
117
   *     NProgress.start();;
118
   *
119
   */
120
  NProgress.start = function() {
121
    if (!NProgress.status) NProgress.set(0);
122
 
123
    var work = function() {
124
      setTimeout(function() {
125
        if (!NProgress.status) return;
126
        NProgress.trickle();
127
        work();
128
      }, Settings.trickleSpeed);
129
    };
130
 
131
    if (Settings.trickle) work();
132
 
133
    return this;
134
  };
135
 
136
  /**
137
   * Hides the progress bar.
138
   * This is the *sort of* the same as setting the status to 100%, with the
139
   * difference being `done()` makes some placebo effect of some realistic motion.
140
   *
141
   *     NProgress.done();
142
   *
143
   * If `true` is passed, it will show the progress bar even if its hidden.
144
   *
145
   *     NProgress.done(true);
146
   */
147
 
148
  NProgress.done = function(force) {
149
    if (!force && !NProgress.status) return this;
150
 
151
    return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
152
  };
153
 
154
  /**
155
   * Increments by a random amount.
156
   */
157
 
158
  NProgress.inc = function(amount) {
159
    var n = NProgress.status;
160
 
161
    if (!n) {
162
      return NProgress.start();;
163
    } else if(n > 1) {
164
      return;
165
    } else {
166
      if (typeof amount !== 'number') {
167
        if (n >= 0 && n < 0.2) { amount = 0.1; }
168
        else if (n >= 0.2 && n < 0.5) { amount = 0.04; }
169
        else if (n >= 0.5 && n < 0.8) { amount = 0.02; }
170
        else if (n >= 0.8 && n < 0.99) { amount = 0.005; }
171
        else { amount = 0; }
172
      }
173
 
174
      n = clamp(n + amount, 0, 0.994);
175
      return NProgress.set(n);
176
    }
177
  };
178
 
179
  NProgress.trickle = function() {
180
    return NProgress.inc();
181
  };
182
 
183
  /**
184
   * Waits for all supplied jQuery promises and
185
   * increases the progress as the promises resolve.
186
   *
187
   * @param $promise jQUery Promise
188
   */
189
  (function() {
190
    var initial = 0, current = 0;
191
 
192
    NProgress.promise = function($promise) {
193
      if (!$promise || $promise.state() === "resolved") {
194
        return this;
195
      }
196
 
197
      if (current === 0) {
198
        NProgress.start();;
199
      }
200
 
201
      initial++;
202
      current++;
203
 
204
      $promise.always(function() {
205
        current--;
206
        if (current === 0) {
207
            initial = 0;
208
            NProgress.done();
209
        } else {
210
            NProgress.set((initial - current) / initial);
211
        }
212
      });
213
 
214
      return this;
215
    };
216
 
217
  })();
218
 
219
  /**
220
   * (Internal) renders the progress bar markup based on the `template`
221
   * setting.
222
   */
223
 
224
  NProgress.render = function(fromStart) {
225
    if (NProgress.isRendered()) return document.getElementById('nprogress');
226
 
227
    addClass(document.documentElement, 'nprogress-busy');
228
 
229
    var progress = document.createElement('div');
230
    progress.id = 'nprogress';
231
    progress.innerHTML = Settings.template;
232
 
233
 
234
 
235
    var bar = progress.querySelector(Settings.barSelector),
236
        perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
237
        parent = isDOM(Settings.parent)
238
          ? Settings.parent
239
          : document.querySelector(Settings.parent),
240
        spinner
241
 
242
    css(bar, {
243
      transition: 'all 0 linear',
244
      transform: 'translate3d(' + perc + '%,0,0)'
245
    });
246
 
247
    if (!Settings.showSpinner) {
248
      spinner = progress.querySelector(Settings.spinnerSelector);
249
      spinner && removeElement(spinner);
250
    }
251
 
252
    if (parent != document.body) {
253
      addClass(parent, 'nprogress-custom-parent');
254
    }
255
 
256
    parent.appendChild(progress);
257
    return progress;
258
  };
259
 
260
  /**
261
   * Removes the element. Opposite of render().
262
   */
263
 
264
  NProgress.remove = function() {
265
    removeClass(document.documentElement, 'nprogress-busy');
266
    var parent = isDOM(Settings.parent)
267
      ? Settings.parent
268
      : document.querySelector(Settings.parent)
269
    removeClass(parent, 'nprogress-custom-parent')
270
    var progress = document.getElementById('nprogress');
271
    progress && removeElement(progress);
272
  };
273
 
274
  /**
275
   * Checks if the progress bar is rendered.
276
   */
277
 
278
  NProgress.isRendered = function() {
279
    return !!document.getElementById('nprogress');
280
  };
281
 
282
  /**
283
   * Determine which positioning CSS rule to use.
284
   */
285
 
286
  NProgress.getPositioningCSS = function() {
287
    // Sniff on document.body.style
288
    var bodyStyle = document.body.style;
289
 
290
    // Sniff prefixes
291
    var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
292
                       ('MozTransform' in bodyStyle) ? 'Moz' :
293
                       ('msTransform' in bodyStyle) ? 'ms' :
294
                       ('OTransform' in bodyStyle) ? 'O' : '';
295
 
296
    if (vendorPrefix + 'Perspective' in bodyStyle) {
297
      // Modern browsers with 3D support, e.g. Webkit, IE10
298
      return 'translate3d';
299
    } else if (vendorPrefix + 'Transform' in bodyStyle) {
300
      // Browsers without 3D support, e.g. IE9
301
      return 'translate';
302
    } else {
303
      // Browsers without translate() support, e.g. IE7-8
304
      return 'margin';
305
    }
306
  };
307
 
308
  /**
309
   * Helpers
310
   */
311
 
312
  function isDOM (obj) {
313
    if (typeof HTMLElement === 'object') {
314
      return obj instanceof HTMLElement
315
    }
316
    return (
317
      obj &&
318
      typeof obj === 'object' &&
319
      obj.nodeType === 1 &&
320
      typeof obj.nodeName === 'string'
321
    )
322
  }
323
 
324
  function clamp(n, min, max) {
325
    if (n < min) return min;
326
    if (n > max) return max;
327
    return n;
328
  }
329
 
330
  /**
331
   * (Internal) converts a percentage (`0..1`) to a bar translateX
332
   * percentage (`-100%..0%`).
333
   */
334
 
335
  function toBarPerc(n) {
336
    return (-1 + n) * 100;
337
  }
338
 
339
 
340
  /**
341
   * (Internal) returns the correct CSS for changing the bar's
342
   * position given an n percentage, and speed and ease from Settings
343
   */
344
 
345
  function barPositionCSS(n, speed, ease) {
346
    var barCSS;
347
 
348
    if (Settings.positionUsing === 'translate3d') {
349
      barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
350
    } else if (Settings.positionUsing === 'translate') {
351
      barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
352
    } else {
353
      barCSS = { 'margin-left': toBarPerc(n)+'%' };
354
    }
355
 
356
    barCSS.transition = 'all '+speed+'ms '+ease;
357
 
358
    return barCSS;
359
  }
360
 
361
  /**
362
   * (Internal) Queues a function to be executed.
363
   */
364
 
365
  var queue = (function() {
366
    var pending = [];
367
 
368
    function next() {
369
      var fn = pending.shift();
370
      if (fn) {
371
        fn(next);
372
      }
373
    }
374
 
375
    return function(fn) {
376
      pending.push(fn);
377
      if (pending.length == 1) next();
378
    };
379
  })();
380
 
381
  /**
382
   * (Internal) Applies css properties to an element, similar to the jQuery
383
   * css method.
384
   *
385
   * While this helper does assist with vendor prefixed property names, it
386
   * does not perform any manipulation of values prior to setting styles.
387
   */
388
 
389
  var css = (function() {
390
    var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
391
        cssProps    = {};
392
 
393
    function camelCase(string) {
394
      return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
395
        return letter.toUpperCase();
396
      });
397
    }
398
 
399
    function getVendorProp(name) {
400
      var style = document.body.style;
401
      if (name in style) return name;
402
 
403
      var i = cssPrefixes.length,
404
          capName = name.charAt(0).toUpperCase() + name.slice(1),
405
          vendorName;
406
      while (i--) {
407
        vendorName = cssPrefixes[i] + capName;
408
        if (vendorName in style) return vendorName;
409
      }
410
 
411
      return name;
412
    }
413
 
414
    function getStyleProp(name) {
415
      name = camelCase(name);
416
      return cssProps[name] || (cssProps[name] = getVendorProp(name));
417
    }
418
 
419
    function applyCss(element, prop, value) {
420
      prop = getStyleProp(prop);
421
      element.style[prop] = value;
422
    }
423
 
424
    return function(element, properties) {
425
      var args = arguments,
426
          prop,
427
          value;
428
 
429
      if (args.length == 2) {
430
        for (prop in properties) {
431
          value = properties[prop];
432
          if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
433
        }
434
      } else {
435
        applyCss(element, args[1], args[2]);
436
      }
437
    }
438
  })();
439
 
440
  /**
441
   * (Internal) Determines if an element or space separated list of class names contains a class name.
442
   */
443
 
444
  function hasClass(element, name) {
445
    var list = typeof element == 'string' ? element : classList(element);
446
    return list.indexOf(' ' + name + ' ') >= 0;
447
  }
448
 
449
  /**
450
   * (Internal) Adds a class to an element.
451
   */
452
 
453
  function addClass(element, name) {
454
    var oldList = classList(element),
455
        newList = oldList + name;
456
 
457
    if (hasClass(oldList, name)) return;
458
 
459
    // Trim the opening space.
460
    element.className = newList.substring(1);
461
  }
462
 
463
  /**
464
   * (Internal) Removes a class from an element.
465
   */
466
 
467
  function removeClass(element, name) {
468
    var oldList = classList(element),
469
        newList;
470
 
471
    if (!hasClass(element, name)) return;
472
 
473
    // Replace the class name.
474
    newList = oldList.replace(' ' + name + ' ', ' ');
475
 
476
    // Trim the opening and closing spaces.
477
    element.className = newList.substring(1, newList.length - 1);
478
  }
479
 
480
  /**
481
   * (Internal) Gets a space separated list of the class names on the element.
482
   * The list is wrapped with a single space on each end to facilitate finding
483
   * matches within the list.
484
   */
485
 
486
  function classList(element) {
487
    return (' ' + (element && element.className || '') + ' ').replace(/\s+/gi, ' ');
488
  }
489
 
490
  /**
491
   * (Internal) Removes an element from the DOM.
492
   */
493
 
494
  function removeElement(element) {
495
    element && element.parentNode && element.parentNode.removeChild(element);
496
  }
497
 
498
  return NProgress;
499
});