-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #4909. Elements using this mixin will not "enable" themselves when they have a `disable-upgrade` attribute. This mirrors a feature of Polymer 1.x but is now opt-in.
- Loading branch information
Steven Orvell
committed
Dec 15, 2017
1 parent
84abed1
commit 62ce314
Showing
4 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
<!-- | ||
@license | ||
Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | ||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | ||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | ||
Code distributed by Google as part of the polymer project is also | ||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | ||
--> | ||
<script> | ||
(function() { | ||
|
||
const DISABLED_ATTR = 'disable-upgrade'; | ||
|
||
/** | ||
* Element class mixin that allows the element to boot up in a non-enabled | ||
* state when the `disable-upgrade` attribute is present. This mixin is | ||
* designed to be used with element classes like Polymer.Element that perform | ||
* initial startup work when they are first connected. When the | ||
* `disable-upgrade` attribute is removed, if the element is connected, it | ||
* boots up and "enables" as it otherwise would; if it is not connected, the | ||
* element boots up when it is next connected. | ||
* | ||
* Using `disable-upgrade` with Polymer.Element prevents any data propagation | ||
* to the element, any element DOM from stamping, or any work done in | ||
* connected/disconnctedCallback from occuring, but it does not prevent work | ||
* done in the element constructor. | ||
* | ||
* Note, this mixin must be applied on top of any element class that | ||
* itself implements a `connectedCallback` so that it can control the work | ||
* done in `connectedCallback`. For example, | ||
* | ||
* MyClass = Polymer.DisableUpgradeMixin(class extends BaseClass {...}); | ||
* | ||
* @mixinFunction | ||
* @polymer | ||
* @memberof Polymer | ||
*/ | ||
Polymer.DisableUpgradeMixin = Polymer.dedupingMixin((base) => { | ||
|
||
return class DisableUpgradeClass extends base { | ||
|
||
static get observedAttributes() { | ||
return super.observedAttributes.concat(DISABLED_ATTR); | ||
} | ||
|
||
attributeChangedCallback(name, old, value) { | ||
if (name == DISABLED_ATTR) { | ||
if (!this.__dataEnabled && value == null && this.isConnected) { | ||
super.connectedCallback(); | ||
} | ||
} else { | ||
super.attributeChangedCallback(name, old, value); | ||
} | ||
} | ||
|
||
__shouldEnable() { | ||
return this.__dataEnabled || !this.hasAttribute(DISABLED_ATTR); | ||
} | ||
|
||
// prevent user code in connected from running | ||
connectedCallback() { | ||
if (this.__shouldEnable()) { | ||
super.connectedCallback(); | ||
} | ||
} | ||
|
||
// prevent element from turning on properties | ||
_enableProperties() { | ||
if (this.__shouldEnable()) { | ||
super._enableProperties(); | ||
} | ||
} | ||
|
||
// only go if "enabled" | ||
disconnectedCallback() { | ||
if (this.__dataEnabled) { | ||
super.disconnectedCallback(); | ||
} | ||
} | ||
|
||
} | ||
}); | ||
|
||
})(); | ||
|
||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<link rel="import" href="../../polymer.html"> | ||
<link rel="import" href="../../lib/mixins/disable-upgrade-mixin.html"> | ||
</head> | ||
<body> | ||
<script> | ||
(function() { | ||
const ogDefine = window.customElements.ogDefine = window.customElements.define; | ||
window.customElements.defineWithDisabled = function(name, constructor) { | ||
return ogDefine.call(customElements, name, | ||
Polymer.DisableUpgradeMixin(constructor)); | ||
} | ||
window.customElements.define = window.customElements.defineWithDisabled; | ||
})(); | ||
|
||
</script> | ||
|
||
<dom-module id="x-disabled"> | ||
|
||
<template> | ||
<style> | ||
:host { | ||
display: block; | ||
} | ||
|
||
h2 { | ||
letter-spacing: 1em; | ||
} | ||
</style> | ||
<h2>[[prop]]</h2> | ||
</template> | ||
|
||
<script> | ||
class Disabled extends Polymer.Element { | ||
static get is() { return 'x-disabled'; } | ||
static get properties() { | ||
return { | ||
prop: { | ||
type: String | ||
} | ||
} | ||
} | ||
constructor() { | ||
super(); | ||
this.prop = 'enabled!'; | ||
} | ||
}; | ||
customElements.define(Disabled.is, Disabled); | ||
|
||
</script> | ||
|
||
</dom-module> | ||
|
||
<dom-module id="my-element"> | ||
|
||
<template> | ||
<style> | ||
:host { | ||
display: block; | ||
} | ||
|
||
button { | ||
display: block; | ||
} | ||
</style> | ||
<h3>x-disabled without disable-upgrade</h3> | ||
<x-disabled>Disabled</x-disabled> | ||
<h3>x-disabled with disable-upgrade</h3> | ||
<x-disabled id="disabled" disable-upgrade>Disabled</x-disabled> | ||
<h3>x-disabled with disable-upgrade</h3> | ||
<x-disabled disable-upgrade$="[[upgradeDisabled]]">Disabled</x-disabled> | ||
<button on-click="_enable">Enable</button> | ||
</template> | ||
|
||
<script> | ||
|
||
|
||
class MyElement extends Polymer.Element { | ||
static get is() { return 'my-element'; } | ||
static get properties() { | ||
return { | ||
upgradeDisabled: {value: true} | ||
} | ||
} | ||
_enable() { | ||
this.$.disabled.removeAttribute('disable-upgrade'); | ||
this.upgradeDisabled = false; | ||
} | ||
} | ||
customElements.define(MyElement.is, MyElement); | ||
|
||
</script> | ||
|
||
</dom-module> | ||
|
||
<my-element></my-element> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<!doctype html> | ||
<!-- | ||
@license | ||
Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | ||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | ||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | ||
Code distributed by Google as part of the polymer project is also | ||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | ||
--> | ||
<html dir="rtl"> | ||
<head> | ||
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script> | ||
<script src="../../../web-component-tester/browser.js"></script> | ||
<link rel="import" href="../../polymer.html"> | ||
<link rel="import" href="../../lib/mixins/disable-upgrade-mixin.html"> | ||
</head> | ||
<body> | ||
|
||
<dom-module id="x-disabled"> | ||
<template> | ||
<style> | ||
:host { | ||
display: block; | ||
} | ||
|
||
h2 { | ||
letter-spacing: 1em; | ||
} | ||
</style> | ||
<h2 id="element">[[prop]]</h2> | ||
</template> | ||
|
||
<script> | ||
const Disabled = Polymer.DisableUpgradeMixin(class extends Polymer.Element { | ||
static get is() { return 'x-disabled'; } | ||
static get properties() { | ||
return { | ||
prop: { | ||
type: String | ||
} | ||
} | ||
} | ||
constructor() { | ||
super(); | ||
this.prop = 'enabled!'; | ||
} | ||
|
||
ready() { | ||
super.ready(); | ||
this.enabled = true; | ||
} | ||
}); | ||
customElements.define(Disabled.is, Disabled); | ||
|
||
</script> | ||
|
||
</dom-module> | ||
|
||
<dom-module id="my-element"> | ||
|
||
<template> | ||
<x-disabled id="enabledEl">Disabled</x-disabled> | ||
<x-disabled id="disabledEl" disable-upgrade>Disabled</x-disabled> | ||
<x-disabled id="disabledBoundEl" disable-upgrade$="[[upgradeDisabled]]">Disabled</x-disabled> | ||
</template> | ||
|
||
<script> | ||
class MyElement extends Polymer.Element { | ||
static get is() { return 'my-element'; } | ||
static get properties() { | ||
return { | ||
upgradeDisabled: {value: true} | ||
} | ||
} | ||
enable() { | ||
this.$.disabledEl.removeAttribute('disable-upgrade'); | ||
this.upgradeDisabled = false; | ||
} | ||
} | ||
customElements.define(MyElement.is, MyElement); | ||
|
||
</script> | ||
|
||
</dom-module> | ||
|
||
<script> | ||
suite('disable-upgrade', function() { | ||
let el; | ||
|
||
setup(() => { | ||
el = document.createElement('my-element'); | ||
document.body.appendChild(el); | ||
}); | ||
teardown(function() { | ||
document.body.removeChild(el); | ||
}); | ||
|
||
test('elements upgrade as expected with and without `disable-upgrade`', function() { | ||
assert.ok(el.$.enabledEl.enabled); | ||
assert.ok(el.$.enabledEl.$.element); | ||
assert.equal(el.$.enabledEl.$.element.textContent, 'enabled!'); | ||
assert.notOk(el.$.disabledEl.enabled); | ||
assert.notOk(el.$.disabledEl.$); | ||
assert.notOk(el.$.disabledBoundEl.enabled); | ||
assert.notOk(el.$.disabledBoundEl.$); | ||
}); | ||
|
||
test('elements upgrade when `disable-upgrade` removed', function() { | ||
assert.notOk(el.$.disabledEl.enabled); | ||
assert.notOk(el.$.disabledEl.$); | ||
assert.notOk(el.$.disabledBoundEl.enabled); | ||
assert.notOk(el.$.disabledBoundEl.$); | ||
el.enable(); | ||
assert.ok(el.$.disabledEl.enabled); | ||
assert.ok(el.$.disabledEl.$.element); | ||
assert.equal(el.$.disabledEl.$.element.textContent, 'enabled!'); | ||
assert.ok(el.$.disabledBoundEl.enabled); | ||
assert.ok(el.$.disabledBoundEl.$.element); | ||
assert.equal(el.$.disabledBoundEl.$.element.textContent, 'enabled!'); | ||
}); | ||
|
||
|
||
}); | ||
</script> | ||
</body> | ||
</html> |