stimulus-rails 0.6.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -22
- data/app/assets/javascripts/stimulus-autoloader.js +2 -0
- data/app/assets/javascripts/stimulus-importmap-autoloader.js +2 -0
- data/app/assets/javascripts/stimulus-loading.js +81 -0
- data/app/assets/javascripts/stimulus.js +26 -4
- data/app/assets/javascripts/stimulus.min.js +3 -2
- data/lib/generators/stimulus/stimulus_generator.rb +1 -1
- data/lib/install/app/javascript/controllers/index_for_importmap.js +8 -2
- data/lib/install/stimulus_with_importmap.rb +2 -2
- data/lib/stimulus/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a394227aa508c3626226dfc459efb1d264dcd310d90077d9f446605407f8f778
|
4
|
+
data.tar.gz: 267e9e6e0429f0d2cb9a46befac52e319055e05f316ddf68f618cc4b59b2def8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ffd9d3864592dea0e364690f3d19dff2469b68e6318884c02e1af4ef110244fe193568003139b198df5a69da8e4194cd71bc96746ba004664460fc83a72908a
|
7
|
+
data.tar.gz: c70a8be0745b25ac1de92456309ee11e74930c265ef6fb1cf5f9df0ae474beb295b5d06dd37f844b76d399b096424f0ebd41ea2598d21c2f69e7b55005001de2
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[Stimulus](https://stimulus.hotwired.dev) is a JavaScript framework with modest ambitions. It doesn’t seek to take over your entire front-end in fact, it’s not concerned with rendering HTML at all. Instead, it’s designed to augment your HTML with just enough behavior to make it shine. Stimulus pairs beautifully with Turbo to provide a complete solution for fast, compelling applications with a minimal amount of effort. Together they form the core of [Hotwire](https://hotwired.dev).
|
4
4
|
|
5
|
-
Stimulus for Rails makes it easy to use this modest framework with
|
5
|
+
Stimulus for Rails makes it easy to use this modest framework with both import-mapped and JavaScript-bundled apps. It relies on either `importmap-rails` to make Stimulus available via ESM or a Node-capable Rails (like via `jsbundling-rails`) to include Stimulus in the bundle. Make sure to install one of these first!
|
6
6
|
|
7
7
|
|
8
8
|
## Installation
|
@@ -11,14 +11,25 @@ Stimulus for Rails makes it easy to use this modest framework with the asset pip
|
|
11
11
|
2. Run `./bin/bundle install`.
|
12
12
|
3. Run `./bin/rails stimulus:install`
|
13
13
|
|
14
|
-
The installer will automatically detect whether you're using an [import map](https://github.com/rails/importmap-rails) or [JavaScript bundler](https://github.com/rails/jsbundling-rails) to manage your application's JavaScript. If you're using an import map, the Stimulus dependencies will be pinned to the versions of the library included with this gem. If you're using
|
14
|
+
The installer will automatically detect whether you're using an [import map](https://github.com/rails/importmap-rails) or [JavaScript bundler](https://github.com/rails/jsbundling-rails) to manage your application's JavaScript. If you're using an import map, the Stimulus dependencies will be pinned to the versions of the library included with this gem. If you're using Node, yarn will add the dependencies to your `package.json` file.
|
15
15
|
|
16
|
+
The installer amends your JavaScript entry point at `app/javascript/application.js` to import the `app/javascript/controllers/index.js` file, which is responsible for setting up your Stimulus application and registering your controllers.
|
16
17
|
|
17
|
-
## Usage
|
18
18
|
|
19
|
-
|
19
|
+
## Usage with import map
|
20
|
+
|
21
|
+
With an import-mapped application, controllers are automatically pinned and registered based on the file structure. The installer will amend your `config/importmap.rb` to configure this such that all controllers in `app/javascript/controllers` are pinned.
|
22
|
+
|
23
|
+
By default, your application will be setup to eager load all the controllers mentioned in your import map under "controllers". This works well together with preloading in the import map when you have a modest number of controllers.
|
24
|
+
|
25
|
+
If you have a lot of controllers, you may well want to lazy load them instead. This can be done by changing from `eagerLoadControllersFrom` to `lazyLoadControllersFrom` in your `app/javascript/controllers/index.js` file.
|
26
|
+
|
27
|
+
When lazy loading, controllers are not loaded until their data-controller identifier is encountered in the DOM.
|
28
|
+
|
20
29
|
|
21
|
-
|
30
|
+
## Usage with JavaScript bundler
|
31
|
+
|
32
|
+
With an application using a JavaScript bundler, controllers need to be imported and registered directly in the index.js file. But this can be done automatically using either the Stimulus generator (`./bin/rails generate stimulus [controller]`) or the dedicated `stimulus:manifest:update` task. Either will overwrite the `controllers/index.js` file.
|
22
33
|
|
23
34
|
You're encouraged to use the generator to add new controllers like so:
|
24
35
|
|
@@ -38,23 +49,6 @@ export default class extends Controller {
|
|
38
49
|
}
|
39
50
|
```
|
40
51
|
|
41
|
-
And it'll be activated and registered automatically when encountering the data-controller attribute in your DOM:
|
42
|
-
|
43
|
-
```html
|
44
|
-
<div data-controller="hello">
|
45
|
-
<input data-hello-target="name" type="text">
|
46
|
-
|
47
|
-
<button data-action="click->hello#greet">
|
48
|
-
Greet
|
49
|
-
</button>
|
50
|
-
|
51
|
-
<span data-hello-target="output">
|
52
|
-
</span>
|
53
|
-
</div>
|
54
|
-
```
|
55
|
-
|
56
|
-
That's it!
|
57
|
-
|
58
52
|
|
59
53
|
## License
|
60
54
|
|
@@ -50,3 +50,5 @@ new MutationObserver((mutationsList) => {
|
|
50
50
|
}).observe(document, { attributeFilter: [controllerAttribute], subtree: true, childList: true })
|
51
51
|
|
52
52
|
autoloadControllersWithin(document)
|
53
|
+
|
54
|
+
console.warn("stimulus-autoload.js has been deprecated in favor of stimulus-loading.js")
|
@@ -23,3 +23,5 @@ function registerControllerFromPath(path, under, application) {
|
|
23
23
|
.then(module => application.register(name, module.default))
|
24
24
|
.catch(error => console.log(`Failed to register controller: ${name} (${path})`, error))
|
25
25
|
}
|
26
|
+
|
27
|
+
console.warn("stimulus-importmap-autoload.js has been deprecated in favor of stimulus-loading.js")
|
@@ -0,0 +1,81 @@
|
|
1
|
+
// FIXME: es-module-shim won't shim the dynamic import without this explicit import
|
2
|
+
import "@hotwired/stimulus"
|
3
|
+
|
4
|
+
const controllerAttribute = "data-controller"
|
5
|
+
const registeredControllers = {}
|
6
|
+
|
7
|
+
// Eager load all controllers registered beneath the `under` path in the import map to the passed application instance.
|
8
|
+
export function eagerLoadControllersFrom(under, application) {
|
9
|
+
const paths = Object.keys(parseImportmapJson()).filter(path => path.match(new RegExp(`^${under}/.*_controller$`)))
|
10
|
+
paths.forEach(path => registerControllerFromPath(path, under, application))
|
11
|
+
}
|
12
|
+
|
13
|
+
function parseImportmapJson() {
|
14
|
+
return JSON.parse(document.querySelector("script[type=importmap]").text).imports
|
15
|
+
}
|
16
|
+
|
17
|
+
function registerControllerFromPath(path, under, application) {
|
18
|
+
const name = path
|
19
|
+
.replace(new RegExp(`^${under}/`), "")
|
20
|
+
.replace("_controller", "")
|
21
|
+
.replace(/\//g, "--")
|
22
|
+
.replace(/_/g, "-")
|
23
|
+
|
24
|
+
import(path)
|
25
|
+
.then(module => registerController(name, module, application))
|
26
|
+
.catch(error => console.debug(`Failed to register controller: ${name} (${path})`, error))
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
// Lazy load controllers registered beneath the `under` path in the import map to the passed application instance.
|
31
|
+
export function lazyLoadControllersFrom(under, application, element = document) {
|
32
|
+
lazyLoadExistingControllers(under, application, element)
|
33
|
+
lazyLoadNewControllers(under, application, element)
|
34
|
+
}
|
35
|
+
|
36
|
+
function lazyLoadExistingControllers(under, application, element) {
|
37
|
+
queryControllerNamesWithin(element).forEach(controllerName => loadController(controllerName, under, application))
|
38
|
+
}
|
39
|
+
|
40
|
+
function lazyLoadNewControllers(under, application, element) {
|
41
|
+
new MutationObserver((mutationsList) => {
|
42
|
+
for (const { attributeName, target, type } of mutationsList) {
|
43
|
+
switch (type) {
|
44
|
+
case "attributes": {
|
45
|
+
if (attributeName == controllerAttribute && target.getAttribute(controllerAttribute)) {
|
46
|
+
extractControllerNamesFrom(target).forEach(controllerName => loadController(controllerName, under, application))
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
case "childList": {
|
51
|
+
lazyLoadExistingControllers(under, application, target)
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}).observe(element, { attributeFilter: [controllerAttribute], subtree: true, childList: true })
|
56
|
+
}
|
57
|
+
|
58
|
+
function queryControllerNamesWithin(element) {
|
59
|
+
return Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).map(extractControllerNamesFrom).flat()
|
60
|
+
}
|
61
|
+
|
62
|
+
function extractControllerNamesFrom(element) {
|
63
|
+
return element.getAttribute(controllerAttribute).split(/\s+/).filter(content => content.length)
|
64
|
+
}
|
65
|
+
|
66
|
+
function loadController(name, under, application) {
|
67
|
+
import(controllerFilename(name, under))
|
68
|
+
.then(module => registerController(name, module, application))
|
69
|
+
.catch(error => console.debug(`Failed to autoload controller: ${name}`, error))
|
70
|
+
}
|
71
|
+
|
72
|
+
function controllerFilename(name, under) {
|
73
|
+
return `${under}/${name.replace(/--/g, "/").replace(/-/g, "_")}_controller`
|
74
|
+
}
|
75
|
+
|
76
|
+
function registerController(name, module, application) {
|
77
|
+
if (name in registeredControllers) return
|
78
|
+
|
79
|
+
application.register(name, module.default)
|
80
|
+
registeredControllers[name] = true
|
81
|
+
}
|
@@ -1,8 +1,9 @@
|
|
1
1
|
//= link ./stimulus-autoloader.js
|
2
2
|
//= link ./stimulus-importmap-autoloader.js
|
3
|
+
//= link ./stimulus-loading.js
|
3
4
|
|
4
5
|
/*
|
5
|
-
Stimulus 3.0.
|
6
|
+
Stimulus 3.0.1
|
6
7
|
Copyright © 2021 Basecamp, LLC
|
7
8
|
*/
|
8
9
|
class EventListener {
|
@@ -218,6 +219,7 @@ const defaultEventNames = {
|
|
218
219
|
"a": e => "click",
|
219
220
|
"button": e => "click",
|
220
221
|
"form": e => "submit",
|
222
|
+
"details": e => "toggle",
|
221
223
|
"input": e => e.getAttribute("type") == "submit" ? "click" : "input",
|
222
224
|
"select": e => "change",
|
223
225
|
"textarea": e => "input"
|
@@ -314,6 +316,7 @@ class Binding {
|
|
314
316
|
|
315
317
|
class ElementObserver {
|
316
318
|
constructor(element, delegate) {
|
319
|
+
this.mutationObserverInit = { attributes: true, childList: true, subtree: true };
|
317
320
|
this.element = element;
|
318
321
|
this.started = false;
|
319
322
|
this.delegate = delegate;
|
@@ -323,10 +326,21 @@ class ElementObserver {
|
|
323
326
|
start() {
|
324
327
|
if (!this.started) {
|
325
328
|
this.started = true;
|
326
|
-
this.mutationObserver.observe(this.element,
|
329
|
+
this.mutationObserver.observe(this.element, this.mutationObserverInit);
|
327
330
|
this.refresh();
|
328
331
|
}
|
329
332
|
}
|
333
|
+
pause(callback) {
|
334
|
+
if (this.started) {
|
335
|
+
this.mutationObserver.disconnect();
|
336
|
+
this.started = false;
|
337
|
+
}
|
338
|
+
callback();
|
339
|
+
if (!this.started) {
|
340
|
+
this.mutationObserver.observe(this.element, this.mutationObserverInit);
|
341
|
+
this.started = true;
|
342
|
+
}
|
343
|
+
}
|
330
344
|
stop() {
|
331
345
|
if (this.started) {
|
332
346
|
this.mutationObserver.takeRecords();
|
@@ -452,6 +466,9 @@ class AttributeObserver {
|
|
452
466
|
start() {
|
453
467
|
this.elementObserver.start();
|
454
468
|
}
|
469
|
+
pause(callback) {
|
470
|
+
this.elementObserver.pause(callback);
|
471
|
+
}
|
455
472
|
stop() {
|
456
473
|
this.elementObserver.stop();
|
457
474
|
}
|
@@ -677,6 +694,9 @@ class TokenListObserver {
|
|
677
694
|
start() {
|
678
695
|
this.attributeObserver.start();
|
679
696
|
}
|
697
|
+
pause(callback) {
|
698
|
+
this.attributeObserver.pause(callback);
|
699
|
+
}
|
680
700
|
stop() {
|
681
701
|
this.attributeObserver.stop();
|
682
702
|
}
|
@@ -992,15 +1012,17 @@ class TargetObserver {
|
|
992
1012
|
this.disconnectTarget(element, name);
|
993
1013
|
}
|
994
1014
|
connectTarget(element, name) {
|
1015
|
+
var _a;
|
995
1016
|
if (!this.targetsByName.has(name, element)) {
|
996
1017
|
this.targetsByName.add(name, element);
|
997
|
-
this.delegate.targetConnected(element, name);
|
1018
|
+
(_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetConnected(element, name));
|
998
1019
|
}
|
999
1020
|
}
|
1000
1021
|
disconnectTarget(element, name) {
|
1022
|
+
var _a;
|
1001
1023
|
if (this.targetsByName.has(name, element)) {
|
1002
1024
|
this.targetsByName.delete(name, element);
|
1003
|
-
this.delegate.targetDisconnected(element, name);
|
1025
|
+
(_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetDisconnected(element, name));
|
1004
1026
|
}
|
1005
1027
|
}
|
1006
1028
|
disconnectAllTargets() {
|
@@ -1,8 +1,9 @@
|
|
1
1
|
//= link ./stimulus-autoloader.js
|
2
2
|
//= link ./stimulus-importmap-autoloader.js
|
3
|
+
//= link ./stimulus-loading.js
|
3
4
|
|
4
5
|
/*
|
5
|
-
Stimulus 3.0.
|
6
|
+
Stimulus 3.0.1
|
6
7
|
Copyright © 2021 Basecamp, LLC
|
7
8
|
*/
|
8
|
-
class e{constructor(e,t,r){this.eventTarget=e,this.eventName=t,this.eventOptions=r,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}get bindings(){return Array.from(this.unorderedBindings).sort(((e,t)=>{const r=e.index,s=t.index;return r<s?-1:r>s?1:0}))}}class t{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach((e=>e.connect())))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach((e=>e.disconnect())))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce(((e,t)=>e.concat(Array.from(t.values()))),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e){this.fetchEventListenerForBinding(e).bindingDisconnected(e)}handleError(e,t,r={}){this.application.handleError(e,`Error ${t}`,r)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:r,eventOptions:s}=e;return this.fetchEventListener(t,r,s)}fetchEventListener(e,t,r){const s=this.fetchEventListenerMapForEventTarget(e),n=this.cacheKey(t,r);let i=s.get(n);return i||(i=this.createEventListener(e,t,r),s.set(n,i)),i}createEventListener(t,r,s){const n=new e(t,r,s);return this.started&&n.connect(),n}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const r=[e];return Object.keys(t).sort().forEach((e=>{r.push(`${t[e]?"":"!"}${e}`)})),r.join(":")}}const r=/^((.+?)(@(window|document))?->)?(.+?)(#([^:]+?))(:(.+))?$/;function s(e){return"window"==e?window:"document"==e?document:void 0}function n(e){return e.replace(/(?:[_-])([a-z0-9])/g,((e,t)=>t.toUpperCase()))}function i(e){return e.charAt(0).toUpperCase()+e.slice(1)}function o(e){return e.replace(/([A-Z])/g,((e,t)=>`-${t.toLowerCase()}`))}const a={a:e=>"click",button:e=>"click",form:e=>"submit",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:e=>"change",textarea:e=>"input"};function c(e){throw new Error(e)}function h(e){try{return JSON.parse(e)}catch(t){return e}}class l{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){this.willBeInvokedByEvent(e)&&this.invokeWithEvent(e)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}invokeWithEvent(e){const{target:t,currentTarget:r}=e;try{const{params:s}=this.action,n=Object.assign(e,{params:s});this.method.call(this.controller,n),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:r,action:this.methodName})}catch(t){const{identifier:r,controller:s,element:n,index:i}=this,o={identifier:r,controller:s,element:n,index:i,event:e};this.context.handleError(t,`invoking action "${this.action}"`,o)}}willBeInvokedByEvent(e){const t=e.target;return this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class u{constructor(e,t){this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,childList:!0,subtree:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){const r=e;this.elements.has(r)?this.delegate.elementAttributeChanged&&this.matchElement(r)?this.delegate.elementAttributeChanged(r,t):this.removeElement(r):this.matchElement(r)&&this.addElement(r)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const r of this.matchElementsInTree(e))t.call(this,r)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class d{constructor(e,t,r){this.attributeName=t,this.delegate=r,this.elementObserver=new u(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],r=Array.from(e.querySelectorAll(this.selector));return t.concat(r)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}class g{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const r=this.delegate.getStringMapKeyForAttribute(e);if(null!=r){this.stringMap.has(e)||this.stringMapKeyAdded(r,e);const s=this.element.getAttribute(e);if(this.stringMap.get(e)!=s&&this.stringMapValueChanged(s,r,t),null==s){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(r,e,t)}else this.stringMap.set(e,s)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,r){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,r)}stringMapKeyRemoved(e,t,r){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,r)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map((e=>e.name))}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}function m(e,t,r){f(e,t).add(r)}function p(e,t,r){f(e,t).delete(r),b(e,t)}function f(e,t){let r=e.get(t);return r||(r=new Set,e.set(t,r)),r}function b(e,t){const r=e.get(t);null!=r&&0==r.size&&e.delete(t)}class v{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e.concat(Array.from(t))),[])}get size(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e+t.size),0)}add(e,t){m(this.valuesByKey,e,t)}delete(e,t){p(this.valuesByKey,e,t)}has(e,t){const r=this.valuesByKey.get(e);return null!=r&&r.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some((t=>t.has(e)))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter((([t,r])=>r.has(e))).map((([e,t])=>e))}}class y extends v{constructor(){super(),this.keysByValue=new Map}get values(){return Array.from(this.keysByValue.keys())}add(e,t){super.add(e,t),m(this.keysByValue,t,e)}delete(e,t){super.delete(e,t),p(this.keysByValue,t,e)}hasValue(e){return this.keysByValue.has(e)}getKeysForValue(e){const t=this.keysByValue.get(e);return t?Array.from(t):[]}}class A{constructor(e,t,r){this.attributeObserver=new d(e,t,this),this.delegate=r,this.tokensByElement=new v}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,r]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(r)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach((e=>this.tokenMatched(e)))}tokensUnmatched(e){e.forEach((e=>this.tokenUnmatched(e)))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),r=this.readTokensForElement(e),s=function(e,t){const r=Math.max(e.length,t.length);return Array.from({length:r},((r,s)=>[e[s],t[s]]))}(t,r).findIndex((([e,t])=>{return s=t,!((r=e)&&s&&r.index==s.index&&r.content==s.content);var r,s}));return-1==s?[[],[]]:[t.slice(s),r.slice(s)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,r){return e.trim().split(/\s+/).filter((e=>e.length)).map(((e,s)=>({element:t,attributeName:r,content:e,index:s})))}(e.getAttribute(t)||"",e,t)}}class E{constructor(e,t,r){this.tokenListObserver=new A(e,t,this),this.delegate=r,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:r}=this.fetchParseResultForToken(e);r&&(this.fetchValuesByTokenForElement(t).set(e,r),this.delegate.elementMatchedValue(t,r))}tokenUnmatched(e){const{element:t}=e,{value:r}=this.fetchParseResultForToken(e);r&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,r))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class w{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new E(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new l(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach((e=>this.delegate.bindingDisconnected(e))),this.bindingsByAction.clear()}parseValueForToken(e){const t=class{constructor(e,t,r){this.element=e,this.index=t,this.eventTarget=r.eventTarget||e,this.eventName=r.eventName||function(e){const t=e.tagName.toLowerCase();if(t in a)return a[t](e)}(e)||c("missing event name"),this.eventOptions=r.eventOptions||{},this.identifier=r.identifier||c("missing identifier"),this.methodName=r.methodName||c("missing method name")}static forToken(e){return new this(e.element,e.index,function(e){const t=e.trim().match(r)||[];return{eventTarget:s(t[4]),eventName:t[2],eventOptions:t[9]?(n=t[9],n.split(":").reduce(((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)})),{})):{},identifier:t[5],methodName:t[7]};var n}(e.content))}toString(){const e=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}->${this.identifier}#${this.methodName}`}get params(){return this.eventTarget instanceof Element?this.getParamsFromEventTargetAttributes(this.eventTarget):{}}getParamsFromEventTargetAttributes(e){const t={},r=new RegExp(`^data-${this.identifier}-(.+)-param$`);return Array.from(e.attributes).forEach((({name:e,value:s})=>{const i=e.match(r),o=i&&i[1];o&&Object.assign(t,{[n(o)]:h(s)})})),t}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}}.forToken(e);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class O{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new g(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap,this.invokeChangedCallbacksForDefaultValues()}start(){this.stringMapObserver.start()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const r=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,r.writer(this.receiver[e]),r.writer(r.defaultValue))}stringMapValueChanged(e,t,r){const s=this.valueDescriptorNameMap[t];null!==e&&(null===r&&(r=s.writer(s.defaultValue)),this.invokeChangedCallback(t,e,r))}stringMapKeyRemoved(e,t,r){const s=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,s.writer(this.receiver[e]),r):this.invokeChangedCallback(e,s.writer(s.defaultValue),r)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:r,writer:s}of this.valueDescriptors)null==r||this.controller.data.has(e)||this.invokeChangedCallback(t,s(r),void 0)}invokeChangedCallback(e,t,r){const s=`${e}Changed`,n=this.receiver[s];if("function"==typeof n){const s=this.valueDescriptorNameMap[e],i=s.reader(t);let o=r;r&&(o=s.reader(r)),n.call(this.receiver,i,o)}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map((t=>e[t]))}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach((t=>{const r=this.valueDescriptorMap[t];e[r.name]=r})),e}hasValue(e){const t=`has${i(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class k{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new v}start(){this.tokenListObserver||(this.tokenListObserver=new A(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),this.delegate.targetConnected(e,t))}disconnectTarget(e,t){this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),this.delegate.targetDisconnected(e,t))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}class M{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:r,controller:s,element:n}=this;t=Object.assign({identifier:r,controller:s,element:n},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new w(this,this.dispatcher),this.valueObserver=new O(this,this.controller),this.targetObserver=new k(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,r={}){const{identifier:s,controller:n,element:i}=this;r=Object.assign({identifier:s,controller:n,element:i},r),this.application.handleError(e,`Error ${t}`,r)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}invokeControllerMethod(e,...t){const r=this.controller;"function"==typeof r[e]&&r[e](...t)}}function N(e,t){const r=T(e);return Array.from(r.reduce(((e,r)=>(function(e,t){const r=e[t];return Array.isArray(r)?r:[]}(r,t).forEach((t=>e.add(t))),e)),new Set))}function B(e,t){return T(e).reduce(((e,r)=>(e.push(...function(e,t){const r=e[t];return r?Object.keys(r).map((e=>[e,r[e]])):[]}(r,t)),e)),[])}function T(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}function C(e){return function(e,t){const r=x(e),s=function(e,t){return F(t).reduce(((r,s)=>{const n=function(e,t,r){const s=Object.getOwnPropertyDescriptor(e,r);if(!s||!("value"in s)){const e=Object.getOwnPropertyDescriptor(t,r).value;return s&&(e.get=s.get||e.get,e.set=s.set||e.set),e}}(e,t,s);return n&&Object.assign(r,{[s]:n}),r}),{})}(e.prototype,t);return Object.defineProperties(r.prototype,s),r}(e,function(e){return N(e,"blessings").reduce(((t,r)=>{const s=r(e);for(const e in s){const r=t[e]||{};t[e]=Object.assign(r,s[e])}return t}),{})}(e))}const F="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,x=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e((function(){this.a.call(this)}));t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class ${constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:C(e.controllerConstructor)}}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new M(this,e),this.contextsByScope.set(e,t)),t}}class L{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){const t=this.data.get(this.getDataKey(e))||"";return t.match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class S{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const r=this.getAttributeNameForKey(e);return this.element.setAttribute(r,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${o(e)}`}}class D{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,r){let s=this.warnedKeysByObject.get(e);s||(s=new Set,this.warnedKeysByObject.set(e,s)),s.has(t)||(s.add(t),this.logger.warn(r,e))}}function V(e,t){return`[${e}~="${t}"]`}class K{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)]),[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return V(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map((t=>this.deprecate(t,e)))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return V(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:r}=this,s=this.schema.targetAttribute,n=this.schema.targetAttributeForScope(r);this.guide.warn(e,`target:${t}`,`Please replace ${s}="${r}.${t}" with ${n}="${t}". The ${s} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class j{constructor(e,t,r,s){this.targets=new K(this),this.classes=new L(this),this.data=new S(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=r,this.guide=new D(s)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return V(this.schema.controllerAttribute,this.identifier)}}class I{constructor(e,t,r){this.element=e,this.schema=t,this.delegate=r,this.valueListObserver=new E(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:r}=e,s=this.fetchScopesByIdentifierForElement(t);let n=s.get(r);return n||(n=this.delegate.createScopeForElementAndIdentifier(t,r),s.set(r,n)),n}elementMatchedValue(e,t){const r=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,r),1==r&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const r=this.scopeReferenceCounts.get(t);r&&(this.scopeReferenceCounts.set(t,r-1),1==r&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class R{constructor(e){this.application=e,this.scopeObserver=new I(this.element,this.schema,this),this.scopesByIdentifier=new v,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce(((e,t)=>e.concat(t.contexts)),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new $(this.application,e);this.connectModule(t)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const r=this.modulesByIdentifier.get(t);if(r)return r.contexts.find((t=>t.element==e))}handleError(e,t,r){this.application.handleError(e,t,r)}createScopeForElementAndIdentifier(e,t){return new j(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e);this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.connectContextForScope(t)))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier);this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.disconnectContextForScope(t)))}}const P={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`};class U{constructor(e=document.documentElement,r=P){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,r={})=>{this.debug&&this.logFormattedMessage(e,t,r)},this.element=e,this.schema=r,this.dispatcher=new t(this),this.router=new R(this)}static start(e,t){const r=new U(e,t);return r.start(),r}async start(){await new Promise((e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",(()=>e())):e()})),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){t.shouldLoad&&this.load({identifier:e,controllerConstructor:t})}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>this.router.loadDefinition(e)))}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>this.router.unloadIdentifier(e)))}get controllers(){return this.router.contexts.map((e=>e.controller))}getControllerForElementAndIdentifier(e,t){const r=this.router.getContextForElementAndIdentifier(e,t);return r?r.controller:null}handleError(e,t,r){var s;this.logger.error("%s\n\n%o\n\n%o",t,e,r),null===(s=window.onerror)||void 0===s||s.call(window,t,"",0,0,e)}logFormattedMessage(e,t,r={}){r=Object.assign({application:this},r),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},r)),this.logger.groupEnd()}}function z([e,t]){return function(e,t){const r=`${o(e)}-value`,s=function(e){const t=function(e){const t=W(e.type);if(t){const r=q(e.default);if(t!==r)throw new Error(`Type "${t}" must match the type of the default value. Given default value: "${e.default}" as "${r}"`);return t}}(e),r=q(e),s=W(e),n=t||r||s;if(n)return n;throw new Error(`Unknown value type "${e}"`)}(t);return{type:s,key:r,name:n(r),get defaultValue(){return function(e){const t=W(e);if(t)return J[t];const r=e.default;return void 0!==r?r:e}(t)},get hasCustomDefaultValue(){return void 0!==q(t)},reader:_[s],writer:G[s]||G.default}}(e,t)}function W(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function q(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const J={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},_={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError("Expected array");return t},boolean:e=>!("0"==e||"false"==e),number:e=>Number(e),object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError("Expected object");return t},string:e=>e},G={default:function(e){return`${e}`},array:Z,object:Z};function Z(e){return JSON.stringify(e)}class H{constructor(e){this.context=e}static get shouldLoad(){return!0}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:r={},prefix:s=this.identifier,bubbles:n=!0,cancelable:i=!0}={}){const o=new CustomEvent(s?`${s}:${e}`:e,{detail:r,bubbles:n,cancelable:i});return t.dispatchEvent(o),o}}H.blessings=[function(e){return N(e,"classes").reduce(((e,t)=>{return Object.assign(e,{[`${r=t}Class`]:{get(){const{classes:e}=this;if(e.has(r))return e.get(r);{const t=e.getAttributeName(r);throw new Error(`Missing attribute "${t}"`)}}},[`${r}Classes`]:{get(){return this.classes.getAll(r)}},[`has${i(r)}Class`]:{get(){return this.classes.has(r)}}});var r}),{})},function(e){return N(e,"targets").reduce(((e,t)=>{return Object.assign(e,{[`${r=t}Target`]:{get(){const e=this.targets.find(r);if(e)return e;throw new Error(`Missing target element "${r}" for "${this.identifier}" controller`)}},[`${r}Targets`]:{get(){return this.targets.findAll(r)}},[`has${i(r)}Target`]:{get(){return this.targets.has(r)}}});var r}),{})},function(e){const t=B(e,"values"),r={valueDescriptorMap:{get(){return t.reduce(((e,t)=>{const r=z(t),s=this.data.getAttributeNameForKey(r.key);return Object.assign(e,{[s]:r})}),{})}}};return t.reduce(((e,t)=>Object.assign(e,function(e){const t=z(e),{key:r,name:s,reader:n,writer:o}=t;return{[s]:{get(){const e=this.data.get(r);return null!==e?n(e):t.defaultValue},set(e){void 0===e?this.data.delete(r):this.data.set(r,o(e))}},[`has${i(s)}`]:{get(){return this.data.has(r)||t.hasCustomDefaultValue}}}}(t))),r)}],H.targets=[],H.values={};export{U as Application,d as AttributeObserver,M as Context,H as Controller,u as ElementObserver,y as IndexedMultimap,v as Multimap,g as StringMapObserver,A as TokenListObserver,E as ValueListObserver,m as add,P as defaultSchema,p as del,f as fetch,b as prune};
|
9
|
+
class e{constructor(e,t,r){this.eventTarget=e,this.eventName=t,this.eventOptions=r,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}get bindings(){return Array.from(this.unorderedBindings).sort(((e,t)=>{const r=e.index,s=t.index;return r<s?-1:r>s?1:0}))}}class t{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach((e=>e.connect())))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach((e=>e.disconnect())))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce(((e,t)=>e.concat(Array.from(t.values()))),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e){this.fetchEventListenerForBinding(e).bindingDisconnected(e)}handleError(e,t,r={}){this.application.handleError(e,`Error ${t}`,r)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:r,eventOptions:s}=e;return this.fetchEventListener(t,r,s)}fetchEventListener(e,t,r){const s=this.fetchEventListenerMapForEventTarget(e),n=this.cacheKey(t,r);let i=s.get(n);return i||(i=this.createEventListener(e,t,r),s.set(n,i)),i}createEventListener(t,r,s){const n=new e(t,r,s);return this.started&&n.connect(),n}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const r=[e];return Object.keys(t).sort().forEach((e=>{r.push(`${t[e]?"":"!"}${e}`)})),r.join(":")}}const r=/^((.+?)(@(window|document))?->)?(.+?)(#([^:]+?))(:(.+))?$/;function s(e){return"window"==e?window:"document"==e?document:void 0}function n(e){return e.replace(/(?:[_-])([a-z0-9])/g,((e,t)=>t.toUpperCase()))}function i(e){return e.charAt(0).toUpperCase()+e.slice(1)}function o(e){return e.replace(/([A-Z])/g,((e,t)=>`-${t.toLowerCase()}`))}const a={a:e=>"click",button:e=>"click",form:e=>"submit",details:e=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:e=>"change",textarea:e=>"input"};function c(e){throw new Error(e)}function h(e){try{return JSON.parse(e)}catch(t){return e}}class l{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){this.willBeInvokedByEvent(e)&&this.invokeWithEvent(e)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}invokeWithEvent(e){const{target:t,currentTarget:r}=e;try{const{params:s}=this.action,n=Object.assign(e,{params:s});this.method.call(this.controller,n),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:r,action:this.methodName})}catch(t){const{identifier:r,controller:s,element:n,index:i}=this,o={identifier:r,controller:s,element:n,index:i,event:e};this.context.handleError(t,`invoking action "${this.action}"`,o)}}willBeInvokedByEvent(e){const t=e.target;return this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class u{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){const r=e;this.elements.has(r)?this.delegate.elementAttributeChanged&&this.matchElement(r)?this.delegate.elementAttributeChanged(r,t):this.removeElement(r):this.matchElement(r)&&this.addElement(r)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const r of this.matchElementsInTree(e))t.call(this,r)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class d{constructor(e,t,r){this.attributeName=t,this.delegate=r,this.elementObserver=new u(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],r=Array.from(e.querySelectorAll(this.selector));return t.concat(r)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}class g{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const r=this.delegate.getStringMapKeyForAttribute(e);if(null!=r){this.stringMap.has(e)||this.stringMapKeyAdded(r,e);const s=this.element.getAttribute(e);if(this.stringMap.get(e)!=s&&this.stringMapValueChanged(s,r,t),null==s){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(r,e,t)}else this.stringMap.set(e,s)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,r){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,r)}stringMapKeyRemoved(e,t,r){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,r)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map((e=>e.name))}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}function m(e,t,r){f(e,t).add(r)}function p(e,t,r){f(e,t).delete(r),b(e,t)}function f(e,t){let r=e.get(t);return r||(r=new Set,e.set(t,r)),r}function b(e,t){const r=e.get(t);null!=r&&0==r.size&&e.delete(t)}class v{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e.concat(Array.from(t))),[])}get size(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e+t.size),0)}add(e,t){m(this.valuesByKey,e,t)}delete(e,t){p(this.valuesByKey,e,t)}has(e,t){const r=this.valuesByKey.get(e);return null!=r&&r.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some((t=>t.has(e)))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter((([t,r])=>r.has(e))).map((([e,t])=>e))}}class y extends v{constructor(){super(),this.keysByValue=new Map}get values(){return Array.from(this.keysByValue.keys())}add(e,t){super.add(e,t),m(this.keysByValue,t,e)}delete(e,t){super.delete(e,t),p(this.keysByValue,t,e)}hasValue(e){return this.keysByValue.has(e)}getKeysForValue(e){const t=this.keysByValue.get(e);return t?Array.from(t):[]}}class A{constructor(e,t,r){this.attributeObserver=new d(e,t,this),this.delegate=r,this.tokensByElement=new v}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,r]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(r)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach((e=>this.tokenMatched(e)))}tokensUnmatched(e){e.forEach((e=>this.tokenUnmatched(e)))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),r=this.readTokensForElement(e),s=function(e,t){const r=Math.max(e.length,t.length);return Array.from({length:r},((r,s)=>[e[s],t[s]]))}(t,r).findIndex((([e,t])=>{return s=t,!((r=e)&&s&&r.index==s.index&&r.content==s.content);var r,s}));return-1==s?[[],[]]:[t.slice(s),r.slice(s)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,r){return e.trim().split(/\s+/).filter((e=>e.length)).map(((e,s)=>({element:t,attributeName:r,content:e,index:s})))}(e.getAttribute(t)||"",e,t)}}class E{constructor(e,t,r){this.tokenListObserver=new A(e,t,this),this.delegate=r,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:r}=this.fetchParseResultForToken(e);r&&(this.fetchValuesByTokenForElement(t).set(e,r),this.delegate.elementMatchedValue(t,r))}tokenUnmatched(e){const{element:t}=e,{value:r}=this.fetchParseResultForToken(e);r&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,r))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class O{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new E(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new l(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach((e=>this.delegate.bindingDisconnected(e))),this.bindingsByAction.clear()}parseValueForToken(e){const t=class{constructor(e,t,r){this.element=e,this.index=t,this.eventTarget=r.eventTarget||e,this.eventName=r.eventName||function(e){const t=e.tagName.toLowerCase();if(t in a)return a[t](e)}(e)||c("missing event name"),this.eventOptions=r.eventOptions||{},this.identifier=r.identifier||c("missing identifier"),this.methodName=r.methodName||c("missing method name")}static forToken(e){return new this(e.element,e.index,function(e){const t=e.trim().match(r)||[];return{eventTarget:s(t[4]),eventName:t[2],eventOptions:t[9]?(n=t[9],n.split(":").reduce(((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)})),{})):{},identifier:t[5],methodName:t[7]};var n}(e.content))}toString(){const e=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}->${this.identifier}#${this.methodName}`}get params(){return this.eventTarget instanceof Element?this.getParamsFromEventTargetAttributes(this.eventTarget):{}}getParamsFromEventTargetAttributes(e){const t={},r=new RegExp(`^data-${this.identifier}-(.+)-param$`);return Array.from(e.attributes).forEach((({name:e,value:s})=>{const i=e.match(r),o=i&&i[1];o&&Object.assign(t,{[n(o)]:h(s)})})),t}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}}.forToken(e);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class w{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new g(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap,this.invokeChangedCallbacksForDefaultValues()}start(){this.stringMapObserver.start()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const r=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,r.writer(this.receiver[e]),r.writer(r.defaultValue))}stringMapValueChanged(e,t,r){const s=this.valueDescriptorNameMap[t];null!==e&&(null===r&&(r=s.writer(s.defaultValue)),this.invokeChangedCallback(t,e,r))}stringMapKeyRemoved(e,t,r){const s=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,s.writer(this.receiver[e]),r):this.invokeChangedCallback(e,s.writer(s.defaultValue),r)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:r,writer:s}of this.valueDescriptors)null==r||this.controller.data.has(e)||this.invokeChangedCallback(t,s(r),void 0)}invokeChangedCallback(e,t,r){const s=`${e}Changed`,n=this.receiver[s];if("function"==typeof n){const s=this.valueDescriptorNameMap[e],i=s.reader(t);let o=r;r&&(o=s.reader(r)),n.call(this.receiver,i,o)}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map((t=>e[t]))}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach((t=>{const r=this.valueDescriptorMap[t];e[r.name]=r})),e}hasValue(e){const t=`has${i(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class k{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new v}start(){this.tokenListObserver||(this.tokenListObserver=new A(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var r;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null===(r=this.tokenListObserver)||void 0===r||r.pause((()=>this.delegate.targetConnected(e,t))))}disconnectTarget(e,t){var r;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null===(r=this.tokenListObserver)||void 0===r||r.pause((()=>this.delegate.targetDisconnected(e,t))))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}class M{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:r,controller:s,element:n}=this;t=Object.assign({identifier:r,controller:s,element:n},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new O(this,this.dispatcher),this.valueObserver=new w(this,this.controller),this.targetObserver=new k(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,r={}){const{identifier:s,controller:n,element:i}=this;r=Object.assign({identifier:s,controller:n,element:i},r),this.application.handleError(e,`Error ${t}`,r)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}invokeControllerMethod(e,...t){const r=this.controller;"function"==typeof r[e]&&r[e](...t)}}function N(e,t){const r=T(e);return Array.from(r.reduce(((e,r)=>(function(e,t){const r=e[t];return Array.isArray(r)?r:[]}(r,t).forEach((t=>e.add(t))),e)),new Set))}function B(e,t){return T(e).reduce(((e,r)=>(e.push(...function(e,t){const r=e[t];return r?Object.keys(r).map((e=>[e,r[e]])):[]}(r,t)),e)),[])}function T(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}function C(e){return function(e,t){const r=x(e),s=function(e,t){return F(t).reduce(((r,s)=>{const n=function(e,t,r){const s=Object.getOwnPropertyDescriptor(e,r);if(!s||!("value"in s)){const e=Object.getOwnPropertyDescriptor(t,r).value;return s&&(e.get=s.get||e.get,e.set=s.set||e.set),e}}(e,t,s);return n&&Object.assign(r,{[s]:n}),r}),{})}(e.prototype,t);return Object.defineProperties(r.prototype,s),r}(e,function(e){return N(e,"blessings").reduce(((t,r)=>{const s=r(e);for(const e in s){const r=t[e]||{};t[e]=Object.assign(r,s[e])}return t}),{})}(e))}const F="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,x=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e((function(){this.a.call(this)}));t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class L{constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:C(e.controllerConstructor)}}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new M(this,e),this.contextsByScope.set(e,t)),t}}class ${constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){const t=this.data.get(this.getDataKey(e))||"";return t.match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class S{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const r=this.getAttributeNameForKey(e);return this.element.setAttribute(r,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${o(e)}`}}class D{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,r){let s=this.warnedKeysByObject.get(e);s||(s=new Set,this.warnedKeysByObject.set(e,s)),s.has(t)||(s.add(t),this.logger.warn(r,e))}}function V(e,t){return`[${e}~="${t}"]`}class K{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)]),[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return V(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map((t=>this.deprecate(t,e)))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return V(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:r}=this,s=this.schema.targetAttribute,n=this.schema.targetAttributeForScope(r);this.guide.warn(e,`target:${t}`,`Please replace ${s}="${r}.${t}" with ${n}="${t}". The ${s} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class j{constructor(e,t,r,s){this.targets=new K(this),this.classes=new $(this),this.data=new S(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=r,this.guide=new D(s)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return V(this.schema.controllerAttribute,this.identifier)}}class I{constructor(e,t,r){this.element=e,this.schema=t,this.delegate=r,this.valueListObserver=new E(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:r}=e,s=this.fetchScopesByIdentifierForElement(t);let n=s.get(r);return n||(n=this.delegate.createScopeForElementAndIdentifier(t,r),s.set(r,n)),n}elementMatchedValue(e,t){const r=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,r),1==r&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const r=this.scopeReferenceCounts.get(t);r&&(this.scopeReferenceCounts.set(t,r-1),1==r&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class R{constructor(e){this.application=e,this.scopeObserver=new I(this.element,this.schema,this),this.scopesByIdentifier=new v,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce(((e,t)=>e.concat(t.contexts)),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new L(this.application,e);this.connectModule(t)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const r=this.modulesByIdentifier.get(t);if(r)return r.contexts.find((t=>t.element==e))}handleError(e,t,r){this.application.handleError(e,t,r)}createScopeForElementAndIdentifier(e,t){return new j(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e);this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.connectContextForScope(t)))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier);this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.disconnectContextForScope(t)))}}const P={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`};class U{constructor(e=document.documentElement,r=P){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,r={})=>{this.debug&&this.logFormattedMessage(e,t,r)},this.element=e,this.schema=r,this.dispatcher=new t(this),this.router=new R(this)}static start(e,t){const r=new U(e,t);return r.start(),r}async start(){await new Promise((e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",(()=>e())):e()})),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){t.shouldLoad&&this.load({identifier:e,controllerConstructor:t})}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>this.router.loadDefinition(e)))}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>this.router.unloadIdentifier(e)))}get controllers(){return this.router.contexts.map((e=>e.controller))}getControllerForElementAndIdentifier(e,t){const r=this.router.getContextForElementAndIdentifier(e,t);return r?r.controller:null}handleError(e,t,r){var s;this.logger.error("%s\n\n%o\n\n%o",t,e,r),null===(s=window.onerror)||void 0===s||s.call(window,t,"",0,0,e)}logFormattedMessage(e,t,r={}){r=Object.assign({application:this},r),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},r)),this.logger.groupEnd()}}function z([e,t]){return function(e,t){const r=`${o(e)}-value`,s=function(e){const t=function(e){const t=W(e.type);if(t){const r=q(e.default);if(t!==r)throw new Error(`Type "${t}" must match the type of the default value. Given default value: "${e.default}" as "${r}"`);return t}}(e),r=q(e),s=W(e),n=t||r||s;if(n)return n;throw new Error(`Unknown value type "${e}"`)}(t);return{type:s,key:r,name:n(r),get defaultValue(){return function(e){const t=W(e);if(t)return J[t];const r=e.default;return void 0!==r?r:e}(t)},get hasCustomDefaultValue(){return void 0!==q(t)},reader:_[s],writer:G[s]||G.default}}(e,t)}function W(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function q(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const J={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},_={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError("Expected array");return t},boolean:e=>!("0"==e||"false"==e),number:e=>Number(e),object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError("Expected object");return t},string:e=>e},G={default:function(e){return`${e}`},array:Z,object:Z};function Z(e){return JSON.stringify(e)}class H{constructor(e){this.context=e}static get shouldLoad(){return!0}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:r={},prefix:s=this.identifier,bubbles:n=!0,cancelable:i=!0}={}){const o=new CustomEvent(s?`${s}:${e}`:e,{detail:r,bubbles:n,cancelable:i});return t.dispatchEvent(o),o}}H.blessings=[function(e){return N(e,"classes").reduce(((e,t)=>{return Object.assign(e,{[`${r=t}Class`]:{get(){const{classes:e}=this;if(e.has(r))return e.get(r);{const t=e.getAttributeName(r);throw new Error(`Missing attribute "${t}"`)}}},[`${r}Classes`]:{get(){return this.classes.getAll(r)}},[`has${i(r)}Class`]:{get(){return this.classes.has(r)}}});var r}),{})},function(e){return N(e,"targets").reduce(((e,t)=>{return Object.assign(e,{[`${r=t}Target`]:{get(){const e=this.targets.find(r);if(e)return e;throw new Error(`Missing target element "${r}" for "${this.identifier}" controller`)}},[`${r}Targets`]:{get(){return this.targets.findAll(r)}},[`has${i(r)}Target`]:{get(){return this.targets.has(r)}}});var r}),{})},function(e){const t=B(e,"values"),r={valueDescriptorMap:{get(){return t.reduce(((e,t)=>{const r=z(t),s=this.data.getAttributeNameForKey(r.key);return Object.assign(e,{[s]:r})}),{})}}};return t.reduce(((e,t)=>Object.assign(e,function(e){const t=z(e),{key:r,name:s,reader:n,writer:o}=t;return{[s]:{get(){const e=this.data.get(r);return null!==e?n(e):t.defaultValue},set(e){void 0===e?this.data.delete(r):this.data.set(r,o(e))}},[`has${i(s)}`]:{get(){return this.data.has(r)||t.hasCustomDefaultValue}}}}(t))),r)}],H.targets=[],H.values={};export{U as Application,d as AttributeObserver,M as Context,H as Controller,u as ElementObserver,y as IndexedMultimap,v as Multimap,g as StringMapObserver,A as TokenListObserver,E as ValueListObserver,m as add,P as defaultSchema,p as del,f as fetch,b as prune};
|
@@ -1,5 +1,11 @@
|
|
1
1
|
// Import and register all your controllers from the importmap under controllers/*
|
2
2
|
|
3
3
|
import { application } from "controllers/application"
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
// Eager load all controllers defined in the import map under controllers/**/*_controller
|
6
|
+
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
|
7
|
+
eagerLoadControllersFrom("controllers", application)
|
8
|
+
|
9
|
+
// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
|
10
|
+
// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
|
11
|
+
// lazyLoadControllersFrom("controllers", application)
|
@@ -12,8 +12,8 @@ append_to_file "app/javascript/application.js", %(import "controllers"\n)
|
|
12
12
|
|
13
13
|
say "Pin Stimulus"
|
14
14
|
append_to_file "config/importmap.rb" do <<-RUBY
|
15
|
-
pin "@hotwired/stimulus", to: "stimulus.js"
|
16
|
-
pin "@hotwired/stimulus-
|
15
|
+
pin "@hotwired/stimulus", to: "stimulus.js", preload: true
|
16
|
+
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
|
17
17
|
pin_all_from "app/javascript/controllers", under: "controllers"
|
18
18
|
RUBY
|
19
19
|
end
|
data/lib/stimulus/version.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stimulus-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Stephenson
|
8
8
|
- Javan Mahkmali
|
9
9
|
- David Heinemeier Hansson
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-11-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: 6.0.0
|
29
|
-
description:
|
29
|
+
description:
|
30
30
|
email: david@loudthinking.com
|
31
31
|
executables: []
|
32
32
|
extensions: []
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- Rakefile
|
38
38
|
- app/assets/javascripts/stimulus-autoloader.js
|
39
39
|
- app/assets/javascripts/stimulus-importmap-autoloader.js
|
40
|
+
- app/assets/javascripts/stimulus-loading.js
|
40
41
|
- app/assets/javascripts/stimulus.js
|
41
42
|
- app/assets/javascripts/stimulus.min.js
|
42
43
|
- lib/generators/stimulus/USAGE
|
@@ -59,7 +60,7 @@ licenses:
|
|
59
60
|
metadata:
|
60
61
|
homepage_uri: https://stimulus.hotwired.dev
|
61
62
|
source_code_uri: https://github.com/hotwired/stimulus-rails
|
62
|
-
post_install_message:
|
63
|
+
post_install_message:
|
63
64
|
rdoc_options: []
|
64
65
|
require_paths:
|
65
66
|
- lib
|
@@ -74,8 +75,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
75
|
- !ruby/object:Gem::Version
|
75
76
|
version: '0'
|
76
77
|
requirements: []
|
77
|
-
rubygems_version: 3.
|
78
|
-
signing_key:
|
78
|
+
rubygems_version: 3.2.22
|
79
|
+
signing_key:
|
79
80
|
specification_version: 4
|
80
81
|
summary: A modest JavaScript framework for the HTML you already have.
|
81
82
|
test_files: []
|