diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index 776cf1ab0bb6..e103f428cf24 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -375,6 +375,7 @@ export default function dom( if (sigil === '@') { if (name in shared) { if (options.dev && `${name}Dev` in shared) name = `${name}Dev`; + else if (options.immutable && `${name}Immutable` in shared) name = `${name}Immutable`; usedHelpers.add(name); } diff --git a/src/interfaces.ts b/src/interfaces.ts index 9773d330d394..82de8cd04737 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -52,6 +52,7 @@ export interface CompileOptions { cssOutputFilename?: string; dev?: boolean; + immutable?: boolean; shared?: boolean | string; cascade?: boolean; hydratable?: boolean; diff --git a/src/shared/index.js b/src/shared/index.js index ef160ebf0779..ec8706be6d1b 100644 --- a/src/shared/index.js +++ b/src/shared/index.js @@ -26,7 +26,25 @@ export function destroyDev(detach) { } export function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; +} + +export function differsImmutable(a, b) { + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b; } export function dispatchObservers(component, group, changed, newState, oldState) { @@ -165,6 +183,27 @@ export function _set(newState) { } } +export function _setImmutable(newState) { + var oldState = this._state, + changed = {}, + dirty = false; + + for (var key in newState) { + if (differsImmutable(newState[key], oldState[key])) changed[key] = dirty = true; + } + if (!dirty) return; + + this._state = assign({}, oldState, newState); + this._recompute(changed, this._state); + if (this._bind) this._bind(changed, this._state); + + if (this._fragment) { + dispatchObservers(this, this._observers.pre, changed, this._state, oldState); + this._fragment.p(changed, this._state); + dispatchObservers(this, this._observers.post, changed, this._state, oldState); + } +} + export function setDev(newState) { if (typeof newState !== 'object') { throw new Error( diff --git a/store.js b/store.js index f31c659080a3..853d36a52a9b 100644 --- a/store.js +++ b/store.js @@ -2,12 +2,13 @@ import { assign, blankObject, differs, + differsImmutable, dispatchObservers, get, observe } from './shared.js'; -function Store(state) { +function Store(state, options) { this._observers = { pre: blankObject(), post: blankObject() }; this._changeHandlers = []; this._dependents = []; @@ -16,6 +17,7 @@ function Store(state) { this._sortedComputedProperties = []; this._state = assign({}, state); + this._differs = options && options.immutable ? differsImmutable : differs; } assign(Store.prototype, { @@ -88,7 +90,7 @@ assign(Store.prototype, { if (dirty) { var newValue = fn.apply(null, values); - if (differs(newValue, value)) { + if (store._differs(newValue, value)) { value = newValue; changed[key] = true; state[key] = value; @@ -124,7 +126,7 @@ assign(Store.prototype, { for (var key in newState) { if (this._computed[key]) throw new Error("'" + key + "' is a read-only property"); - if (differs(newState[key], oldState[key])) changed[key] = dirty = true; + if (this._differs(newState[key], oldState[key])) changed[key] = dirty = true; } if (!dirty) return; diff --git a/test/js/samples/collapses-text-around-comments/expected-bundle.js b/test/js/samples/collapses-text-around-comments/expected-bundle.js index 59cd2de1256b..ffc75c872ce7 100644 --- a/test/js/samples/collapses-text-around-comments/expected-bundle.js +++ b/test/js/samples/collapses-text-around-comments/expected-bundle.js @@ -52,7 +52,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/component-static/expected-bundle.js b/test/js/samples/component-static/expected-bundle.js index 708ef5be95ac..970b8e139a71 100644 --- a/test/js/samples/component-static/expected-bundle.js +++ b/test/js/samples/component-static/expected-bundle.js @@ -28,7 +28,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/computed-collapsed-if/expected-bundle.js b/test/js/samples/computed-collapsed-if/expected-bundle.js index b39f95a77b71..e9285f3bc068 100644 --- a/test/js/samples/computed-collapsed-if/expected-bundle.js +++ b/test/js/samples/computed-collapsed-if/expected-bundle.js @@ -28,7 +28,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/css-media-query/expected-bundle.js b/test/js/samples/css-media-query/expected-bundle.js index 91662053a4f1..6ccc9200d57c 100644 --- a/test/js/samples/css-media-query/expected-bundle.js +++ b/test/js/samples/css-media-query/expected-bundle.js @@ -48,7 +48,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js b/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js index 03e5cef1e24b..4948afea4d55 100644 --- a/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js +++ b/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js @@ -40,7 +40,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/deconflict-globals/expected-bundle.js b/test/js/samples/deconflict-globals/expected-bundle.js index ba22542c4b49..6733b68767f3 100644 --- a/test/js/samples/deconflict-globals/expected-bundle.js +++ b/test/js/samples/deconflict-globals/expected-bundle.js @@ -28,7 +28,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/do-use-dataset/expected-bundle.js b/test/js/samples/do-use-dataset/expected-bundle.js index 2079e6607c98..442afd002e47 100644 --- a/test/js/samples/do-use-dataset/expected-bundle.js +++ b/test/js/samples/do-use-dataset/expected-bundle.js @@ -44,7 +44,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js b/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js index efcfcc8f30c6..3b5681f2ca06 100644 --- a/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js +++ b/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js @@ -48,7 +48,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/dont-use-dataset-in-svg/expected-bundle.js b/test/js/samples/dont-use-dataset-in-svg/expected-bundle.js index cf43bbd1300d..242ac5182875 100644 --- a/test/js/samples/dont-use-dataset-in-svg/expected-bundle.js +++ b/test/js/samples/dont-use-dataset-in-svg/expected-bundle.js @@ -48,7 +48,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/each-block-changed-check/expected-bundle.js b/test/js/samples/each-block-changed-check/expected-bundle.js index e35826e354d9..ca09f3774ff3 100644 --- a/test/js/samples/each-block-changed-check/expected-bundle.js +++ b/test/js/samples/each-block-changed-check/expected-bundle.js @@ -60,7 +60,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/event-handlers-custom/expected-bundle.js b/test/js/samples/event-handlers-custom/expected-bundle.js index 43db3035a350..f9e32a02565a 100644 --- a/test/js/samples/event-handlers-custom/expected-bundle.js +++ b/test/js/samples/event-handlers-custom/expected-bundle.js @@ -40,7 +40,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/head-no-whitespace/expected-bundle.js b/test/js/samples/head-no-whitespace/expected-bundle.js index 91f894bc301c..62aac217d514 100644 --- a/test/js/samples/head-no-whitespace/expected-bundle.js +++ b/test/js/samples/head-no-whitespace/expected-bundle.js @@ -40,7 +40,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/if-block-no-update/expected-bundle.js b/test/js/samples/if-block-no-update/expected-bundle.js index b309a25e9698..681edc072ec8 100644 --- a/test/js/samples/if-block-no-update/expected-bundle.js +++ b/test/js/samples/if-block-no-update/expected-bundle.js @@ -44,7 +44,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/if-block-simple/expected-bundle.js b/test/js/samples/if-block-simple/expected-bundle.js index 5084639f4b9b..9ce6331f4485 100644 --- a/test/js/samples/if-block-simple/expected-bundle.js +++ b/test/js/samples/if-block-simple/expected-bundle.js @@ -44,7 +44,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/inline-style-optimized-multiple/expected-bundle.js b/test/js/samples/inline-style-optimized-multiple/expected-bundle.js index 753d61db71c4..9077eea9d795 100644 --- a/test/js/samples/inline-style-optimized-multiple/expected-bundle.js +++ b/test/js/samples/inline-style-optimized-multiple/expected-bundle.js @@ -44,7 +44,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/inline-style-optimized-url/expected-bundle.js b/test/js/samples/inline-style-optimized-url/expected-bundle.js index cf360881b1bd..7277ff587a23 100644 --- a/test/js/samples/inline-style-optimized-url/expected-bundle.js +++ b/test/js/samples/inline-style-optimized-url/expected-bundle.js @@ -44,7 +44,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/inline-style-optimized/expected-bundle.js b/test/js/samples/inline-style-optimized/expected-bundle.js index 38024df4ff8c..9b3f41768f04 100644 --- a/test/js/samples/inline-style-optimized/expected-bundle.js +++ b/test/js/samples/inline-style-optimized/expected-bundle.js @@ -44,7 +44,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/inline-style-unoptimized/expected-bundle.js b/test/js/samples/inline-style-unoptimized/expected-bundle.js index 320c733a43dc..f1a5a53d7f29 100644 --- a/test/js/samples/inline-style-unoptimized/expected-bundle.js +++ b/test/js/samples/inline-style-unoptimized/expected-bundle.js @@ -44,7 +44,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/input-without-blowback-guard/expected-bundle.js b/test/js/samples/input-without-blowback-guard/expected-bundle.js index eacaca85a623..b32377763e01 100644 --- a/test/js/samples/input-without-blowback-guard/expected-bundle.js +++ b/test/js/samples/input-without-blowback-guard/expected-bundle.js @@ -48,7 +48,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/legacy-input-type/expected-bundle.js b/test/js/samples/legacy-input-type/expected-bundle.js index 7b730f08d921..1dbd32f6194a 100644 --- a/test/js/samples/legacy-input-type/expected-bundle.js +++ b/test/js/samples/legacy-input-type/expected-bundle.js @@ -46,7 +46,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/legacy-quote-class/expected-bundle.js b/test/js/samples/legacy-quote-class/expected-bundle.js index 499a82c46e4e..0b203fb4b65d 100644 --- a/test/js/samples/legacy-quote-class/expected-bundle.js +++ b/test/js/samples/legacy-quote-class/expected-bundle.js @@ -63,7 +63,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/media-bindings/expected-bundle.js b/test/js/samples/media-bindings/expected-bundle.js index bbd56d81237b..ec971167be53 100644 --- a/test/js/samples/media-bindings/expected-bundle.js +++ b/test/js/samples/media-bindings/expected-bundle.js @@ -56,7 +56,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/non-imported-component/expected-bundle.js b/test/js/samples/non-imported-component/expected-bundle.js index f8e0722db702..46de1d757ed6 100644 --- a/test/js/samples/non-imported-component/expected-bundle.js +++ b/test/js/samples/non-imported-component/expected-bundle.js @@ -42,7 +42,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js index e53dd0de5e91..b65e0bfc2a47 100644 --- a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js +++ b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js @@ -28,7 +28,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/setup-method/expected-bundle.js b/test/js/samples/setup-method/expected-bundle.js index 58ee3a67a03c..80bb84769218 100644 --- a/test/js/samples/setup-method/expected-bundle.js +++ b/test/js/samples/setup-method/expected-bundle.js @@ -28,7 +28,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/svg-title/expected-bundle.js b/test/js/samples/svg-title/expected-bundle.js index 12f06bcf9226..1ee4d64a4841 100644 --- a/test/js/samples/svg-title/expected-bundle.js +++ b/test/js/samples/svg-title/expected-bundle.js @@ -48,7 +48,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/title/expected-bundle.js b/test/js/samples/title/expected-bundle.js index 6eb3471b5b2e..454a1fad0e23 100644 --- a/test/js/samples/title/expected-bundle.js +++ b/test/js/samples/title/expected-bundle.js @@ -28,7 +28,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/use-elements-as-anchors/expected-bundle.js b/test/js/samples/use-elements-as-anchors/expected-bundle.js index e2ee1e61fba2..9ac57fe2156f 100644 --- a/test/js/samples/use-elements-as-anchors/expected-bundle.js +++ b/test/js/samples/use-elements-as-anchors/expected-bundle.js @@ -52,7 +52,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) { diff --git a/test/js/samples/window-binding-scroll/expected-bundle.js b/test/js/samples/window-binding-scroll/expected-bundle.js index a8a932c8b7cf..457f6d55ea37 100644 --- a/test/js/samples/window-binding-scroll/expected-bundle.js +++ b/test/js/samples/window-binding-scroll/expected-bundle.js @@ -48,7 +48,14 @@ function destroy(detach) { } function differs(a, b) { - return a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + if (a == null || b == null) return a !== b; + if (a.constructor !== b.constructor) return true; + if (a.valueOf && b.valueOf) { + a = a.valueOf(); + b = b.valueOf(); + } + if (typeof a === 'number' && isNaN(a) && isNaN(b)) return false; + return a !== b || typeof a === 'object' || typeof a === 'function'; } function dispatchObservers(component, group, changed, newState, oldState) {