vue 2.6.4 → 2.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,6 +40,11 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu
40
40
  <table>
41
41
  <tbody>
42
42
  <tr>
43
+ <td align="center" valign="middle">
44
+ <a href="https://moduscreate.com/?utm_source=Vue&utm_medium=Partnership&utm_campaign=VueShip" target="_blank">
45
+ <img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/modus.png">
46
+ </a>
47
+ </td>
43
48
  <td align="center" valign="middle">
44
49
  <a href="https://www.bitsrc.io/?utm_source=vue&utm_medium=vue&utm_campaign=vue&utm_term=vue&utm_content=vue" target="_blank">
45
50
  <img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/bit.png">
@@ -55,13 +60,13 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu
55
60
  <img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/vueschool.png">
56
61
  </a>
57
62
  </td>
63
+ </tr><tr></tr>
64
+ <tr>
58
65
  <td align="center" valign="middle">
59
66
  <a href="https://vehikl.com/" target="_blank">
60
67
  <img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/vehikl.png">
61
68
  </a>
62
69
  </td>
63
- </tr><tr></tr>
64
- <tr>
65
70
  <td align="center" valign="middle">
66
71
  <a href="https://www.nativescript.org/vue?utm_source=vue-js-org&utm_medium=website&utm_campaign=nativescript-awareness" target="_blank">
67
72
  <img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/nativescript.png">
@@ -163,7 +168,7 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu
163
168
  </a>
164
169
  </td>
165
170
  <td align="center" valign="middle">
166
- <a href="https://syncfusion.com/products/vue" target="_blank">
171
+ <a href="http://www.syncfusion.com/?utm_source=vuejs&utm_medium=list&utm_campaign=vuejsjslistcy19" target="_blank">
167
172
  <img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/syncfusion.png">
168
173
  </a>
169
174
  </td>
@@ -214,6 +219,11 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu
214
219
  <img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/bacancy_technology.png">
215
220
  </a>
216
221
  </td>
222
+ <td align="center" valign="middle">
223
+ <a href="https://passionatepeople.io/" target="_blank">
224
+ <img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/passionate_people.png">
225
+ </a>
226
+ </td>
217
227
  </tr><tr></tr>
218
228
  </tbody>
219
229
  </table>
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vue.js v2.6.4
2
+ * Vue.js v2.6.8
3
3
  * (c) 2014-2019 Evan You
4
4
  * Released under the MIT License.
5
5
  */
@@ -477,7 +477,7 @@ var config = ({
477
477
  * using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname
478
478
  * skipping \u10000-\uEFFFF due to it freezing up PhantomJS
479
479
  */
480
- var unicodeLetters = 'a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD';
480
+ var unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/;
481
481
 
482
482
  /**
483
483
  * Check if a string starts with $ or _
@@ -502,7 +502,7 @@ function def (obj, key, val, enumerable) {
502
502
  /**
503
503
  * Parse simple path.
504
504
  */
505
- var bailRE = new RegExp(("[^" + unicodeLetters + ".$_\\d]"));
505
+ var bailRE = new RegExp(("[^" + (unicodeRegExp.source) + ".$_\\d]"));
506
506
  function parsePath (path) {
507
507
  if (bailRE.test(path)) {
508
508
  return
@@ -1406,7 +1406,7 @@ function checkComponents (options) {
1406
1406
  }
1407
1407
 
1408
1408
  function validateComponentName (name) {
1409
- if (!new RegExp(("^[a-zA-Z][\\-\\.0-9_" + unicodeLetters + "]*$")).test(name)) {
1409
+ if (!new RegExp(("^[a-zA-Z][\\-\\.0-9_" + (unicodeRegExp.source) + "]*$")).test(name)) {
1410
1410
  warn(
1411
1411
  'Invalid component name: "' + name + '". Component names ' +
1412
1412
  'should conform to valid custom element name in html5 specification.'
@@ -1821,23 +1821,30 @@ function isBoolean () {
1821
1821
  /* */
1822
1822
 
1823
1823
  function handleError (err, vm, info) {
1824
- if (vm) {
1825
- var cur = vm;
1826
- while ((cur = cur.$parent)) {
1827
- var hooks = cur.$options.errorCaptured;
1828
- if (hooks) {
1829
- for (var i = 0; i < hooks.length; i++) {
1830
- try {
1831
- var capture = hooks[i].call(cur, err, vm, info) === false;
1832
- if (capture) { return }
1833
- } catch (e) {
1834
- globalHandleError(e, cur, 'errorCaptured hook');
1824
+ // Deactivate deps tracking while processing error handler to avoid possible infinite rendering.
1825
+ // See: https://github.com/vuejs/vuex/issues/1505
1826
+ pushTarget();
1827
+ try {
1828
+ if (vm) {
1829
+ var cur = vm;
1830
+ while ((cur = cur.$parent)) {
1831
+ var hooks = cur.$options.errorCaptured;
1832
+ if (hooks) {
1833
+ for (var i = 0; i < hooks.length; i++) {
1834
+ try {
1835
+ var capture = hooks[i].call(cur, err, vm, info) === false;
1836
+ if (capture) { return }
1837
+ } catch (e) {
1838
+ globalHandleError(e, cur, 'errorCaptured hook');
1839
+ }
1835
1840
  }
1836
1841
  }
1837
1842
  }
1838
1843
  }
1844
+ globalHandleError(err, vm, info);
1845
+ } finally {
1846
+ popTarget();
1839
1847
  }
1840
- globalHandleError(err, vm, info);
1841
1848
  }
1842
1849
 
1843
1850
  function invokeWithErrorHandling (
@@ -1851,7 +1858,9 @@ function invokeWithErrorHandling (
1851
1858
  try {
1852
1859
  res = args ? handler.apply(context, args) : handler.call(context);
1853
1860
  if (res && !res._isVue && isPromise(res)) {
1854
- res.catch(function (e) { return handleError(e, vm, info + " (Promise/async)"); });
1861
+ // issue #9511
1862
+ // reassign to res to avoid catch triggering multiple times when nested calls
1863
+ res = res.catch(function (e) { return handleError(e, vm, info + " (Promise/async)"); });
1855
1864
  }
1856
1865
  } catch (e) {
1857
1866
  handleError(e, vm, info);
@@ -2534,26 +2543,35 @@ function normalizeScopedSlots (
2534
2543
  prevSlots
2535
2544
  ) {
2536
2545
  var res;
2546
+ var isStable = slots ? !!slots.$stable : true;
2547
+ var key = slots && slots.$key;
2537
2548
  if (!slots) {
2538
2549
  res = {};
2539
2550
  } else if (slots._normalized) {
2540
2551
  // fast path 1: child component re-render only, parent did not change
2541
2552
  return slots._normalized
2542
- } else if (slots.$stable && prevSlots && prevSlots !== emptyObject) {
2543
- // fast path 2: stable scoped slots, only need to normalize once
2553
+ } else if (
2554
+ isStable &&
2555
+ prevSlots &&
2556
+ prevSlots !== emptyObject &&
2557
+ key === prevSlots.$key &&
2558
+ Object.keys(normalSlots).length === 0
2559
+ ) {
2560
+ // fast path 2: stable scoped slots w/ no normal slots to proxy,
2561
+ // only need to normalize once
2544
2562
  return prevSlots
2545
2563
  } else {
2546
2564
  res = {};
2547
- for (var key in slots) {
2548
- if (slots[key] && key[0] !== '$') {
2549
- res[key] = normalizeScopedSlot(normalSlots, key, slots[key]);
2565
+ for (var key$1 in slots) {
2566
+ if (slots[key$1] && key$1[0] !== '$') {
2567
+ res[key$1] = normalizeScopedSlot(normalSlots, key$1, slots[key$1]);
2550
2568
  }
2551
2569
  }
2552
2570
  }
2553
2571
  // expose normal slots on scopedSlots
2554
- for (var key$1 in normalSlots) {
2555
- if (!(key$1 in res)) {
2556
- res[key$1] = proxyNormalSlot(normalSlots, key$1);
2572
+ for (var key$2 in normalSlots) {
2573
+ if (!(key$2 in res)) {
2574
+ res[key$2] = proxyNormalSlot(normalSlots, key$2);
2557
2575
  }
2558
2576
  }
2559
2577
  // avoriaz seems to mock a non-extensible $scopedSlots object
@@ -2561,13 +2579,14 @@ function normalizeScopedSlots (
2561
2579
  if (slots && Object.isExtensible(slots)) {
2562
2580
  (slots)._normalized = res;
2563
2581
  }
2564
- def(res, '$stable', slots ? !!slots.$stable : true);
2582
+ def(res, '$stable', isStable);
2583
+ def(res, '$key', key);
2565
2584
  return res
2566
2585
  }
2567
2586
 
2568
2587
  function normalizeScopedSlot(normalSlots, key, fn) {
2569
- var normalized = function (scope) {
2570
- var res = fn(scope || {});
2588
+ var normalized = function () {
2589
+ var res = arguments.length ? fn.apply(null, arguments) : fn({});
2571
2590
  res = res && typeof res === 'object' && !Array.isArray(res)
2572
2591
  ? [res] // single vnode
2573
2592
  : normalizeChildren(res);
@@ -2856,14 +2875,16 @@ function bindObjectListeners (data, value) {
2856
2875
 
2857
2876
  function resolveScopedSlots (
2858
2877
  fns, // see flow/vnode
2878
+ res,
2879
+ // the following are added in 2.6
2859
2880
  hasDynamicKeys,
2860
- res
2881
+ contentHashKey
2861
2882
  ) {
2862
2883
  res = res || { $stable: !hasDynamicKeys };
2863
2884
  for (var i = 0; i < fns.length; i++) {
2864
2885
  var slot = fns[i];
2865
2886
  if (Array.isArray(slot)) {
2866
- resolveScopedSlots(slot, hasDynamicKeys, res);
2887
+ resolveScopedSlots(slot, res, hasDynamicKeys);
2867
2888
  } else if (slot) {
2868
2889
  // marker for reverse proxying v-slot without scope on this.$slots
2869
2890
  if (slot.proxy) {
@@ -2872,6 +2893,9 @@ function resolveScopedSlots (
2872
2893
  res[slot.key] = slot.fn;
2873
2894
  }
2874
2895
  }
2896
+ if (contentHashKey) {
2897
+ (res).$key = contentHashKey;
2898
+ }
2875
2899
  return res
2876
2900
  }
2877
2901
 
@@ -3586,17 +3610,21 @@ function resolveAsyncComponent (
3586
3610
  return factory.resolved
3587
3611
  }
3588
3612
 
3613
+ var owner = currentRenderingInstance;
3614
+ if (isDef(factory.owners) && factory.owners.indexOf(owner) === -1) {
3615
+ // already pending
3616
+ factory.owners.push(owner);
3617
+ }
3618
+
3589
3619
  if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
3590
3620
  return factory.loadingComp
3591
3621
  }
3592
3622
 
3593
- var owner = currentRenderingInstance;
3594
- if (isDef(factory.owners)) {
3595
- // already pending
3596
- factory.owners.push(owner);
3597
- } else {
3623
+ if (!isDef(factory.owners)) {
3598
3624
  var owners = factory.owners = [owner];
3599
- var sync = true;
3625
+ var sync = true
3626
+
3627
+ ;(owner).$on('hook:destroyed', function () { return remove(owners, owner); });
3600
3628
 
3601
3629
  var forceRender = function (renderCompleted) {
3602
3630
  for (var i = 0, l = owners.length; i < l; i++) {
@@ -4049,9 +4077,12 @@ function updateChildComponent (
4049
4077
  // check if there are dynamic scopedSlots (hand-written or compiled but with
4050
4078
  // dynamic slot names). Static scoped slots compiled from template has the
4051
4079
  // "$stable" marker.
4080
+ var newScopedSlots = parentVnode.data.scopedSlots;
4081
+ var oldScopedSlots = vm.$scopedSlots;
4052
4082
  var hasDynamicScopedSlot = !!(
4053
- (parentVnode.data.scopedSlots && !parentVnode.data.scopedSlots.$stable) ||
4054
- (vm.$scopedSlots !== emptyObject && !vm.$scopedSlots.$stable)
4083
+ (newScopedSlots && !newScopedSlots.$stable) ||
4084
+ (oldScopedSlots !== emptyObject && !oldScopedSlots.$stable) ||
4085
+ (newScopedSlots && vm.$scopedSlots.$key !== newScopedSlots.$key)
4055
4086
  );
4056
4087
 
4057
4088
  // Any static slot children from the parent may have changed during parent's
@@ -5373,7 +5404,7 @@ Object.defineProperty(Vue, 'FunctionalRenderContext', {
5373
5404
  value: FunctionalRenderContext
5374
5405
  });
5375
5406
 
5376
- Vue.version = '2.6.4';
5407
+ Vue.version = '2.6.8';
5377
5408
 
5378
5409
  /* */
5379
5410
 
@@ -7459,9 +7490,17 @@ function add$1 (
7459
7490
  var original = handler;
7460
7491
  handler = original._wrapper = function (e) {
7461
7492
  if (
7493
+ // no bubbling, should always fire.
7494
+ // this is just a safety net in case event.timeStamp is unreliable in
7495
+ // certain weird environments...
7496
+ e.target === e.currentTarget ||
7497
+ // event is fired after handler attachment
7462
7498
  e.timeStamp >= attachedTimestamp ||
7499
+ // #9462 bail for iOS 9 bug: event.timeStamp is 0 after history.pushState
7500
+ e.timeStamp === 0 ||
7463
7501
  // #9448 bail if event is fired in another document in a multi-page
7464
- // electron/nw.js app
7502
+ // electron/nw.js app, since event.timeStamp will be using a different
7503
+ // starting reference
7465
7504
  e.target.ownerDocument !== document
7466
7505
  ) {
7467
7506
  return original.apply(this, arguments)
@@ -7544,15 +7583,7 @@ function updateDOMProps (oldVnode, vnode) {
7544
7583
  }
7545
7584
  }
7546
7585
 
7547
- // skip the update if old and new VDOM state is the same.
7548
- // the only exception is `value` where the DOM value may be temporarily
7549
- // out of sync with VDOM state due to focus, composition and modifiers.
7550
- // This also covers #4521 by skipping the unnecesarry `checked` update.
7551
- if (key !== 'value' && cur === oldProps[key]) {
7552
- continue
7553
- }
7554
-
7555
- if (key === 'value') {
7586
+ if (key === 'value' && elm.tagName !== 'PROGRESS') {
7556
7587
  // store value as _value as well since
7557
7588
  // non-string values will be stringified
7558
7589
  elm._value = cur;
@@ -7572,8 +7603,18 @@ function updateDOMProps (oldVnode, vnode) {
7572
7603
  while (svg.firstChild) {
7573
7604
  elm.appendChild(svg.firstChild);
7574
7605
  }
7575
- } else {
7576
- elm[key] = cur;
7606
+ } else if (
7607
+ // skip the update if old and new VDOM state is the same.
7608
+ // `value` is handled separately because the DOM value may be temporarily
7609
+ // out of sync with VDOM state due to focus, composition and modifiers.
7610
+ // This #4521 by skipping the unnecesarry `checked` update.
7611
+ cur !== oldProps[key]
7612
+ ) {
7613
+ // some property updates can throw
7614
+ // e.g. `value` on <progress> w/ non-finite value
7615
+ try {
7616
+ elm[key] = cur;
7617
+ } catch (e) {}
7577
7618
  }
7578
7619
  }
7579
7620
  }
@@ -9165,7 +9206,7 @@ var isNonPhrasingTag = makeMap(
9165
9206
  // Regular Expressions for parsing tags and attributes
9166
9207
  var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9167
9208
  var dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9168
- var ncname = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + unicodeLetters + "]*";
9209
+ var ncname = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + (unicodeRegExp.source) + "]*";
9169
9210
  var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")";
9170
9211
  var startTagOpen = new RegExp(("^<" + qnameCapture));
9171
9212
  var startTagClose = /^\s*(\/?)>/;
@@ -9427,7 +9468,7 @@ function parseHTML (html, options) {
9427
9468
  ) {
9428
9469
  options.warn(
9429
9470
  ("tag <" + (stack[i].tag) + "> has no matching end tag."),
9430
- { start: stack[i].start }
9471
+ { start: stack[i].start, end: stack[i].end }
9431
9472
  );
9432
9473
  }
9433
9474
  if (options.end) {
@@ -9464,7 +9505,7 @@ var dynamicArgRE = /^\[.*\]$/;
9464
9505
 
9465
9506
  var argRE = /:(.*)$/;
9466
9507
  var bindRE = /^:|^\.|^v-bind:/;
9467
- var modifierRE = /\.[^.]+/g;
9508
+ var modifierRE = /\.[^.\]]+(?=[^\]]*$)/g;
9468
9509
 
9469
9510
  var slotRE = /^v-slot(:|$)|^#/;
9470
9511
 
@@ -9641,7 +9682,7 @@ function parse (
9641
9682
  shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
9642
9683
  shouldKeepComment: options.comments,
9643
9684
  outputSourceRange: options.outputSourceRange,
9644
- start: function start (tag, attrs, unary, start$1) {
9685
+ start: function start (tag, attrs, unary, start$1, end) {
9645
9686
  // check namespace.
9646
9687
  // inherit parent ns if there is one
9647
9688
  var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);
@@ -9660,6 +9701,7 @@ function parse (
9660
9701
  {
9661
9702
  if (options.outputSourceRange) {
9662
9703
  element.start = start$1;
9704
+ element.end = end;
9663
9705
  element.rawAttrsMap = element.attrsList.reduce(function (cumulated, attr) {
9664
9706
  cumulated[attr.name] = attr;
9665
9707
  return cumulated
@@ -10777,7 +10819,13 @@ function genHandler (handler) {
10777
10819
  }
10778
10820
 
10779
10821
  function genKeyFilter (keys) {
10780
- return ("if(('keyCode' in $event)&&" + (keys.map(genFilterCode).join('&&')) + ")return null;")
10822
+ return (
10823
+ // make sure the key filters only apply to KeyboardEvents
10824
+ // #9441: can't use 'keyCode' in $event because Chrome autofill fires fake
10825
+ // key events that do not have keyCode property...
10826
+ "if(!$event.type.indexOf('key')&&" +
10827
+ (keys.map(genFilterCode).join('&&')) + ")return null;"
10828
+ )
10781
10829
  }
10782
10830
 
10783
10831
  function genFilterCode (key) {
@@ -11138,26 +11186,68 @@ function genScopedSlots (
11138
11186
  // components with only scoped slots to skip forced updates from parent.
11139
11187
  // but in some cases we have to bail-out of this optimization
11140
11188
  // for example if the slot contains dynamic names, has v-if or v-for on them...
11141
- var needsForceUpdate = Object.keys(slots).some(function (key) {
11189
+ var needsForceUpdate = el.for || Object.keys(slots).some(function (key) {
11142
11190
  var slot = slots[key];
11143
- return slot.slotTargetDynamic || slot.if || slot.for
11191
+ return (
11192
+ slot.slotTargetDynamic ||
11193
+ slot.if ||
11194
+ slot.for ||
11195
+ containsSlotChild(slot) // is passing down slot from parent which may be dynamic
11196
+ )
11144
11197
  });
11145
- // OR when it is inside another scoped slot (the reactivity is disconnected)
11146
- // #9438
11198
+
11199
+ // #9534: if a component with scoped slots is inside a conditional branch,
11200
+ // it's possible for the same component to be reused but with different
11201
+ // compiled slot content. To avoid that, we generate a unique key based on
11202
+ // the generated code of all the slot contents.
11203
+ var needsKey = !!el.if;
11204
+
11205
+ // OR when it is inside another scoped slot or v-for (the reactivity may be
11206
+ // disconnected due to the intermediate scope variable)
11207
+ // #9438, #9506
11208
+ // TODO: this can be further optimized by properly analyzing in-scope bindings
11209
+ // and skip force updating ones that do not actually use scope variables.
11147
11210
  if (!needsForceUpdate) {
11148
11211
  var parent = el.parent;
11149
11212
  while (parent) {
11150
- if (parent.slotScope && parent.slotScope !== emptySlotScopeToken) {
11213
+ if (
11214
+ (parent.slotScope && parent.slotScope !== emptySlotScopeToken) ||
11215
+ parent.for
11216
+ ) {
11151
11217
  needsForceUpdate = true;
11152
11218
  break
11153
11219
  }
11220
+ if (parent.if) {
11221
+ needsKey = true;
11222
+ }
11154
11223
  parent = parent.parent;
11155
11224
  }
11156
11225
  }
11157
11226
 
11158
- return ("scopedSlots:_u([" + (Object.keys(slots).map(function (key) {
11159
- return genScopedSlot(slots[key], state)
11160
- }).join(',')) + "]" + (needsForceUpdate ? ",true" : "") + ")")
11227
+ var generatedSlots = Object.keys(slots)
11228
+ .map(function (key) { return genScopedSlot(slots[key], state); })
11229
+ .join(',');
11230
+
11231
+ return ("scopedSlots:_u([" + generatedSlots + "]" + (needsForceUpdate ? ",null,true" : "") + (!needsForceUpdate && needsKey ? (",null,false," + (hash(generatedSlots))) : "") + ")")
11232
+ }
11233
+
11234
+ function hash(str) {
11235
+ var hash = 5381;
11236
+ var i = str.length;
11237
+ while(i) {
11238
+ hash = (hash * 33) ^ str.charCodeAt(--i);
11239
+ }
11240
+ return hash >>> 0
11241
+ }
11242
+
11243
+ function containsSlotChild (el) {
11244
+ if (el.type === 1) {
11245
+ if (el.tag === 'slot') {
11246
+ return true
11247
+ }
11248
+ return el.children.some(containsSlotChild)
11249
+ }
11250
+ return false
11161
11251
  }
11162
11252
 
11163
11253
  function genScopedSlot (
@@ -11482,11 +11572,13 @@ function generateCodeFrame (
11482
11572
 
11483
11573
  function repeat$1 (str, n) {
11484
11574
  var result = '';
11485
- while (true) { // eslint-disable-line
11486
- if (n & 1) { result += str; }
11487
- n >>>= 1;
11488
- if (n <= 0) { break }
11489
- str += str;
11575
+ if (n > 0) {
11576
+ while (true) { // eslint-disable-line
11577
+ if (n & 1) { result += str; }
11578
+ n >>>= 1;
11579
+ if (n <= 0) { break }
11580
+ str += str;
11581
+ }
11490
11582
  }
11491
11583
  return result
11492
11584
  }