administrate-bootstrap-theme 0.1.0 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -11
  3. data/Rakefile +10 -14
  4. data/app/assets/config/administrate-bootstrap-theme_manifest.js +1 -0
  5. data/app/assets/javascripts/administrate-bootstrap-theme/theme.js +2 -0
  6. data/app/assets/stylesheets/administrate-bootstrap-theme/_base.scss +17 -1
  7. data/app/assets/stylesheets/administrate-bootstrap-theme/components/_content_body.scss +17 -3
  8. data/app/assets/stylesheets/administrate-bootstrap-theme/components/_form.scss +52 -16
  9. data/app/assets/stylesheets/administrate-bootstrap-theme/theme.scss +12 -0
  10. data/lib/administrate-bootstrap-theme/engine.rb +2 -0
  11. data/lib/administrate-bootstrap-theme/version.rb +1 -1
  12. data/node_modules/bootstrap/js/src/alert.js +141 -0
  13. data/node_modules/bootstrap/js/src/base-component.js +46 -0
  14. data/node_modules/bootstrap/js/src/button.js +95 -0
  15. data/node_modules/bootstrap/js/src/carousel.js +624 -0
  16. data/node_modules/bootstrap/js/src/collapse.js +410 -0
  17. data/node_modules/bootstrap/js/src/dom/data.js +57 -0
  18. data/node_modules/bootstrap/js/src/dom/event-handler.js +331 -0
  19. data/node_modules/bootstrap/js/src/dom/manipulator.js +80 -0
  20. data/node_modules/bootstrap/js/src/dom/selector-engine.js +75 -0
  21. data/node_modules/bootstrap/js/src/dropdown.js +543 -0
  22. data/node_modules/bootstrap/js/src/modal.js +582 -0
  23. data/node_modules/bootstrap/js/src/offcanvas.js +279 -0
  24. data/node_modules/bootstrap/js/src/popover.js +171 -0
  25. data/node_modules/bootstrap/js/src/scrollspy.js +319 -0
  26. data/node_modules/bootstrap/js/src/tab.js +220 -0
  27. data/node_modules/bootstrap/js/src/toast.js +219 -0
  28. data/node_modules/bootstrap/js/src/tooltip.js +802 -0
  29. data/node_modules/bootstrap/js/src/util/index.js +253 -0
  30. data/node_modules/bootstrap/js/src/util/sanitizer.js +127 -0
  31. data/node_modules/bootstrap/js/src/util/scrollbar.js +70 -0
  32. data/node_modules/bootstrap/scss/_accordion.scss +116 -0
  33. data/node_modules/bootstrap/scss/_alert.scss +57 -0
  34. data/node_modules/bootstrap/scss/_badge.scss +29 -0
  35. data/node_modules/bootstrap/scss/_breadcrumb.scss +28 -0
  36. data/node_modules/bootstrap/scss/_button-group.scss +139 -0
  37. data/node_modules/bootstrap/scss/_buttons.scss +111 -0
  38. data/node_modules/bootstrap/scss/_card.scss +215 -0
  39. data/node_modules/bootstrap/scss/_carousel.scss +229 -0
  40. data/node_modules/bootstrap/scss/_close.scss +40 -0
  41. data/node_modules/bootstrap/scss/_containers.scss +41 -0
  42. data/node_modules/bootstrap/scss/_dropdown.scss +246 -0
  43. data/node_modules/bootstrap/scss/_forms.scss +9 -0
  44. data/node_modules/bootstrap/scss/_functions.scss +205 -0
  45. data/node_modules/bootstrap/scss/_grid.scss +22 -0
  46. data/node_modules/bootstrap/scss/_helpers.scss +7 -0
  47. data/node_modules/bootstrap/scss/_images.scss +42 -0
  48. data/node_modules/bootstrap/scss/_list-group.scss +174 -0
  49. data/node_modules/bootstrap/scss/_mixins.scss +41 -0
  50. data/node_modules/bootstrap/scss/_modal.scss +237 -0
  51. data/node_modules/bootstrap/scss/_nav.scss +139 -0
  52. data/node_modules/bootstrap/scss/_navbar.scss +306 -0
  53. data/node_modules/bootstrap/scss/_offcanvas.scss +77 -0
  54. data/node_modules/bootstrap/scss/_pagination.scss +64 -0
  55. data/node_modules/bootstrap/scss/_popover.scss +158 -0
  56. data/node_modules/bootstrap/scss/_progress.scss +48 -0
  57. data/node_modules/bootstrap/scss/_reboot.scss +621 -0
  58. data/node_modules/bootstrap/scss/_root.scss +16 -0
  59. data/node_modules/bootstrap/scss/_spinners.scss +69 -0
  60. data/node_modules/bootstrap/scss/_tables.scss +150 -0
  61. data/node_modules/bootstrap/scss/_toasts.scss +51 -0
  62. data/node_modules/bootstrap/scss/_tooltip.scss +115 -0
  63. data/node_modules/bootstrap/scss/_transitions.scss +21 -0
  64. data/node_modules/bootstrap/scss/_type.scss +104 -0
  65. data/node_modules/bootstrap/scss/_utilities.scss +594 -0
  66. data/node_modules/bootstrap/scss/_variables.scss +1464 -0
  67. data/node_modules/bootstrap/scss/bootstrap-grid.scss +65 -0
  68. data/node_modules/bootstrap/scss/bootstrap-reboot.scss +15 -0
  69. data/node_modules/bootstrap/scss/bootstrap-utilities.scss +18 -0
  70. data/node_modules/bootstrap/scss/bootstrap.scss +52 -0
  71. data/node_modules/bootstrap/scss/forms/_floating-labels.scss +61 -0
  72. data/node_modules/bootstrap/scss/forms/_form-check.scss +152 -0
  73. data/node_modules/bootstrap/scss/forms/_form-control.scss +219 -0
  74. data/node_modules/bootstrap/scss/forms/_form-range.scss +91 -0
  75. data/node_modules/bootstrap/scss/forms/_form-select.scss +67 -0
  76. data/node_modules/bootstrap/scss/forms/_form-text.scss +11 -0
  77. data/node_modules/bootstrap/scss/forms/_input-group.scss +121 -0
  78. data/node_modules/bootstrap/scss/forms/_labels.scss +36 -0
  79. data/node_modules/bootstrap/scss/forms/_validation.scss +12 -0
  80. data/node_modules/bootstrap/scss/helpers/_clearfix.scss +3 -0
  81. data/node_modules/bootstrap/scss/helpers/_colored-links.scss +12 -0
  82. data/node_modules/bootstrap/scss/helpers/_position.scss +30 -0
  83. data/node_modules/bootstrap/scss/helpers/_ratio.scss +26 -0
  84. data/node_modules/bootstrap/scss/helpers/_stretched-link.scss +15 -0
  85. data/node_modules/bootstrap/scss/helpers/_text-truncation.scss +7 -0
  86. data/node_modules/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
  87. data/node_modules/bootstrap/scss/mixins/_alert.scss +11 -0
  88. data/node_modules/bootstrap/scss/mixins/_border-radius.scss +78 -0
  89. data/node_modules/bootstrap/scss/mixins/_box-shadow.scss +18 -0
  90. data/node_modules/bootstrap/scss/mixins/_breakpoints.scss +127 -0
  91. data/node_modules/bootstrap/scss/mixins/_buttons.scss +133 -0
  92. data/node_modules/bootstrap/scss/mixins/_caret.scss +64 -0
  93. data/node_modules/bootstrap/scss/mixins/_clearfix.scss +9 -0
  94. data/node_modules/bootstrap/scss/mixins/_container.scss +9 -0
  95. data/node_modules/bootstrap/scss/mixins/_deprecate.scss +10 -0
  96. data/node_modules/bootstrap/scss/mixins/_forms.scss +134 -0
  97. data/node_modules/bootstrap/scss/mixins/_gradients.scss +47 -0
  98. data/node_modules/bootstrap/scss/mixins/_grid.scss +120 -0
  99. data/node_modules/bootstrap/scss/mixins/_image.scss +16 -0
  100. data/node_modules/bootstrap/scss/mixins/_list-group.scss +24 -0
  101. data/node_modules/bootstrap/scss/mixins/_lists.scss +7 -0
  102. data/node_modules/bootstrap/scss/mixins/_pagination.scss +31 -0
  103. data/node_modules/bootstrap/scss/mixins/_reset-text.scss +17 -0
  104. data/node_modules/bootstrap/scss/mixins/_resize.scss +6 -0
  105. data/node_modules/bootstrap/scss/mixins/_table-variants.scss +21 -0
  106. data/node_modules/bootstrap/scss/mixins/_text-truncate.scss +8 -0
  107. data/node_modules/bootstrap/scss/mixins/_transition.scss +26 -0
  108. data/node_modules/bootstrap/scss/mixins/_utilities.scss +68 -0
  109. data/node_modules/bootstrap/scss/mixins/_visually-hidden.scss +29 -0
  110. data/node_modules/bootstrap/scss/utilities/_api.scss +47 -0
  111. data/node_modules/bootstrap/scss/vendor/_rfs.scss +312 -0
  112. metadata +106 -19
@@ -0,0 +1,410 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * Bootstrap (v5.0.0-beta3): collapse.js
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+
8
+ import {
9
+ defineJQueryPlugin,
10
+ emulateTransitionEnd,
11
+ getSelectorFromElement,
12
+ getElementFromSelector,
13
+ getTransitionDurationFromElement,
14
+ isElement,
15
+ reflow,
16
+ typeCheckConfig
17
+ } from './util/index'
18
+ import Data from './dom/data'
19
+ import EventHandler from './dom/event-handler'
20
+ import Manipulator from './dom/manipulator'
21
+ import SelectorEngine from './dom/selector-engine'
22
+ import BaseComponent from './base-component'
23
+
24
+ /**
25
+ * ------------------------------------------------------------------------
26
+ * Constants
27
+ * ------------------------------------------------------------------------
28
+ */
29
+
30
+ const NAME = 'collapse'
31
+ const DATA_KEY = 'bs.collapse'
32
+ const EVENT_KEY = `.${DATA_KEY}`
33
+ const DATA_API_KEY = '.data-api'
34
+
35
+ const Default = {
36
+ toggle: true,
37
+ parent: ''
38
+ }
39
+
40
+ const DefaultType = {
41
+ toggle: 'boolean',
42
+ parent: '(string|element)'
43
+ }
44
+
45
+ const EVENT_SHOW = `show${EVENT_KEY}`
46
+ const EVENT_SHOWN = `shown${EVENT_KEY}`
47
+ const EVENT_HIDE = `hide${EVENT_KEY}`
48
+ const EVENT_HIDDEN = `hidden${EVENT_KEY}`
49
+ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
50
+
51
+ const CLASS_NAME_SHOW = 'show'
52
+ const CLASS_NAME_COLLAPSE = 'collapse'
53
+ const CLASS_NAME_COLLAPSING = 'collapsing'
54
+ const CLASS_NAME_COLLAPSED = 'collapsed'
55
+
56
+ const WIDTH = 'width'
57
+ const HEIGHT = 'height'
58
+
59
+ const SELECTOR_ACTIVES = '.show, .collapsing'
60
+ const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]'
61
+
62
+ /**
63
+ * ------------------------------------------------------------------------
64
+ * Class Definition
65
+ * ------------------------------------------------------------------------
66
+ */
67
+
68
+ class Collapse extends BaseComponent {
69
+ constructor(element, config) {
70
+ super(element)
71
+
72
+ this._isTransitioning = false
73
+ this._config = this._getConfig(config)
74
+ this._triggerArray = SelectorEngine.find(
75
+ `${SELECTOR_DATA_TOGGLE}[href="#${this._element.id}"],` +
76
+ `${SELECTOR_DATA_TOGGLE}[data-bs-target="#${this._element.id}"]`
77
+ )
78
+
79
+ const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)
80
+
81
+ for (let i = 0, len = toggleList.length; i < len; i++) {
82
+ const elem = toggleList[i]
83
+ const selector = getSelectorFromElement(elem)
84
+ const filterElement = SelectorEngine.find(selector)
85
+ .filter(foundElem => foundElem === this._element)
86
+
87
+ if (selector !== null && filterElement.length) {
88
+ this._selector = selector
89
+ this._triggerArray.push(elem)
90
+ }
91
+ }
92
+
93
+ this._parent = this._config.parent ? this._getParent() : null
94
+
95
+ if (!this._config.parent) {
96
+ this._addAriaAndCollapsedClass(this._element, this._triggerArray)
97
+ }
98
+
99
+ if (this._config.toggle) {
100
+ this.toggle()
101
+ }
102
+ }
103
+
104
+ // Getters
105
+
106
+ static get Default() {
107
+ return Default
108
+ }
109
+
110
+ static get DATA_KEY() {
111
+ return DATA_KEY
112
+ }
113
+
114
+ // Public
115
+
116
+ toggle() {
117
+ if (this._element.classList.contains(CLASS_NAME_SHOW)) {
118
+ this.hide()
119
+ } else {
120
+ this.show()
121
+ }
122
+ }
123
+
124
+ show() {
125
+ if (this._isTransitioning || this._element.classList.contains(CLASS_NAME_SHOW)) {
126
+ return
127
+ }
128
+
129
+ let actives
130
+ let activesData
131
+
132
+ if (this._parent) {
133
+ actives = SelectorEngine.find(SELECTOR_ACTIVES, this._parent)
134
+ .filter(elem => {
135
+ if (typeof this._config.parent === 'string') {
136
+ return elem.getAttribute('data-bs-parent') === this._config.parent
137
+ }
138
+
139
+ return elem.classList.contains(CLASS_NAME_COLLAPSE)
140
+ })
141
+
142
+ if (actives.length === 0) {
143
+ actives = null
144
+ }
145
+ }
146
+
147
+ const container = SelectorEngine.findOne(this._selector)
148
+ if (actives) {
149
+ const tempActiveData = actives.find(elem => container !== elem)
150
+ activesData = tempActiveData ? Data.get(tempActiveData, DATA_KEY) : null
151
+
152
+ if (activesData && activesData._isTransitioning) {
153
+ return
154
+ }
155
+ }
156
+
157
+ const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)
158
+ if (startEvent.defaultPrevented) {
159
+ return
160
+ }
161
+
162
+ if (actives) {
163
+ actives.forEach(elemActive => {
164
+ if (container !== elemActive) {
165
+ Collapse.collapseInterface(elemActive, 'hide')
166
+ }
167
+
168
+ if (!activesData) {
169
+ Data.set(elemActive, DATA_KEY, null)
170
+ }
171
+ })
172
+ }
173
+
174
+ const dimension = this._getDimension()
175
+
176
+ this._element.classList.remove(CLASS_NAME_COLLAPSE)
177
+ this._element.classList.add(CLASS_NAME_COLLAPSING)
178
+
179
+ this._element.style[dimension] = 0
180
+
181
+ if (this._triggerArray.length) {
182
+ this._triggerArray.forEach(element => {
183
+ element.classList.remove(CLASS_NAME_COLLAPSED)
184
+ element.setAttribute('aria-expanded', true)
185
+ })
186
+ }
187
+
188
+ this.setTransitioning(true)
189
+
190
+ const complete = () => {
191
+ this._element.classList.remove(CLASS_NAME_COLLAPSING)
192
+ this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)
193
+
194
+ this._element.style[dimension] = ''
195
+
196
+ this.setTransitioning(false)
197
+
198
+ EventHandler.trigger(this._element, EVENT_SHOWN)
199
+ }
200
+
201
+ const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
202
+ const scrollSize = `scroll${capitalizedDimension}`
203
+ const transitionDuration = getTransitionDurationFromElement(this._element)
204
+
205
+ EventHandler.one(this._element, 'transitionend', complete)
206
+
207
+ emulateTransitionEnd(this._element, transitionDuration)
208
+ this._element.style[dimension] = `${this._element[scrollSize]}px`
209
+ }
210
+
211
+ hide() {
212
+ if (this._isTransitioning || !this._element.classList.contains(CLASS_NAME_SHOW)) {
213
+ return
214
+ }
215
+
216
+ const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)
217
+ if (startEvent.defaultPrevented) {
218
+ return
219
+ }
220
+
221
+ const dimension = this._getDimension()
222
+
223
+ this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`
224
+
225
+ reflow(this._element)
226
+
227
+ this._element.classList.add(CLASS_NAME_COLLAPSING)
228
+ this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)
229
+
230
+ const triggerArrayLength = this._triggerArray.length
231
+ if (triggerArrayLength > 0) {
232
+ for (let i = 0; i < triggerArrayLength; i++) {
233
+ const trigger = this._triggerArray[i]
234
+ const elem = getElementFromSelector(trigger)
235
+
236
+ if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) {
237
+ trigger.classList.add(CLASS_NAME_COLLAPSED)
238
+ trigger.setAttribute('aria-expanded', false)
239
+ }
240
+ }
241
+ }
242
+
243
+ this.setTransitioning(true)
244
+
245
+ const complete = () => {
246
+ this.setTransitioning(false)
247
+ this._element.classList.remove(CLASS_NAME_COLLAPSING)
248
+ this._element.classList.add(CLASS_NAME_COLLAPSE)
249
+ EventHandler.trigger(this._element, EVENT_HIDDEN)
250
+ }
251
+
252
+ this._element.style[dimension] = ''
253
+ const transitionDuration = getTransitionDurationFromElement(this._element)
254
+
255
+ EventHandler.one(this._element, 'transitionend', complete)
256
+ emulateTransitionEnd(this._element, transitionDuration)
257
+ }
258
+
259
+ setTransitioning(isTransitioning) {
260
+ this._isTransitioning = isTransitioning
261
+ }
262
+
263
+ dispose() {
264
+ super.dispose()
265
+ this._config = null
266
+ this._parent = null
267
+ this._triggerArray = null
268
+ this._isTransitioning = null
269
+ }
270
+
271
+ // Private
272
+
273
+ _getConfig(config) {
274
+ config = {
275
+ ...Default,
276
+ ...config
277
+ }
278
+ config.toggle = Boolean(config.toggle) // Coerce string values
279
+ typeCheckConfig(NAME, config, DefaultType)
280
+ return config
281
+ }
282
+
283
+ _getDimension() {
284
+ return this._element.classList.contains(WIDTH) ? WIDTH : HEIGHT
285
+ }
286
+
287
+ _getParent() {
288
+ let { parent } = this._config
289
+
290
+ if (isElement(parent)) {
291
+ // it's a jQuery object
292
+ if (typeof parent.jquery !== 'undefined' || typeof parent[0] !== 'undefined') {
293
+ parent = parent[0]
294
+ }
295
+ } else {
296
+ parent = SelectorEngine.findOne(parent)
297
+ }
298
+
299
+ const selector = `${SELECTOR_DATA_TOGGLE}[data-bs-parent="${parent}"]`
300
+
301
+ SelectorEngine.find(selector, parent)
302
+ .forEach(element => {
303
+ const selected = getElementFromSelector(element)
304
+
305
+ this._addAriaAndCollapsedClass(
306
+ selected,
307
+ [element]
308
+ )
309
+ })
310
+
311
+ return parent
312
+ }
313
+
314
+ _addAriaAndCollapsedClass(element, triggerArray) {
315
+ if (!element || !triggerArray.length) {
316
+ return
317
+ }
318
+
319
+ const isOpen = element.classList.contains(CLASS_NAME_SHOW)
320
+
321
+ triggerArray.forEach(elem => {
322
+ if (isOpen) {
323
+ elem.classList.remove(CLASS_NAME_COLLAPSED)
324
+ } else {
325
+ elem.classList.add(CLASS_NAME_COLLAPSED)
326
+ }
327
+
328
+ elem.setAttribute('aria-expanded', isOpen)
329
+ })
330
+ }
331
+
332
+ // Static
333
+
334
+ static collapseInterface(element, config) {
335
+ let data = Data.get(element, DATA_KEY)
336
+ const _config = {
337
+ ...Default,
338
+ ...Manipulator.getDataAttributes(element),
339
+ ...(typeof config === 'object' && config ? config : {})
340
+ }
341
+
342
+ if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
343
+ _config.toggle = false
344
+ }
345
+
346
+ if (!data) {
347
+ data = new Collapse(element, _config)
348
+ }
349
+
350
+ if (typeof config === 'string') {
351
+ if (typeof data[config] === 'undefined') {
352
+ throw new TypeError(`No method named "${config}"`)
353
+ }
354
+
355
+ data[config]()
356
+ }
357
+ }
358
+
359
+ static jQueryInterface(config) {
360
+ return this.each(function () {
361
+ Collapse.collapseInterface(this, config)
362
+ })
363
+ }
364
+ }
365
+
366
+ /**
367
+ * ------------------------------------------------------------------------
368
+ * Data Api implementation
369
+ * ------------------------------------------------------------------------
370
+ */
371
+
372
+ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
373
+ // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
374
+ if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {
375
+ event.preventDefault()
376
+ }
377
+
378
+ const triggerData = Manipulator.getDataAttributes(this)
379
+ const selector = getSelectorFromElement(this)
380
+ const selectorElements = SelectorEngine.find(selector)
381
+
382
+ selectorElements.forEach(element => {
383
+ const data = Data.get(element, DATA_KEY)
384
+ let config
385
+ if (data) {
386
+ // update parent attribute
387
+ if (data._parent === null && typeof triggerData.parent === 'string') {
388
+ data._config.parent = triggerData.parent
389
+ data._parent = data._getParent()
390
+ }
391
+
392
+ config = 'toggle'
393
+ } else {
394
+ config = triggerData
395
+ }
396
+
397
+ Collapse.collapseInterface(element, config)
398
+ })
399
+ })
400
+
401
+ /**
402
+ * ------------------------------------------------------------------------
403
+ * jQuery
404
+ * ------------------------------------------------------------------------
405
+ * add .Collapse to jQuery only if jQuery is present
406
+ */
407
+
408
+ defineJQueryPlugin(NAME, Collapse)
409
+
410
+ export default Collapse
@@ -0,0 +1,57 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * Bootstrap (v5.0.0-beta3): dom/data.js
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+
8
+ /**
9
+ * ------------------------------------------------------------------------
10
+ * Constants
11
+ * ------------------------------------------------------------------------
12
+ */
13
+
14
+ const elementMap = new Map()
15
+
16
+ export default {
17
+ set(element, key, instance) {
18
+ if (!elementMap.has(element)) {
19
+ elementMap.set(element, new Map())
20
+ }
21
+
22
+ const instanceMap = elementMap.get(element)
23
+
24
+ // make it clear we only want one instance per element
25
+ // can be removed later when multiple key/instances are fine to be used
26
+ if (!instanceMap.has(key) && instanceMap.size !== 0) {
27
+ // eslint-disable-next-line no-console
28
+ console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)
29
+ return
30
+ }
31
+
32
+ instanceMap.set(key, instance)
33
+ },
34
+
35
+ get(element, key) {
36
+ if (elementMap.has(element)) {
37
+ return elementMap.get(element).get(key) || null
38
+ }
39
+
40
+ return null
41
+ },
42
+
43
+ remove(element, key) {
44
+ if (!elementMap.has(element)) {
45
+ return
46
+ }
47
+
48
+ const instanceMap = elementMap.get(element)
49
+
50
+ instanceMap.delete(key)
51
+
52
+ // free up element references if there are no instances left for an element
53
+ if (instanceMap.size === 0) {
54
+ elementMap.delete(element)
55
+ }
56
+ }
57
+ }