|
20 | 20 | let dedupeId = 0;
|
21 | 21 |
|
22 | 22 | /**
|
23 |
| - * Given a mixin producing function, memoize applications of mixin to base |
24 |
| - * @private |
25 |
| - * @param {Function} mixin Mixin for which to create a caching mixin. |
26 |
| - * @return {Function} Returns a mixin which when applied multiple times to the |
27 |
| - * same base will always return the same extended class. |
| 23 | + * @constructor |
| 24 | + * @extends {Function} |
28 | 25 | */
|
29 |
| - function cachingMixin(mixin) { |
30 |
| - return function(base) { |
31 |
| - if (!mixin.__mixinApplications) { |
32 |
| - mixin.__mixinApplications = new WeakMap(); |
33 |
| - } |
34 |
| - let map = mixin.__mixinApplications; |
35 |
| - let application = map.get(base); |
36 |
| - if (!application) { |
37 |
| - application = mixin(base); |
38 |
| - map.set(base, application); |
39 |
| - } |
40 |
| - return application; |
41 |
| - }; |
42 |
| - } |
| 26 | + function MixinFunction(){} |
| 27 | + /** @type {(WeakMap | undefined)} */ |
| 28 | + MixinFunction.prototype.__mixinApplications; |
| 29 | + /** @type {(Object | undefined)} */ |
| 30 | + MixinFunction.prototype.__mixinSet; |
43 | 31 |
|
44 | 32 | /**
|
45 | 33 | * Wraps an ES6 class expression mixin such that the mixin is only applied
|
|
53 | 41 | * mixin applications to base
|
54 | 42 | */
|
55 | 43 | Polymer.dedupingMixin = function(mixin) {
|
56 |
| - mixin = cachingMixin(mixin); |
| 44 | + let mixinApplications = /** @type {!MixinFunction} */(mixin).__mixinApplications; |
| 45 | + if (!mixinApplications) { |
| 46 | + mixinApplications = new WeakMap(); |
| 47 | + /** @type {!MixinFunction} */(mixin).__mixinApplications = mixinApplications; |
| 48 | + } |
57 | 49 | // maintain a unique id for each mixin
|
58 |
| - mixin.__dedupeId = ++dedupeId; |
59 |
| - return function(base) { |
60 |
| - let baseSet = base.__mixinSet; |
61 |
| - if (baseSet && baseSet[mixin.__dedupeId]) { |
| 50 | + let mixinDedupeId = dedupeId++; |
| 51 | + function dedupingMixin(base) { |
| 52 | + let baseSet = /** @type {!MixinFunction} */(base).__mixinSet; |
| 53 | + if (baseSet && baseSet[mixinDedupeId]) { |
62 | 54 | return base;
|
63 | 55 | }
|
64 |
| - let extended = mixin(base); |
| 56 | + let map = mixinApplications; |
| 57 | + let extended = map.get(base); |
| 58 | + if (!extended) { |
| 59 | + extended = /** @type {!Function} */(mixin)(base); |
| 60 | + map.set(base, extended); |
| 61 | + } |
65 | 62 | // copy inherited mixin set from the extended class, or the base class
|
66 | 63 | // NOTE: we avoid use of Set here because some browser (IE11)
|
67 | 64 | // cannot extend a base Set via the constructor.
|
68 |
| - extended.__mixinSet = |
69 |
| - Object.create(extended.__mixinSet || baseSet || null); |
70 |
| - extended.__mixinSet[mixin.__dedupeId] = true; |
| 65 | + let mixinSet = Object.create(/** @type {!MixinFunction} */(extended).__mixinSet || baseSet || null); |
| 66 | + mixinSet[mixinDedupeId] = true; |
| 67 | + /** @type {!MixinFunction} */(extended).__mixinSet = mixinSet; |
71 | 68 | return extended;
|
72 | 69 | }
|
| 70 | + |
| 71 | + return /** @type {T} */(dedupingMixin); |
73 | 72 | };
|
74 | 73 |
|
75 | 74 | })();
|
|
0 commit comments