79 lines
2.5 KiB
HTML
79 lines
2.5 KiB
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
|
||
|
|
-->
|
||
|
|
|
||
|
|
<link rel="import" href="boot.html">
|
||
|
|
|
||
|
|
<script>
|
||
|
|
|
||
|
|
(function() {
|
||
|
|
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
// unique global id for deduping mixins.
|
||
|
|
let dedupeId = 0;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @constructor
|
||
|
|
* @extends {Function}
|
||
|
|
*/
|
||
|
|
function MixinFunction(){}
|
||
|
|
/** @type {(WeakMap | undefined)} */
|
||
|
|
MixinFunction.prototype.__mixinApplications;
|
||
|
|
/** @type {(Object | undefined)} */
|
||
|
|
MixinFunction.prototype.__mixinSet;
|
||
|
|
|
||
|
|
/* eslint-disable valid-jsdoc */
|
||
|
|
/**
|
||
|
|
* Wraps an ES6 class expression mixin such that the mixin is only applied
|
||
|
|
* if it has not already been applied its base argument. Also memoizes mixin
|
||
|
|
* applications.
|
||
|
|
*
|
||
|
|
* @memberof Polymer
|
||
|
|
* @template T
|
||
|
|
* @param {T} mixin ES6 class expression mixin to wrap
|
||
|
|
* @return {T}
|
||
|
|
* @suppress {invalidCasts}
|
||
|
|
*/
|
||
|
|
Polymer.dedupingMixin = function(mixin) {
|
||
|
|
let mixinApplications = /** @type {!MixinFunction} */(mixin).__mixinApplications;
|
||
|
|
if (!mixinApplications) {
|
||
|
|
mixinApplications = new WeakMap();
|
||
|
|
/** @type {!MixinFunction} */(mixin).__mixinApplications = mixinApplications;
|
||
|
|
}
|
||
|
|
// maintain a unique id for each mixin
|
||
|
|
let mixinDedupeId = dedupeId++;
|
||
|
|
function dedupingMixin(base) {
|
||
|
|
let baseSet = /** @type {!MixinFunction} */(base).__mixinSet;
|
||
|
|
if (baseSet && baseSet[mixinDedupeId]) {
|
||
|
|
return base;
|
||
|
|
}
|
||
|
|
let map = mixinApplications;
|
||
|
|
let extended = map.get(base);
|
||
|
|
if (!extended) {
|
||
|
|
extended = /** @type {!Function} */(mixin)(base);
|
||
|
|
map.set(base, extended);
|
||
|
|
}
|
||
|
|
// copy inherited mixin set from the extended class, or the base class
|
||
|
|
// NOTE: we avoid use of Set here because some browser (IE11)
|
||
|
|
// cannot extend a base Set via the constructor.
|
||
|
|
let mixinSet = Object.create(/** @type {!MixinFunction} */(extended).__mixinSet || baseSet || null);
|
||
|
|
mixinSet[mixinDedupeId] = true;
|
||
|
|
/** @type {!MixinFunction} */(extended).__mixinSet = mixinSet;
|
||
|
|
return extended;
|
||
|
|
}
|
||
|
|
|
||
|
|
return /** @type {T} */ (dedupingMixin);
|
||
|
|
};
|
||
|
|
/* eslint-enable valid-jsdoc */
|
||
|
|
|
||
|
|
})();
|
||
|
|
|
||
|
|
</script>
|