Issues (4542)

js/nprogress.js (18 issues)

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.1.6';
18
19
  var Settings = NProgress.settings = {
20
    minimum: 0.08,
21
    easing: 'ease',
22
    positionUsing: '',
23
    speed: 200,
24
    trickle: true,
25
    trickleRate: 0.02,
26
    trickleSpeed: 800,
27
    showSpinner: true,
28
    barSelector: '[role="bar"]',
29
    spinnerSelector: '[role="spinner"]',
30
    parent: 'body',
31
    template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
32
  };
33
34
  /**
35
   * Updates configuration.
36
   *
37
   *     NProgress.configure({
38
   *       minimum: 0.1
39
   *     });
40
   */
41
  NProgress.configure = function(options) {
42
    var key, value;
43
    for (key in options) {
44
      value = options[key];
45
      if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
46
    }
47
48
    return this;
49
  };
50
51
  /**
52
   * Last number.
53
   */
54
55
  NProgress.status = null;
56
57
  /**
58
   * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
59
   *
60
   *     NProgress.set(0.4);
61
   *     NProgress.set(1.0);
62
   */
63
64
  NProgress.set = function(n) {
65
    var started = NProgress.isStarted();
66
67
    n = clamp(n, Settings.minimum, 1);
68
    NProgress.status = (n === 1 ? null : n);
69
70
    var progress = NProgress.render(!started),
71
        bar      = progress.querySelector(Settings.barSelector),
72
        speed    = Settings.speed,
73
        ease     = Settings.easing;
74
75
    progress.offsetWidth; /* Repaint */
0 ignored issues
show
The result of the property access to progress.offsetWidth is not used.
Loading history...
76
77
    queue(function(next) {
78
      // Set positionUsing if it hasn't already been set
79
      if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
80
81
      // Add transition
82
      css(bar, barPositionCSS(n, speed, ease));
83
84
      if (n === 1) {
85
        // Fade out
86
        css(progress, { 
87
          transition: 'none', 
88
          opacity: 1 
89
        });
90
        progress.offsetWidth; /* Repaint */
0 ignored issues
show
The result of the property access to progress.offsetWidth is not used.
Loading history...
91
92
        setTimeout(function() {
93
          css(progress, { 
94
            transition: 'all ' + speed + 'ms linear', 
95
            opacity: 0 
96
          });
97
          setTimeout(function() {
98
            NProgress.remove();
99
            next();
100
          }, speed);
101
        }, speed);
102
      } else {
103
        setTimeout(next, speed);
104
      }
105
    });
106
107
    return this;
108
  };
109
110
  NProgress.isStarted = function() {
111
    return typeof NProgress.status === 'number';
112
  };
113
114
  /**
115
   * Shows the progress bar.
116
   * This is the same as setting the status to 0%, except that it doesn't go backwards.
117
   *
118
   *     NProgress.start();
119
   *
120
   */
121
  NProgress.start = function() {
122
    if (!NProgress.status) NProgress.set(0);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
123
124
    var work = function() {
125
      setTimeout(function() {
126
        if (!NProgress.status) return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
127
        NProgress.trickle();
128
        work();
129
      }, Settings.trickleSpeed);
130
    };
131
132
    if (Settings.trickle) work();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
133
134
    return this;
135
  };
136
137
  /**
138
   * Hides the progress bar.
139
   * This is the *sort of* the same as setting the status to 100%, with the
140
   * difference being `done()` makes some placebo effect of some realistic motion.
141
   *
142
   *     NProgress.done();
143
   *
144
   * If `true` is passed, it will show the progress bar even if its hidden.
145
   *
146
   *     NProgress.done(true);
147
   */
148
149
  NProgress.done = function(force) {
150
    if (!force && !NProgress.status) return this;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
151
152
    return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
153
  };
154
155
  /**
156
   * Increments by a random amount.
157
   */
158
159
  NProgress.inc = function(amount) {
160
    var n = NProgress.status;
161
162
    if (!n) {
163
      return NProgress.start();
164
    } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
165
      if (typeof amount !== 'number') {
166
        amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);
167
      }
168
169
      n = clamp(n + amount, 0, 0.994);
170
      return NProgress.set(n);
171
    }
172
  };
173
174
  NProgress.trickle = function() {
175
    return NProgress.inc(Math.random() * Settings.trickleRate);
176
  };
177
178
  /**
179
   * Waits for all supplied jQuery promises and
180
   * increases the progress as the promises resolve.
181
   * 
182
   * @param $promise jQUery Promise
183
   */
184
  (function() {
185
    var initial = 0, current = 0;
186
    
187
    NProgress.promise = function($promise) {
188
      if (!$promise || $promise.state() == "resolved") {
189
        return this;
190
      }
191
      
192
      if (current == 0) {
193
        NProgress.start();
194
      }
195
      
196
      initial++;
197
      current++;
198
      
199
      $promise.always(function() {
200
        current--;
201
        if (current == 0) {
202
            initial = 0;
203
            NProgress.done();
204
        } else {
205
            NProgress.set((initial - current) / initial);
206
        }
207
      });
208
      
209
      return this;
210
    };
211
    
212
  })();
213
214
  /**
215
   * (Internal) renders the progress bar markup based on the `template`
216
   * setting.
217
   */
218
219
  NProgress.render = function(fromStart) {
220
    if (NProgress.isRendered()) return document.getElementById('nprogress');
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
221
222
    addClass(document.documentElement, 'nprogress-busy');
223
    
224
    var progress = document.createElement('div');
225
    progress.id = 'nprogress';
226
    progress.innerHTML = Settings.template;
227
228
    var bar      = progress.querySelector(Settings.barSelector),
229
        perc     = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
230
        parent   = document.querySelector(Settings.parent),
231
        spinner;
232
    
233
    css(bar, {
234
      transition: 'all 0 linear',
235
      transform: 'translate3d(' + perc + '%,0,0)'
236
    });
237
238
    if (!Settings.showSpinner) {
239
      spinner = progress.querySelector(Settings.spinnerSelector);
240
      spinner && removeElement(spinner);
241
    }
242
243
    if (parent != document.body) {
244
      addClass(parent, 'nprogress-custom-parent');
245
    }
246
247
    parent.appendChild(progress);
248
    return progress;
249
  };
250
251
  /**
252
   * Removes the element. Opposite of render().
253
   */
254
255
  NProgress.remove = function() {
256
    removeClass(document.documentElement, 'nprogress-busy');
257
    removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent')
258
    var progress = document.getElementById('nprogress');
259
    progress && removeElement(progress);
260
  };
261
262
  /**
263
   * Checks if the progress bar is rendered.
264
   */
265
266
  NProgress.isRendered = function() {
267
    return !!document.getElementById('nprogress');
268
  };
269
270
  /**
271
   * Determine which positioning CSS rule to use.
272
   */
273
274
  NProgress.getPositioningCSS = function() {
275
    // Sniff on document.body.style
276
    var bodyStyle = document.body.style;
277
278
    // Sniff prefixes
279
    var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
280
                       ('MozTransform' in bodyStyle) ? 'Moz' :
281
                       ('msTransform' in bodyStyle) ? 'ms' :
282
                       ('OTransform' in bodyStyle) ? 'O' : '';
283
284
    if (vendorPrefix + 'Perspective' in bodyStyle) {
285
      // Modern browsers with 3D support, e.g. Webkit, IE10
286
      return 'translate3d';
287
    } else if (vendorPrefix + 'Transform' in bodyStyle) {
288
      // Browsers without 3D support, e.g. IE9
289
      return 'translate';
290
    } else {
291
      // Browsers without translate() support, e.g. IE7-8
292
      return 'margin';
293
    }
294
  };
295
296
  /**
297
   * Helpers
298
   */
299
300
  function clamp(n, min, max) {
301
    if (n < min) return min;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
302
    if (n > max) return max;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
303
    return n;
304
  }
305
306
  /**
307
   * (Internal) converts a percentage (`0..1`) to a bar translateX
308
   * percentage (`-100%..0%`).
309
   */
310
311
  function toBarPerc(n) {
312
    return (-1 + n) * 100;
313
  }
314
315
316
  /**
317
   * (Internal) returns the correct CSS for changing the bar's
318
   * position given an n percentage, and speed and ease from Settings
319
   */
320
321
  function barPositionCSS(n, speed, ease) {
322
    var barCSS;
323
324
    if (Settings.positionUsing === 'translate3d') {
325
      barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
326
    } else if (Settings.positionUsing === 'translate') {
327
      barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
328
    } else {
329
      barCSS = { 'margin-left': toBarPerc(n)+'%' };
330
    }
331
332
    barCSS.transition = 'all '+speed+'ms '+ease;
333
334
    return barCSS;
335
  }
336
337
  /**
338
   * (Internal) Queues a function to be executed.
339
   */
340
341
  var queue = (function() {
342
    var pending = [];
343
    
344
    function next() {
345
      var fn = pending.shift();
346
      if (fn) {
347
        fn(next);
348
      }
349
    }
350
351
    return function(fn) {
352
      pending.push(fn);
353
      if (pending.length == 1) next();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
354
    };
355
  })();
356
357
  /**
358
   * (Internal) Applies css properties to an element, similar to the jQuery 
359
   * css method.
360
   *
361
   * While this helper does assist with vendor prefixed property names, it 
362
   * does not perform any manipulation of values prior to setting styles.
363
   */
364
365
  var css = (function() {
366
    var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
367
        cssProps    = {};
368
369
    function camelCase(string) {
370
      return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
371
        return letter.toUpperCase();
372
      });
373
    }
374
375
    function getVendorProp(name) {
376
      var style = document.body.style;
377
      if (name in style) return name;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
378
379
      var i = cssPrefixes.length,
380
          capName = name.charAt(0).toUpperCase() + name.slice(1),
381
          vendorName;
382
      while (i--) {
383
        vendorName = cssPrefixes[i] + capName;
384
        if (vendorName in style) return vendorName;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
385
      }
386
387
      return name;
388
    }
389
390
    function getStyleProp(name) {
391
      name = camelCase(name);
392
      return cssProps[name] || (cssProps[name] = getVendorProp(name));
393
    }
394
395
    function applyCss(element, prop, value) {
396
      prop = getStyleProp(prop);
397
      element.style[prop] = value;
398
    }
399
400
    return function(element, properties) {
401
      var args = arguments,
402
          prop, 
403
          value;
404
405
      if (args.length == 2) {
406
        for (prop in properties) {
407
          value = properties[prop];
408
          if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
409
        }
410
      } else {
411
        applyCss(element, args[1], args[2]);
412
      }
413
    }
414
  })();
415
416
  /**
417
   * (Internal) Determines if an element or space separated list of class names contains a class name.
418
   */
419
420
  function hasClass(element, name) {
421
    var list = typeof element == 'string' ? element : classList(element);
422
    return list.indexOf(' ' + name + ' ') >= 0;
423
  }
424
425
  /**
426
   * (Internal) Adds a class to an element.
427
   */
428
429
  function addClass(element, name) {
430
    var oldList = classList(element),
431
        newList = oldList + name;
432
433
    if (hasClass(oldList, name)) return; 
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
434
435
    // Trim the opening space.
436
    element.className = newList.substring(1);
437
  }
438
439
  /**
440
   * (Internal) Removes a class from an element.
441
   */
442
443
  function removeClass(element, name) {
444
    var oldList = classList(element),
445
        newList;
446
447
    if (!hasClass(element, name)) return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
448
449
    // Replace the class name.
450
    newList = oldList.replace(' ' + name + ' ', ' ');
451
452
    // Trim the opening and closing spaces.
453
    element.className = newList.substring(1, newList.length - 1);
454
  }
455
456
  /**
457
   * (Internal) Gets a space separated list of the class names on the element. 
458
   * The list is wrapped with a single space on each end to facilitate finding 
459
   * matches within the list.
460
   */
461
462
  function classList(element) {
463
    return (' ' + (element.className || '') + ' ').replace(/\s+/gi, ' ');
464
  }
465
466
  /**
467
   * (Internal) Removes an element from the DOM.
468
   */
469
470
  function removeElement(element) {
471
    element && element.parentNode && element.parentNode.removeChild(element);
472
  }
473
474
  return NProgress;
475
});
476
477