stimulus-rails 0.6.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af74b14f711ea67c26426322da6d6ae36c41db6757a56ae254bad08ccfc2a6b8
4
- data.tar.gz: 2bdbda7a1fd90f0cd964831f88cef4f269c92b560815012eb9875f12b0a0e406
3
+ metadata.gz: 0fa354a81d7e2305ae1f6e333ca31844b04f1bce376b9df1b502574c73725728
4
+ data.tar.gz: 3192954bcd22ebb74c854751646b7089092ed1066a35e778a50bb2384bc0ce30
5
5
  SHA512:
6
- metadata.gz: 56334a9ca151712aec54fb89f8459ade60ae68dee9646e9234ed6b50da3c662d11d0bb890329e27f6ded8d8e1ddc9467cae94447d3f46173a568c0f6ddb7381d
7
- data.tar.gz: f3981eec7f58455483f9f0049b6e1680ff2b808d538d220e872284a2068adb5af70289c1430d89a08042577716527c1e440c20bc0a50a30d6a34b873f51d45c9
6
+ metadata.gz: abde8638a567a585f5ec33a9a194da0e28c3263cabb03ca7a42e6628c91fb636a8ef9218bf82856c30acc502cfbae18d59164758254601275cbe40379be83b1c
7
+ data.tar.gz: 0cd6800704eea7cfaf913b02b460475b2e6e8b3e20ec28c0db28cf3e10effd9d8f60fec42442a5b28d1e91f2966e59a6cd14bed5c0f3a279a5cc0a6ef22897ca
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 the asset pipeline and ES6/ESM in the browser. 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!
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 node, yarn will add the dependencies to your `package.json` file.
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
- 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.
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
- With an import-mapped application, controllers are automatically pinned and registered based on the file structure. With a node application, controllers need to be imported and registered directly in the index.js file, but this is 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.
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,5 +1,6 @@
1
1
  //= link ./stimulus-autoloader.js
2
2
  //= link ./stimulus-importmap-autoloader.js
3
+ //= link ./stimulus-loading.js
3
4
 
4
5
  /*
5
6
  Stimulus 3.0.1
@@ -1,8 +1,5 @@
1
1
  //= link ./stimulus-autoloader.js
2
2
  //= link ./stimulus-importmap-autoloader.js
3
-
4
- /*
5
- Stimulus 3.0.1
6
- Copyright © 2021 Basecamp, LLC
7
- */
3
+ //= link ./stimulus-loading.js
8
4
  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};
5
+ //# sourceMappingURL=stimulus.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stimulus.min.js","sources":["../src/core/event_listener.ts","../src/core/dispatcher.ts","../src/core/action_descriptor.ts","../src/core/string_helpers.ts","../src/core/action.ts","../src/core/binding.ts","../src/mutation-observers/element_observer.ts","../src/mutation-observers/attribute_observer.ts","../src/mutation-observers/string_map_observer.ts","../src/multimap/set_operations.ts","../src/multimap/multimap.ts","../src/multimap/indexed_multimap.ts","../src/mutation-observers/token_list_observer.ts","../src/mutation-observers/value_list_observer.ts","../src/core/binding_observer.ts","../src/core/value_observer.ts","../src/core/target_observer.ts","../src/core/context.ts","../src/core/inheritable_statics.ts","../src/core/blessing.ts","../src/core/module.ts","../src/core/definition.ts","../src/core/class_map.ts","../src/core/data_map.ts","../src/core/guide.ts","../src/core/selectors.ts","../src/core/target_set.ts","../src/core/scope.ts","../src/core/scope_observer.ts","../src/core/router.ts","../src/core/schema.ts","../src/core/application.ts","../src/core/value_properties.ts","../src/core/controller.ts","../src/core/class_properties.ts","../src/core/target_properties.ts"],"sourcesContent":["import { Binding } from \"./binding\"\n\nexport class EventListener implements EventListenerObject {\n readonly eventTarget: EventTarget\n readonly eventName: string\n readonly eventOptions: AddEventListenerOptions\n private unorderedBindings: Set<Binding>\n\n constructor(eventTarget: EventTarget, eventName: string, eventOptions: AddEventListenerOptions) {\n this.eventTarget = eventTarget\n this.eventName = eventName\n this.eventOptions = eventOptions\n this.unorderedBindings = new Set()\n }\n\n connect() {\n this.eventTarget.addEventListener(this.eventName, this, this.eventOptions)\n }\n\n disconnect() {\n this.eventTarget.removeEventListener(this.eventName, this, this.eventOptions)\n }\n\n // Binding observer delegate\n\n bindingConnected(binding: Binding) {\n this.unorderedBindings.add(binding)\n }\n\n bindingDisconnected(binding: Binding) {\n this.unorderedBindings.delete(binding)\n }\n\n handleEvent(event: Event) {\n // FIXME: Determine why TS won't recognize that the extended event has immediatePropagationStopped\n const extendedEvent = extendEvent(event) as any\n for (const binding of this.bindings) {\n if (extendedEvent.immediatePropagationStopped) {\n break\n } else {\n binding.handleEvent(extendedEvent)\n }\n }\n }\n\n get bindings(): Binding[] {\n return Array.from(this.unorderedBindings).sort((left, right) => {\n const leftIndex = left.index, rightIndex = right.index\n return leftIndex < rightIndex ? -1 : leftIndex > rightIndex ? 1 : 0\n })\n }\n\n}\n\nfunction extendEvent(event: Event) {\n if (\"immediatePropagationStopped\" in event) {\n return event\n } else {\n const { stopImmediatePropagation } = event\n return Object.assign(event, {\n immediatePropagationStopped: false,\n stopImmediatePropagation() {\n this.immediatePropagationStopped = true\n stopImmediatePropagation.call(this)\n }\n })\n }\n}\n","import { Application } from \"./application\"\nimport { Binding } from \"./binding\"\nimport { BindingObserverDelegate } from \"./binding_observer\"\nimport { EventListener } from \"./event_listener\"\n\nexport class Dispatcher implements BindingObserverDelegate {\n readonly application: Application\n private eventListenerMaps: Map<EventTarget, Map<string, EventListener>>\n private started: boolean\n\n constructor(application: Application) {\n this.application = application\n this.eventListenerMaps = new Map\n this.started = false\n }\n\n start() {\n if (!this.started) {\n this.started = true\n this.eventListeners.forEach(eventListener => eventListener.connect())\n }\n }\n\n stop() {\n if (this.started) {\n this.started = false\n this.eventListeners.forEach(eventListener => eventListener.disconnect())\n }\n }\n\n get eventListeners(): EventListener[] {\n return Array.from(this.eventListenerMaps.values())\n .reduce((listeners, map) => listeners.concat(Array.from(map.values())), [] as EventListener[])\n }\n\n // Binding observer delegate\n\n bindingConnected(binding: Binding) {\n this.fetchEventListenerForBinding(binding).bindingConnected(binding)\n }\n\n bindingDisconnected(binding: Binding) {\n this.fetchEventListenerForBinding(binding).bindingDisconnected(binding)\n }\n\n // Error handling\n\n handleError(error: Error, message: string, detail: object = {}) {\n this.application.handleError(error, `Error ${message}`, detail)\n }\n\n private fetchEventListenerForBinding(binding: Binding): EventListener {\n const { eventTarget, eventName, eventOptions } = binding\n return this.fetchEventListener(eventTarget, eventName, eventOptions)\n }\n\n private fetchEventListener(eventTarget: EventTarget, eventName: string, eventOptions: AddEventListenerOptions): EventListener {\n const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget)\n const cacheKey = this.cacheKey(eventName, eventOptions)\n let eventListener = eventListenerMap.get(cacheKey)\n if (!eventListener) {\n eventListener = this.createEventListener(eventTarget, eventName, eventOptions)\n eventListenerMap.set(cacheKey, eventListener)\n }\n return eventListener\n }\n\n private createEventListener(eventTarget: EventTarget, eventName: string, eventOptions: AddEventListenerOptions): EventListener {\n const eventListener = new EventListener(eventTarget, eventName, eventOptions)\n if (this.started) {\n eventListener.connect()\n }\n return eventListener\n }\n\n private fetchEventListenerMapForEventTarget(eventTarget: EventTarget): Map<string, EventListener> {\n let eventListenerMap = this.eventListenerMaps.get(eventTarget)\n if (!eventListenerMap) {\n eventListenerMap = new Map\n this.eventListenerMaps.set(eventTarget, eventListenerMap)\n }\n return eventListenerMap\n }\n\n private cacheKey(eventName: string, eventOptions: any): string {\n const parts = [ eventName ]\n Object.keys(eventOptions).sort().forEach(key => {\n parts.push(`${eventOptions[key] ? \"\" : \"!\"}${key}`)\n })\n return parts.join(\":\")\n }\n}\n","export interface ActionDescriptor {\n eventTarget: EventTarget\n eventOptions: AddEventListenerOptions\n eventName: string\n identifier: string\n methodName: string\n}\n\n// capture nos.: 12 23 4 43 1 5 56 7 768 9 98\nconst descriptorPattern = /^((.+?)(@(window|document))?->)?(.+?)(#([^:]+?))(:(.+))?$/\n\nexport function parseActionDescriptorString(descriptorString: string): Partial<ActionDescriptor> {\n const source = descriptorString.trim()\n const matches = source.match(descriptorPattern) || []\n return {\n eventTarget: parseEventTarget(matches[4]),\n eventName: matches[2],\n eventOptions: matches[9] ? parseEventOptions(matches[9]) : {},\n identifier: matches[5],\n methodName: matches[7]\n }\n}\n\nfunction parseEventTarget(eventTargetName: string): EventTarget | undefined {\n if (eventTargetName == \"window\") {\n return window\n } else if (eventTargetName == \"document\") {\n return document\n }\n}\n\nfunction parseEventOptions(eventOptions: string): AddEventListenerOptions {\n return eventOptions.split(\":\").reduce((options, token) =>\n Object.assign(options, { [token.replace(/^!/, \"\")]: !/^!/.test(token) })\n , {})\n}\n\nexport function stringifyEventTarget(eventTarget: EventTarget) {\n if (eventTarget == window) {\n return \"window\"\n } else if (eventTarget == document) {\n return \"document\"\n }\n}\n","export function camelize(value: string) {\n return value.replace(/(?:[_-])([a-z0-9])/g, (_, char) => char.toUpperCase())\n}\n\nexport function capitalize(value: string) {\n return value.charAt(0).toUpperCase() + value.slice(1)\n}\n\nexport function dasherize(value: string) {\n return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`)\n}\n\nexport function tokenize(value: string) {\n return value.match(/[^\\s]+/g) || []\n}\n","import { ActionDescriptor, parseActionDescriptorString, stringifyEventTarget } from \"./action_descriptor\"\nimport { Token } from \"../mutation-observers\"\nimport { camelize } from \"./string_helpers\"\n\nexport class Action {\n readonly element: Element\n readonly index: number\n readonly eventTarget: EventTarget\n readonly eventName: string\n readonly eventOptions: AddEventListenerOptions\n readonly identifier: string\n readonly methodName: string\n\n static forToken(token: Token) {\n return new this(token.element, token.index, parseActionDescriptorString(token.content))\n }\n\n constructor(element: Element, index: number, descriptor: Partial<ActionDescriptor>) {\n this.element = element\n this.index = index\n this.eventTarget = descriptor.eventTarget || element\n this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error(\"missing event name\")\n this.eventOptions = descriptor.eventOptions || {}\n this.identifier = descriptor.identifier || error(\"missing identifier\")\n this.methodName = descriptor.methodName || error(\"missing method name\")\n }\n\n toString() {\n const eventNameSuffix = this.eventTargetName ? `@${this.eventTargetName}` : \"\"\n return `${this.eventName}${eventNameSuffix}->${this.identifier}#${this.methodName}`\n }\n\n get params(): object {\n if (this.eventTarget instanceof Element) {\n return this.getParamsFromEventTargetAttributes(this.eventTarget)\n } else {\n return {}\n }\n }\n\n private getParamsFromEventTargetAttributes(eventTarget: Element): {[key: string]: any} {\n const params = {}\n const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`)\n const attributes = Array.from(eventTarget.attributes)\n\n attributes.forEach(({ name, value }: { name: string, value: string }) => {\n const match = name.match(pattern)\n const key = match && match[1]\n if (key) {\n Object.assign(params, { [camelize(key)]: typecast(value) })\n }\n })\n return params\n }\n\n private get eventTargetName() {\n return stringifyEventTarget(this.eventTarget)\n }\n}\n\nconst defaultEventNames: { [tagName: string]: (element: Element) => string } = {\n \"a\": e => \"click\",\n \"button\": e => \"click\",\n \"form\": e => \"submit\",\n \"details\": e => \"toggle\",\n \"input\": e => e.getAttribute(\"type\") == \"submit\" ? \"click\" : \"input\",\n \"select\": e => \"change\",\n \"textarea\": e => \"input\"\n}\n\nexport function getDefaultEventNameForElement(element: Element): string | undefined {\n const tagName = element.tagName.toLowerCase()\n if (tagName in defaultEventNames) {\n return defaultEventNames[tagName](element)\n }\n}\n\nfunction error(message: string): never {\n throw new Error(message)\n}\n\nfunction typecast(value: any): any {\n try {\n return JSON.parse(value)\n } catch (o_O) {\n return value\n }\n}\n\n","import { Action } from \"./action\"\nimport { ActionEvent } from \"./action_event\"\nimport { Context } from \"./context\"\nimport { Controller } from \"./controller\"\nimport { Scope } from \"./scope\"\n\nexport class Binding {\n readonly context: Context\n readonly action: Action\n\n constructor(context: Context, action: Action) {\n this.context = context\n this.action = action\n }\n\n get index(): number {\n return this.action.index\n }\n\n get eventTarget(): EventTarget {\n return this.action.eventTarget\n }\n\n get eventOptions(): AddEventListenerOptions {\n return this.action.eventOptions\n }\n\n get identifier(): string {\n return this.context.identifier\n }\n\n handleEvent(event: Event) {\n if (this.willBeInvokedByEvent(event)) {\n this.invokeWithEvent(event)\n }\n }\n\n get eventName(): string {\n return this.action.eventName\n }\n\n get method(): Function {\n const method = (this.controller as any)[this.methodName]\n if (typeof method == \"function\") {\n return method\n }\n throw new Error(`Action \"${this.action}\" references undefined method \"${this.methodName}\"`)\n }\n\n private invokeWithEvent(event: Event) {\n const { target, currentTarget } = event\n try {\n const { params } = this.action\n const actionEvent: ActionEvent = Object.assign(event, { params })\n this.method.call(this.controller, actionEvent)\n this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName })\n } catch (error) {\n const { identifier, controller, element, index } = this\n const detail = { identifier, controller, element, index, event }\n this.context.handleError(error, `invoking action \"${this.action}\"`, detail)\n }\n }\n\n private willBeInvokedByEvent(event: Event): boolean {\n const eventTarget = event.target\n if (this.element === eventTarget) {\n return true\n } else if (eventTarget instanceof Element && this.element.contains(eventTarget)) {\n return this.scope.containsElement(eventTarget)\n } else {\n return this.scope.containsElement(this.action.element)\n }\n }\n\n private get controller(): Controller {\n return this.context.controller\n }\n\n private get methodName(): string {\n return this.action.methodName\n }\n\n private get element(): Element {\n return this.scope.element\n }\n\n private get scope(): Scope {\n return this.context.scope\n }\n}\n","export interface ElementObserverDelegate {\n matchElement(element: Element): boolean\n matchElementsInTree(tree: Element): Element[]\n\n elementMatched?(element: Element): void\n elementUnmatched?(element: Element): void\n elementAttributeChanged?(element: Element, attributeName: string): void\n}\n\nexport class ElementObserver {\n element: Element\n started: boolean\n private delegate: ElementObserverDelegate\n\n private elements: Set<Element>\n private mutationObserver: MutationObserver\n private mutationObserverInit = { attributes: true, childList: true, subtree: true }\n\n constructor(element: Element, delegate: ElementObserverDelegate) {\n this.element = element\n this.started = false\n this.delegate = delegate\n\n this.elements = new Set\n this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations))\n }\n\n start() {\n if (!this.started) {\n this.started = true\n this.mutationObserver.observe(this.element, this.mutationObserverInit)\n this.refresh()\n }\n }\n\n pause(callback: () => void) {\n if (this.started) {\n this.mutationObserver.disconnect()\n this.started = false\n }\n\n callback()\n\n if (!this.started) {\n this.mutationObserver.observe(this.element, this.mutationObserverInit)\n this.started = true\n }\n }\n\n stop() {\n if (this.started) {\n this.mutationObserver.takeRecords()\n this.mutationObserver.disconnect()\n this.started = false\n }\n }\n\n refresh() {\n if (this.started) {\n const matches = new Set(this.matchElementsInTree())\n\n for (const element of Array.from(this.elements)) {\n if (!matches.has(element)) {\n this.removeElement(element)\n }\n }\n\n for (const element of Array.from(matches)) {\n this.addElement(element)\n }\n }\n }\n\n // Mutation record processing\n\n private processMutations(mutations: MutationRecord[]) {\n if (this.started) {\n for (const mutation of mutations) {\n this.processMutation(mutation)\n }\n }\n }\n\n private processMutation(mutation: MutationRecord) {\n if (mutation.type == \"attributes\") {\n this.processAttributeChange(mutation.target, mutation.attributeName!)\n } else if (mutation.type == \"childList\") {\n this.processRemovedNodes(mutation.removedNodes)\n this.processAddedNodes(mutation.addedNodes)\n }\n }\n\n private processAttributeChange(node: Node, attributeName: string) {\n const element = node as Element\n if (this.elements.has(element)) {\n if (this.delegate.elementAttributeChanged && this.matchElement(element)) {\n this.delegate.elementAttributeChanged(element, attributeName)\n } else {\n this.removeElement(element)\n }\n } else if (this.matchElement(element)) {\n this.addElement(element)\n }\n }\n\n private processRemovedNodes(nodes: NodeList) {\n for (const node of Array.from(nodes)) {\n const element = this.elementFromNode(node)\n if (element) {\n this.processTree(element, this.removeElement)\n }\n }\n }\n\n private processAddedNodes(nodes: NodeList) {\n for (const node of Array.from(nodes)) {\n const element = this.elementFromNode(node)\n if (element && this.elementIsActive(element)) {\n this.processTree(element, this.addElement)\n }\n }\n }\n\n // Element matching\n\n private matchElement(element: Element): boolean {\n return this.delegate.matchElement(element)\n }\n\n private matchElementsInTree(tree: Element = this.element): Element[] {\n return this.delegate.matchElementsInTree(tree)\n }\n\n private processTree(tree: Element, processor: (element: Element) => void) {\n for (const element of this.matchElementsInTree(tree)) {\n processor.call(this, element)\n }\n }\n\n private elementFromNode(node: Node): Element | undefined {\n if (node.nodeType == Node.ELEMENT_NODE) {\n return node as Element\n }\n }\n\n private elementIsActive(element: Element): boolean {\n if (element.isConnected != this.element.isConnected) {\n return false\n } else {\n return this.element.contains(element)\n }\n }\n\n // Element tracking\n\n private addElement(element: Element) {\n if (!this.elements.has(element)) {\n if (this.elementIsActive(element)) {\n this.elements.add(element)\n if (this.delegate.elementMatched) {\n this.delegate.elementMatched(element)\n }\n }\n }\n }\n\n private removeElement(element: Element) {\n if (this.elements.has(element)) {\n this.elements.delete(element)\n if (this.delegate.elementUnmatched) {\n this.delegate.elementUnmatched(element)\n }\n }\n }\n}\n","import { ElementObserver, ElementObserverDelegate } from \"./element_observer\"\n\nexport interface AttributeObserverDelegate {\n elementMatchedAttribute?(element: Element, attributeName: string): void\n elementAttributeValueChanged?(element: Element, attributeName: string): void\n elementUnmatchedAttribute?(element: Element, attributeName: string): void\n}\n\nexport class AttributeObserver implements ElementObserverDelegate {\n attributeName: string\n private delegate: AttributeObserverDelegate\n\n private elementObserver: ElementObserver\n\n constructor(element: Element, attributeName: string, delegate: AttributeObserverDelegate) {\n this.attributeName = attributeName\n this.delegate = delegate\n\n this.elementObserver = new ElementObserver(element, this)\n }\n\n get element(): Element {\n return this.elementObserver.element\n }\n\n get selector(): string {\n return `[${this.attributeName}]`\n }\n\n start() {\n this.elementObserver.start()\n }\n\n pause(callback: () => void) {\n this.elementObserver.pause(callback)\n }\n\n stop() {\n this.elementObserver.stop()\n }\n\n refresh() {\n this.elementObserver.refresh()\n }\n\n get started(): boolean {\n return this.elementObserver.started\n }\n\n // Element observer delegate\n\n matchElement(element: Element): boolean {\n return element.hasAttribute(this.attributeName)\n }\n\n matchElementsInTree(tree: Element): Element[] {\n const match = this.matchElement(tree) ? [tree] : []\n const matches = Array.from(tree.querySelectorAll(this.selector))\n return match.concat(matches)\n }\n\n elementMatched(element: Element) {\n if (this.delegate.elementMatchedAttribute) {\n this.delegate.elementMatchedAttribute(element, this.attributeName)\n }\n }\n\n elementUnmatched(element: Element) {\n if (this.delegate.elementUnmatchedAttribute) {\n this.delegate.elementUnmatchedAttribute(element, this.attributeName)\n }\n }\n\n elementAttributeChanged(element: Element, attributeName: string) {\n if (this.delegate.elementAttributeValueChanged && this.attributeName == attributeName) {\n this.delegate.elementAttributeValueChanged(element, attributeName)\n }\n }\n}\n","export interface StringMapObserverDelegate {\n getStringMapKeyForAttribute(attributeName: string): string | undefined\n stringMapKeyAdded?(key: string, attributeName: string): void\n stringMapValueChanged?(value: string | null, key: string, oldValue: string | null): void\n stringMapKeyRemoved?(key: string, attributeName: string, oldValue: string | null): void\n}\n\nexport class StringMapObserver {\n readonly element: Element\n readonly delegate: StringMapObserverDelegate\n private started: boolean\n private stringMap: Map<string, string>\n private mutationObserver: MutationObserver\n\n constructor(element: Element, delegate: StringMapObserverDelegate) {\n this.element = element\n this.delegate = delegate\n this.started = false\n this.stringMap = new Map\n this.mutationObserver = new MutationObserver(mutations => this.processMutations(mutations))\n }\n\n start() {\n if (!this.started) {\n this.started = true\n this.mutationObserver.observe(this.element, { attributes: true, attributeOldValue: true })\n this.refresh()\n }\n }\n\n stop() {\n if (this.started) {\n this.mutationObserver.takeRecords()\n this.mutationObserver.disconnect()\n this.started = false\n }\n }\n\n refresh() {\n if (this.started) {\n for (const attributeName of this.knownAttributeNames) {\n this.refreshAttribute(attributeName, null)\n }\n }\n }\n\n // Mutation record processing\n\n private processMutations(mutations: MutationRecord[]) {\n if (this.started) {\n for (const mutation of mutations) {\n this.processMutation(mutation)\n }\n }\n }\n\n private processMutation(mutation: MutationRecord) {\n const attributeName = mutation.attributeName\n if (attributeName) {\n this.refreshAttribute(attributeName, mutation.oldValue)\n }\n }\n\n // State tracking\n\n private refreshAttribute(attributeName: string, oldValue: string | null) {\n const key = this.delegate.getStringMapKeyForAttribute(attributeName)\n if (key != null) {\n if (!this.stringMap.has(attributeName)) {\n this.stringMapKeyAdded(key, attributeName)\n }\n\n const value = this.element.getAttribute(attributeName)\n if (this.stringMap.get(attributeName) != value) {\n this.stringMapValueChanged(value, key, oldValue)\n }\n\n if (value == null) {\n const oldValue = this.stringMap.get(attributeName)\n this.stringMap.delete(attributeName)\n if (oldValue) this.stringMapKeyRemoved(key, attributeName, oldValue)\n } else {\n this.stringMap.set(attributeName, value)\n }\n }\n }\n\n private stringMapKeyAdded(key: string, attributeName: string) {\n if (this.delegate.stringMapKeyAdded) {\n this.delegate.stringMapKeyAdded(key, attributeName)\n }\n }\n\n private stringMapValueChanged(value: string | null, key: string, oldValue: string | null) {\n if (this.delegate.stringMapValueChanged) {\n this.delegate.stringMapValueChanged(value, key, oldValue)\n }\n }\n\n private stringMapKeyRemoved(key: string, attributeName: string, oldValue: string | null) {\n if (this.delegate.stringMapKeyRemoved) {\n this.delegate.stringMapKeyRemoved(key, attributeName, oldValue)\n }\n }\n\n private get knownAttributeNames() {\n return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))\n }\n\n private get currentAttributeNames() {\n return Array.from(this.element.attributes).map(attribute => attribute.name)\n }\n\n private get recordedAttributeNames() {\n return Array.from(this.stringMap.keys())\n }\n}\n","export function add<K, V>(map: Map<K, Set<V>>, key: K, value: V) {\n fetch(map, key).add(value)\n}\n\nexport function del<K, V>(map: Map<K, Set<V>>, key: K, value: V) {\n fetch(map, key).delete(value)\n prune(map, key)\n}\n\nexport function fetch<K, V>(map: Map<K, Set<V>>, key: K): Set<V> {\n let values = map.get(key)\n if (!values) {\n values = new Set()\n map.set(key, values)\n }\n return values\n}\n\nexport function prune<K, V>(map: Map<K, Set<V>>, key: K) {\n const values = map.get(key)\n if (values != null && values.size == 0) {\n map.delete(key)\n }\n}\n","import { add, del } from \"./set_operations\"\n\nexport class Multimap<K, V> {\n private valuesByKey: Map<K, Set<V>>\n\n constructor() {\n this.valuesByKey = new Map<K, Set<V>>()\n }\n\n get keys() {\n return Array.from(this.valuesByKey.keys())\n }\n\n get values(): V[] {\n const sets = Array.from(this.valuesByKey.values())\n return sets.reduce((values, set) => values.concat(Array.from(set)), <V[]> [])\n }\n\n get size(): number {\n const sets = Array.from(this.valuesByKey.values())\n return sets.reduce((size, set) => size + set.size, 0)\n }\n\n add(key: K, value: V) {\n add(this.valuesByKey, key, value)\n }\n\n delete(key: K, value: V) {\n del(this.valuesByKey, key, value)\n }\n\n has(key: K, value: V): boolean {\n const values = this.valuesByKey.get(key)\n return values != null && values.has(value)\n }\n\n hasKey(key: K): boolean {\n return this.valuesByKey.has(key)\n }\n\n hasValue(value: V): boolean {\n const sets = Array.from(this.valuesByKey.values())\n return sets.some(set => set.has(value))\n }\n\n getValuesForKey(key: K): V[] {\n const values = this.valuesByKey.get(key)\n return values ? Array.from(values) : []\n }\n\n getKeysForValue(value: V): K[] {\n return Array.from(this.valuesByKey)\n .filter(([key, values]) => values.has(value))\n .map(([key, values]) => key)\n }\n}\n","import { Multimap } from \"./multimap\"\nimport { add, del } from \"./set_operations\"\n\nexport class IndexedMultimap<K, V> extends Multimap<K, V> {\n private keysByValue: Map<V, Set<K>>\n\n constructor() {\n super()\n this.keysByValue = new Map\n }\n\n get values(): V[] {\n return Array.from(this.keysByValue.keys())\n }\n\n add(key: K, value: V) {\n super.add(key, value)\n add(this.keysByValue, value, key)\n }\n\n delete(key: K, value: V) {\n super.delete(key, value)\n del(this.keysByValue, value, key)\n }\n\n hasValue(value: V): boolean {\n return this.keysByValue.has(value)\n }\n\n getKeysForValue(value: V): K[] {\n const set = this.keysByValue.get(value)\n return set ? Array.from(set) : []\n }\n}\n","import { AttributeObserver, AttributeObserverDelegate } from \"./attribute_observer\"\nimport { Multimap } from \"../multimap\"\n\nexport interface Token {\n element: Element\n attributeName: string\n index: number\n content: string\n}\n\nexport interface TokenListObserverDelegate {\n tokenMatched(token: Token): void\n tokenUnmatched(token: Token): void\n}\n\nexport class TokenListObserver implements AttributeObserverDelegate {\n private attributeObserver: AttributeObserver\n private delegate: TokenListObserverDelegate\n private tokensByElement: Multimap<Element, Token>\n\n constructor(element: Element, attributeName: string, delegate: TokenListObserverDelegate) {\n this.attributeObserver = new AttributeObserver(element, attributeName, this)\n this.delegate = delegate\n this.tokensByElement = new Multimap\n }\n\n get started(): boolean {\n return this.attributeObserver.started\n }\n\n start() {\n this.attributeObserver.start()\n }\n\n pause(callback: () => void) {\n this.attributeObserver.pause(callback)\n }\n\n stop() {\n this.attributeObserver.stop()\n }\n\n refresh() {\n this.attributeObserver.refresh()\n }\n\n get element(): Element {\n return this.attributeObserver.element\n }\n\n get attributeName(): string {\n return this.attributeObserver.attributeName\n }\n\n // Attribute observer delegate\n\n elementMatchedAttribute(element: Element) {\n this.tokensMatched(this.readTokensForElement(element))\n }\n\n elementAttributeValueChanged(element: Element) {\n const [unmatchedTokens, matchedTokens] = this.refreshTokensForElement(element)\n this.tokensUnmatched(unmatchedTokens)\n this.tokensMatched(matchedTokens)\n }\n\n elementUnmatchedAttribute(element: Element) {\n this.tokensUnmatched(this.tokensByElement.getValuesForKey(element))\n }\n\n private tokensMatched(tokens: Token[]) {\n tokens.forEach(token => this.tokenMatched(token))\n }\n\n private tokensUnmatched(tokens: Token[]) {\n tokens.forEach(token => this.tokenUnmatched(token))\n }\n\n private tokenMatched(token: Token) {\n this.delegate.tokenMatched(token)\n this.tokensByElement.add(token.element, token)\n }\n\n private tokenUnmatched(token: Token) {\n this.delegate.tokenUnmatched(token)\n this.tokensByElement.delete(token.element, token)\n }\n\n private refreshTokensForElement(element: Element): [Token[], Token[]] {\n const previousTokens = this.tokensByElement.getValuesForKey(element)\n const currentTokens = this.readTokensForElement(element)\n const firstDifferingIndex = zip(previousTokens, currentTokens)\n .findIndex(([previousToken, currentToken]) => !tokensAreEqual(previousToken, currentToken))\n\n if (firstDifferingIndex == -1) {\n return [[], []]\n } else {\n return [previousTokens.slice(firstDifferingIndex), currentTokens.slice(firstDifferingIndex)]\n }\n }\n\n private readTokensForElement(element: Element): Token[] {\n const attributeName = this.attributeName\n const tokenString = element.getAttribute(attributeName) || \"\"\n return parseTokenString(tokenString, element, attributeName)\n }\n}\n\nfunction parseTokenString(tokenString: string, element: Element, attributeName: string): Token[] {\n return tokenString.trim().split(/\\s+/).filter(content => content.length)\n .map((content, index) => ({ element, attributeName, content, index }))\n}\n\nfunction zip<L, R>(left: L[], right: R[]): [L | undefined, R | undefined][] {\n const length = Math.max(left.length, right.length)\n return Array.from({ length }, (_, index) => [left[index], right[index]] as [L, R])\n}\n\nfunction tokensAreEqual(left?: Token, right?: Token) {\n return left && right && left.index == right.index && left.content == right.content\n}\n","import { Token, TokenListObserver, TokenListObserverDelegate } from \"./token_list_observer\"\n\nexport interface ValueListObserverDelegate<T> {\n parseValueForToken(token: Token): T | undefined\n elementMatchedValue(element: Element, value: T): void\n elementUnmatchedValue(element: Element, value: T): void\n}\n\ninterface ParseResult<T> {\n value?: T\n error?: Error\n}\n\nexport class ValueListObserver<T> implements TokenListObserverDelegate {\n private tokenListObserver: TokenListObserver\n private delegate: ValueListObserverDelegate<T>\n private parseResultsByToken: WeakMap<Token, ParseResult<T>>\n private valuesByTokenByElement: WeakMap<Element, Map<Token, T>>\n\n constructor(element: Element, attributeName: string, delegate: ValueListObserverDelegate<T>) {\n this.tokenListObserver = new TokenListObserver(element, attributeName, this)\n this.delegate = delegate\n this.parseResultsByToken = new WeakMap\n this.valuesByTokenByElement = new WeakMap\n }\n\n get started(): boolean {\n return this.tokenListObserver.started\n }\n\n start() {\n this.tokenListObserver.start()\n }\n\n stop() {\n this.tokenListObserver.stop()\n }\n\n refresh() {\n this.tokenListObserver.refresh()\n }\n\n get element(): Element {\n return this.tokenListObserver.element\n }\n\n get attributeName(): string {\n return this.tokenListObserver.attributeName\n }\n\n tokenMatched(token: Token) {\n const { element } = token\n const { value } = this.fetchParseResultForToken(token)\n if (value) {\n this.fetchValuesByTokenForElement(element).set(token, value)\n this.delegate.elementMatchedValue(element, value)\n }\n }\n\n tokenUnmatched(token: Token) {\n const { element } = token\n const { value } = this.fetchParseResultForToken(token)\n if (value) {\n this.fetchValuesByTokenForElement(element).delete(token)\n this.delegate.elementUnmatchedValue(element, value)\n }\n }\n\n private fetchParseResultForToken(token: Token) {\n let parseResult = this.parseResultsByToken.get(token)\n if (!parseResult) {\n parseResult = this.parseToken(token)\n this.parseResultsByToken.set(token, parseResult)\n }\n return parseResult\n }\n\n private fetchValuesByTokenForElement(element: Element) {\n let valuesByToken = this.valuesByTokenByElement.get(element)\n if (!valuesByToken) {\n valuesByToken = new Map\n this.valuesByTokenByElement.set(element, valuesByToken)\n }\n return valuesByToken\n }\n\n private parseToken(token: Token): ParseResult<T> {\n try {\n const value = this.delegate.parseValueForToken(token)\n return { value }\n } catch (error) {\n return { error }\n }\n }\n}\n","import { Action } from \"./action\"\nimport { Binding } from \"./binding\"\nimport { Context } from \"./context\"\nimport { ErrorHandler } from \"./error_handler\"\nimport { Schema } from \"./schema\"\nimport { Token, ValueListObserver, ValueListObserverDelegate } from \"../mutation-observers\"\n\nexport interface BindingObserverDelegate extends ErrorHandler {\n bindingConnected(binding: Binding): void\n bindingDisconnected(binding: Binding): void\n}\n\nexport class BindingObserver implements ValueListObserverDelegate<Action> {\n readonly context: Context\n private delegate: BindingObserverDelegate\n private valueListObserver?: ValueListObserver<Action>\n private bindingsByAction: Map<Action, Binding>\n\n constructor(context: Context, delegate: BindingObserverDelegate) {\n this.context = context\n this.delegate = delegate\n this.bindingsByAction = new Map\n }\n\n start() {\n if (!this.valueListObserver) {\n this.valueListObserver = new ValueListObserver(this.element, this.actionAttribute, this)\n this.valueListObserver.start()\n }\n }\n\n stop() {\n if (this.valueListObserver) {\n this.valueListObserver.stop()\n delete this.valueListObserver\n this.disconnectAllActions()\n }\n }\n\n get element() {\n return this.context.element\n }\n\n get identifier() {\n return this.context.identifier\n }\n\n get actionAttribute() {\n return this.schema.actionAttribute\n }\n\n get schema(): Schema {\n return this.context.schema\n }\n\n get bindings(): Binding[] {\n return Array.from(this.bindingsByAction.values())\n }\n\n private connectAction(action: Action) {\n const binding = new Binding(this.context, action)\n this.bindingsByAction.set(action, binding)\n this.delegate.bindingConnected(binding)\n }\n\n private disconnectAction(action: Action) {\n const binding = this.bindingsByAction.get(action)\n if (binding) {\n this.bindingsByAction.delete(action)\n this.delegate.bindingDisconnected(binding)\n }\n }\n\n private disconnectAllActions() {\n this.bindings.forEach(binding => this.delegate.bindingDisconnected(binding))\n this.bindingsByAction.clear()\n }\n\n // Value observer delegate\n\n parseValueForToken(token: Token): Action | undefined {\n const action = Action.forToken(token)\n if (action.identifier == this.identifier) {\n return action\n }\n }\n\n elementMatchedValue(element: Element, action: Action) {\n this.connectAction(action)\n }\n\n elementUnmatchedValue(element: Element, action: Action) {\n this.disconnectAction(action)\n }\n}\n","import { Context } from \"./context\"\nimport { StringMapObserver, StringMapObserverDelegate } from \"../mutation-observers\"\nimport { ValueDescriptor } from \"./value_properties\"\nimport { capitalize } from \"./string_helpers\"\n\nexport class ValueObserver implements StringMapObserverDelegate {\n readonly context: Context\n readonly receiver: any\n private stringMapObserver: StringMapObserver\n private valueDescriptorMap: { [attributeName: string]: ValueDescriptor }\n\n constructor(context: Context, receiver: any) {\n this.context = context\n this.receiver = receiver\n this.stringMapObserver = new StringMapObserver(this.element, this)\n this.valueDescriptorMap = (this.controller as any).valueDescriptorMap\n this.invokeChangedCallbacksForDefaultValues()\n }\n\n start() {\n this.stringMapObserver.start()\n }\n\n stop() {\n this.stringMapObserver.stop()\n }\n\n get element() {\n return this.context.element\n }\n\n get controller() {\n return this.context.controller\n }\n\n // String map observer delegate\n\n getStringMapKeyForAttribute(attributeName: string) {\n if (attributeName in this.valueDescriptorMap) {\n return this.valueDescriptorMap[attributeName].name\n }\n }\n\n stringMapKeyAdded(key: string, attributeName: string) {\n const descriptor = this.valueDescriptorMap[attributeName]\n\n if (!this.hasValue(key)) {\n this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), descriptor.writer(descriptor.defaultValue))\n }\n }\n\n stringMapValueChanged(value: string, name: string, oldValue: string) {\n const descriptor = this.valueDescriptorNameMap[name]\n\n if (value === null) return\n\n if (oldValue === null) {\n oldValue = descriptor.writer(descriptor.defaultValue)\n }\n\n this.invokeChangedCallback(name, value, oldValue)\n }\n\n stringMapKeyRemoved(key: string, attributeName: string, oldValue: string) {\n const descriptor = this.valueDescriptorNameMap[key]\n\n if (this.hasValue(key)) {\n this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), oldValue)\n } else {\n this.invokeChangedCallback(key, descriptor.writer(descriptor.defaultValue), oldValue)\n }\n }\n\n private invokeChangedCallbacksForDefaultValues() {\n for (const { key, name, defaultValue, writer } of this.valueDescriptors) {\n if (defaultValue != undefined && !this.controller.data.has(key)) {\n this.invokeChangedCallback(name, writer(defaultValue), undefined)\n }\n }\n }\n\n private invokeChangedCallback(name: string, rawValue: string, rawOldValue: string | undefined) {\n const changedMethodName = `${name}Changed`\n const changedMethod = this.receiver[changedMethodName]\n\n if (typeof changedMethod == \"function\") {\n const descriptor = this.valueDescriptorNameMap[name]\n const value = descriptor.reader(rawValue)\n let oldValue = rawOldValue\n\n if (rawOldValue) {\n oldValue = descriptor.reader(rawOldValue)\n }\n\n changedMethod.call(this.receiver, value, oldValue)\n }\n }\n\n private get valueDescriptors() {\n const { valueDescriptorMap } = this\n return Object.keys(valueDescriptorMap).map(key => valueDescriptorMap[key])\n }\n\n private get valueDescriptorNameMap() {\n const descriptors: { [type: string]: ValueDescriptor } = {}\n\n Object.keys(this.valueDescriptorMap).forEach(key => {\n const descriptor = this.valueDescriptorMap[key]\n descriptors[descriptor.name] = descriptor\n })\n\n return descriptors\n }\n\n private hasValue(attributeName: string) {\n const descriptor = this.valueDescriptorNameMap[attributeName]\n const hasMethodName = `has${capitalize(descriptor.name)}`\n\n return this.receiver[hasMethodName]\n }\n}\n","import { Multimap } from \"../multimap\"\nimport { Token, TokenListObserver, TokenListObserverDelegate } from \"../mutation-observers\"\nimport { Context } from \"./context\"\n\nexport interface TargetObserverDelegate {\n targetConnected(element: Element, name: string): void\n targetDisconnected(element: Element, name: string): void\n}\n\nexport class TargetObserver implements TokenListObserverDelegate {\n readonly context: Context\n readonly delegate: TargetObserverDelegate\n readonly targetsByName: Multimap<string, Element>\n private tokenListObserver?: TokenListObserver\n\n constructor(context: Context, delegate: TargetObserverDelegate) {\n this.context = context\n this.delegate = delegate\n this.targetsByName = new Multimap\n }\n\n start() {\n if (!this.tokenListObserver) {\n this.tokenListObserver = new TokenListObserver(this.element, this.attributeName, this)\n this.tokenListObserver.start()\n }\n }\n\n stop() {\n if (this.tokenListObserver) {\n this.disconnectAllTargets()\n this.tokenListObserver.stop()\n delete this.tokenListObserver\n }\n }\n\n // Token list observer delegate\n\n tokenMatched({ element, content: name }: Token) {\n if (this.scope.containsElement(element)) {\n this.connectTarget(element, name)\n }\n }\n\n tokenUnmatched({ element, content: name }: Token) {\n this.disconnectTarget(element, name)\n }\n\n // Target management\n\n connectTarget(element: Element, name: string) {\n if (!this.targetsByName.has(name, element)) {\n this.targetsByName.add(name, element)\n this.tokenListObserver?.pause(() => this.delegate.targetConnected(element, name))\n }\n }\n\n disconnectTarget(element: Element, name: string) {\n if (this.targetsByName.has(name, element)) {\n this.targetsByName.delete(name, element)\n this.tokenListObserver?.pause(() => this.delegate.targetDisconnected(element, name))\n }\n }\n\n disconnectAllTargets() {\n for (const name of this.targetsByName.keys) {\n for (const element of this.targetsByName.getValuesForKey(name)) {\n this.disconnectTarget(element, name)\n }\n }\n }\n\n // Private\n\n private get attributeName() {\n return `data-${this.context.identifier}-target`\n }\n\n private get element() {\n return this.context.element\n }\n\n private get scope() {\n return this.context.scope\n }\n}\n","import { Application } from \"./application\"\nimport { BindingObserver } from \"./binding_observer\"\nimport { Controller } from \"./controller\"\nimport { Dispatcher } from \"./dispatcher\"\nimport { ErrorHandler } from \"./error_handler\"\nimport { Module } from \"./module\"\nimport { Schema } from \"./schema\"\nimport { Scope } from \"./scope\"\nimport { ValueObserver } from \"./value_observer\"\nimport { TargetObserver, TargetObserverDelegate } from \"./target_observer\"\n\nexport class Context implements ErrorHandler, TargetObserverDelegate {\n readonly module: Module\n readonly scope: Scope\n readonly controller: Controller\n private bindingObserver: BindingObserver\n private valueObserver: ValueObserver\n private targetObserver: TargetObserver\n\n constructor(module: Module, scope: Scope) {\n this.module = module\n this.scope = scope\n this.controller = new module.controllerConstructor(this)\n this.bindingObserver = new BindingObserver(this, this.dispatcher)\n this.valueObserver = new ValueObserver(this, this.controller)\n this.targetObserver = new TargetObserver(this, this)\n\n try {\n this.controller.initialize()\n this.logDebugActivity(\"initialize\")\n } catch (error) {\n this.handleError(error, \"initializing controller\")\n }\n }\n\n connect() {\n this.bindingObserver.start()\n this.valueObserver.start()\n this.targetObserver.start()\n\n try {\n this.controller.connect()\n this.logDebugActivity(\"connect\")\n } catch (error) {\n this.handleError(error, \"connecting controller\")\n }\n }\n\n disconnect() {\n try {\n this.controller.disconnect()\n this.logDebugActivity(\"disconnect\")\n } catch (error) {\n this.handleError(error, \"disconnecting controller\")\n }\n\n this.targetObserver.stop()\n this.valueObserver.stop()\n this.bindingObserver.stop()\n }\n\n get application(): Application {\n return this.module.application\n }\n\n get identifier(): string {\n return this.module.identifier\n }\n\n get schema(): Schema {\n return this.application.schema\n }\n\n get dispatcher(): Dispatcher {\n return this.application.dispatcher\n }\n\n get element(): Element {\n return this.scope.element\n }\n\n get parentElement(): Element | null {\n return this.element.parentElement\n }\n\n // Error handling\n\n handleError(error: Error, message: string, detail: object = {}) {\n const { identifier, controller, element } = this\n detail = Object.assign({ identifier, controller, element }, detail)\n this.application.handleError(error, `Error ${message}`, detail)\n }\n\n // Debug logging\n\n logDebugActivity = (functionName: string, detail: object = {}): void => {\n const { identifier, controller, element } = this\n detail = Object.assign({ identifier, controller, element }, detail)\n this.application.logDebugActivity(this.identifier, functionName, detail)\n }\n\n // Target observer delegate\n\n targetConnected(element: Element, name: string) {\n this.invokeControllerMethod(`${name}TargetConnected`, element)\n }\n\n targetDisconnected(element: Element, name: string) {\n this.invokeControllerMethod(`${name}TargetDisconnected`, element)\n }\n\n // Private\n\n invokeControllerMethod(methodName: string, ...args: any[]) {\n const controller: any = this.controller\n if (typeof controller[methodName] == \"function\") {\n controller[methodName](...args)\n }\n }\n}\n","import { Constructor } from \"./constructor\"\n\nexport function readInheritableStaticArrayValues<T, U = string>(constructor: Constructor<T>, propertyName: string) {\n const ancestors = getAncestorsForConstructor(constructor)\n return Array.from(ancestors.reduce((values, constructor) => {\n getOwnStaticArrayValues(constructor, propertyName).forEach(name => values.add(name))\n return values\n }, new Set as Set<U>))\n}\n\nexport function readInheritableStaticObjectPairs<T, U>(constructor: Constructor<T>, propertyName: string) {\n const ancestors = getAncestorsForConstructor(constructor)\n return ancestors.reduce((pairs, constructor) => {\n pairs.push(...getOwnStaticObjectPairs(constructor, propertyName) as any)\n return pairs\n }, [] as [string, U][])\n}\n\nfunction getAncestorsForConstructor<T>(constructor: Constructor<T>) {\n const ancestors: Constructor<{}>[] = []\n while (constructor) {\n ancestors.push(constructor)\n constructor = Object.getPrototypeOf(constructor)\n }\n return ancestors.reverse()\n}\n\nfunction getOwnStaticArrayValues<T>(constructor: Constructor<T>, propertyName: string) {\n const definition = (constructor as any)[propertyName]\n return Array.isArray(definition) ? definition : []\n}\n\nfunction getOwnStaticObjectPairs<T, U>(constructor: Constructor<T>, propertyName: string) {\n const definition = (constructor as any)[propertyName]\n return definition ? Object.keys(definition).map(key => [key, definition[key]] as [string, U]) : []\n}\n","import { Constructor } from \"./constructor\"\nimport { readInheritableStaticArrayValues } from \"./inheritable_statics\"\n\nexport type Blessing<T> = (constructor: Constructor<T>) => PropertyDescriptorMap\n\nexport interface Blessable<T> extends Constructor<T> {\n readonly blessings?: Blessing<T>[]\n}\n\nexport function bless<T>(constructor: Blessable<T>): Constructor<T> {\n return shadow(constructor, getBlessedProperties(constructor))\n}\n\nfunction shadow<T>(constructor: Constructor<T>, properties: PropertyDescriptorMap) {\n const shadowConstructor = extend(constructor)\n const shadowProperties = getShadowProperties(constructor.prototype, properties)\n Object.defineProperties(shadowConstructor.prototype, shadowProperties)\n return shadowConstructor\n}\n\nfunction getBlessedProperties<T>(constructor: Constructor<T>) {\n const blessings = readInheritableStaticArrayValues(constructor, \"blessings\") as Blessing<T>[]\n return blessings.reduce((blessedProperties, blessing) => {\n const properties = blessing(constructor)\n for (const key in properties) {\n const descriptor = blessedProperties[key] || {} as PropertyDescriptor\n blessedProperties[key] = Object.assign(descriptor, properties[key])\n }\n return blessedProperties\n }, {} as PropertyDescriptorMap)\n}\n\nfunction getShadowProperties<T>(prototype: any, properties: PropertyDescriptorMap) {\n return getOwnKeys(properties).reduce((shadowProperties, key) => {\n const descriptor = getShadowedDescriptor(prototype, properties, key)\n if (descriptor) {\n Object.assign(shadowProperties, { [key]: descriptor })\n }\n return shadowProperties\n }, {} as PropertyDescriptorMap)\n}\n\nfunction getShadowedDescriptor(prototype: any, properties: PropertyDescriptorMap, key: string | symbol) {\n const shadowingDescriptor = Object.getOwnPropertyDescriptor(prototype, key)\n const shadowedByValue = shadowingDescriptor && \"value\" in shadowingDescriptor\n if (!shadowedByValue) {\n const descriptor = Object.getOwnPropertyDescriptor(properties, key)!.value\n if (shadowingDescriptor) {\n descriptor.get = shadowingDescriptor.get || descriptor.get\n descriptor.set = shadowingDescriptor.set || descriptor.set\n }\n return descriptor\n }\n}\n\nconst getOwnKeys = (() => {\n if (typeof Object.getOwnPropertySymbols == \"function\") {\n return (object: any) => [\n ...Object.getOwnPropertyNames(object),\n ...Object.getOwnPropertySymbols(object)\n ]\n } else {\n return Object.getOwnPropertyNames\n }\n})()\n\nconst extend = (() => {\n function extendWithReflect<T extends Constructor<{}>>(constructor: T): T {\n function extended() {\n return Reflect.construct(constructor, arguments, new.target)\n }\n\n extended.prototype = Object.create(constructor.prototype, {\n constructor: { value: extended }\n })\n\n Reflect.setPrototypeOf(extended, constructor)\n return extended as any\n }\n\n function testReflectExtension() {\n const a = function(this: any) { this.a.call(this) } as any\n const b = extendWithReflect(a)\n b.prototype.a = function() {}\n return new b\n }\n\n try {\n testReflectExtension()\n return extendWithReflect\n } catch (error) {\n return <T extends Constructor<{}>>(constructor: T) => class extended extends constructor {}\n }\n})()\n","import { Application } from \"./application\"\nimport { Context } from \"./context\"\nimport { ControllerConstructor } from \"./controller\"\nimport { Definition, blessDefinition } from \"./definition\"\nimport { Scope } from \"./scope\"\n\nexport class Module {\n readonly application: Application\n readonly definition: Definition\n private contextsByScope: WeakMap<Scope, Context>\n private connectedContexts: Set<Context>\n\n constructor(application: Application, definition: Definition) {\n this.application = application\n this.definition = blessDefinition(definition)\n this.contextsByScope = new WeakMap\n this.connectedContexts = new Set\n }\n\n get identifier(): string {\n return this.definition.identifier\n }\n\n get controllerConstructor(): ControllerConstructor {\n return this.definition.controllerConstructor\n }\n\n get contexts(): Context[] {\n return Array.from(this.connectedContexts)\n }\n\n connectContextForScope(scope: Scope) {\n const context = this.fetchContextForScope(scope)\n this.connectedContexts.add(context)\n context.connect()\n }\n\n disconnectContextForScope(scope: Scope) {\n const context = this.contextsByScope.get(scope)\n if (context) {\n this.connectedContexts.delete(context)\n context.disconnect()\n }\n }\n\n private fetchContextForScope(scope: Scope): Context {\n let context = this.contextsByScope.get(scope)\n if (!context) {\n context = new Context(this, scope)\n this.contextsByScope.set(scope, context)\n }\n return context\n }\n}\n","import { bless } from \"./blessing\"\nimport { ControllerConstructor } from \"./controller\"\n\nexport interface Definition {\n identifier: string\n controllerConstructor: ControllerConstructor\n}\n\nexport function blessDefinition(definition: Definition): Definition {\n return {\n identifier: definition.identifier,\n controllerConstructor: bless(definition.controllerConstructor)\n }\n}\n","import { Scope } from \"./scope\"\nimport { tokenize } from \"./string_helpers\"\n\nexport class ClassMap {\n readonly scope: Scope\n\n constructor(scope: Scope) {\n this.scope = scope\n }\n\n has(name: string) {\n return this.data.has(this.getDataKey(name))\n }\n\n get(name: string): string | undefined {\n return this.getAll(name)[0]\n }\n\n getAll(name: string) {\n const tokenString = this.data.get(this.getDataKey(name)) || \"\"\n return tokenize(tokenString)\n }\n\n getAttributeName(name: string) {\n return this.data.getAttributeNameForKey(this.getDataKey(name))\n }\n\n getDataKey(name: string) {\n return `${name}-class`\n }\n\n get data() {\n return this.scope.data\n }\n}\n","import { Scope } from \"./scope\"\nimport { dasherize } from \"./string_helpers\"\n\nexport class DataMap {\n readonly scope: Scope\n\n constructor(scope: Scope) {\n this.scope = scope\n }\n\n get element(): Element {\n return this.scope.element\n }\n\n get identifier(): string {\n return this.scope.identifier\n }\n\n get(key: string): string | null {\n const name = this.getAttributeNameForKey(key)\n return this.element.getAttribute(name)\n }\n\n set(key: string, value: string): string | null {\n const name = this.getAttributeNameForKey(key)\n this.element.setAttribute(name, value)\n return this.get(key)\n }\n\n has(key: string): boolean {\n const name = this.getAttributeNameForKey(key)\n return this.element.hasAttribute(name)\n }\n\n delete(key: string): boolean {\n if (this.has(key)) {\n const name = this.getAttributeNameForKey(key)\n this.element.removeAttribute(name)\n return true\n } else {\n return false\n }\n }\n\n getAttributeNameForKey(key: string): string {\n return `data-${this.identifier}-${dasherize(key)}`\n }\n}\n","import { Logger } from \"./logger\"\n\nexport class Guide {\n readonly logger: Logger\n readonly warnedKeysByObject: WeakMap<any, Set<string>> = new WeakMap\n\n constructor(logger: Logger) {\n this.logger = logger\n }\n\n warn(object: any, key: string, message: string) {\n let warnedKeys: Set<string> | undefined = this.warnedKeysByObject.get(object)\n\n if (!warnedKeys) {\n warnedKeys = new Set\n this.warnedKeysByObject.set(object, warnedKeys)\n }\n\n if (!warnedKeys.has(key)) {\n warnedKeys.add(key)\n this.logger.warn(message, object)\n }\n }\n}\n","export function attributeValueContainsToken(attributeName: string, token: string) {\n return `[${attributeName}~=\"${token}\"]`\n}\n","import { Scope } from \"./scope\"\nimport { attributeValueContainsToken } from \"./selectors\"\n\nexport class TargetSet {\n readonly scope: Scope\n\n constructor(scope: Scope) {\n this.scope = scope\n }\n\n get element() {\n return this.scope.element\n }\n\n get identifier() {\n return this.scope.identifier\n }\n\n get schema() {\n return this.scope.schema\n }\n\n has(targetName: string) {\n return this.find(targetName) != null\n }\n\n find(...targetNames: string[]) {\n return targetNames.reduce((target, targetName) =>\n target\n || this.findTarget(targetName)\n || this.findLegacyTarget(targetName)\n , undefined as Element | undefined)\n }\n\n findAll(...targetNames: string[]) {\n return targetNames.reduce((targets, targetName) => [\n ...targets,\n ...this.findAllTargets(targetName),\n ...this.findAllLegacyTargets(targetName)\n ], [] as Element[])\n }\n\n private findTarget(targetName: string) {\n const selector = this.getSelectorForTargetName(targetName)\n return this.scope.findElement(selector)\n }\n\n private findAllTargets(targetName: string) {\n const selector = this.getSelectorForTargetName(targetName)\n return this.scope.findAllElements(selector)\n }\n\n private getSelectorForTargetName(targetName: string) {\n const attributeName = this.schema.targetAttributeForScope(this.identifier)\n return attributeValueContainsToken(attributeName, targetName)\n }\n\n private findLegacyTarget(targetName: string) {\n const selector = this.getLegacySelectorForTargetName(targetName)\n return this.deprecate(this.scope.findElement(selector), targetName)\n }\n\n private findAllLegacyTargets(targetName: string) {\n const selector = this.getLegacySelectorForTargetName(targetName)\n return this.scope.findAllElements(selector).map(element => this.deprecate(element, targetName))\n }\n\n private getLegacySelectorForTargetName(targetName: string) {\n const targetDescriptor = `${this.identifier}.${targetName}`\n return attributeValueContainsToken(this.schema.targetAttribute, targetDescriptor)\n }\n\n private deprecate<T>(element: T, targetName: string) {\n if (element) {\n const { identifier } = this\n const attributeName = this.schema.targetAttribute\n const revisedAttributeName = this.schema.targetAttributeForScope(identifier)\n this.guide.warn(element, `target:${targetName}`,\n `Please replace ${attributeName}=\"${identifier}.${targetName}\" with ${revisedAttributeName}=\"${targetName}\". ` +\n `The ${attributeName} attribute is deprecated and will be removed in a future version of Stimulus.`)\n }\n return element\n }\n\n private get guide() {\n return this.scope.guide\n }\n}\n","import { ClassMap } from \"./class_map\"\nimport { DataMap } from \"./data_map\"\nimport { Guide } from \"./guide\"\nimport { Logger } from \"./logger\"\nimport { Schema } from \"./schema\"\nimport { attributeValueContainsToken } from \"./selectors\"\nimport { TargetSet } from \"./target_set\"\n\nexport class Scope {\n readonly schema: Schema\n readonly element: Element\n readonly identifier: string\n readonly guide: Guide\n readonly targets = new TargetSet(this)\n readonly classes = new ClassMap(this)\n readonly data = new DataMap(this)\n\n constructor(schema: Schema, element: Element, identifier: string, logger: Logger) {\n this.schema = schema\n this.element = element\n this.identifier = identifier\n this.guide = new Guide(logger)\n }\n\n findElement(selector: string): Element | undefined {\n return this.element.matches(selector)\n ? this.element\n : this.queryElements(selector).find(this.containsElement)\n }\n\n findAllElements(selector: string): Element[] {\n return [\n ...this.element.matches(selector) ? [this.element] : [],\n ...this.queryElements(selector).filter(this.containsElement)\n ]\n }\n\n containsElement = (element: Element): boolean => {\n return element.closest(this.controllerSelector) === this.element\n }\n\n private queryElements(selector: string): Element[] {\n return Array.from(this.element.querySelectorAll(selector))\n }\n\n private get controllerSelector(): string {\n return attributeValueContainsToken(this.schema.controllerAttribute, this.identifier)\n }\n}\n","import { ErrorHandler } from \"./error_handler\"\nimport { Schema } from \"./schema\"\nimport { Scope } from \"./scope\"\nimport { Token, ValueListObserver, ValueListObserverDelegate } from \"../mutation-observers\"\n\nexport interface ScopeObserverDelegate extends ErrorHandler {\n createScopeForElementAndIdentifier(element: Element, identifier: string): Scope\n scopeConnected(scope: Scope): void\n scopeDisconnected(scope: Scope): void\n}\n\nexport class ScopeObserver implements ValueListObserverDelegate<Scope> {\n readonly element: Element\n readonly schema: Schema\n private delegate: ScopeObserverDelegate\n private valueListObserver: ValueListObserver<Scope>\n private scopesByIdentifierByElement: WeakMap<Element, Map<string, Scope>>\n private scopeReferenceCounts: WeakMap<Scope, number>\n\n constructor(element: Element, schema: Schema, delegate: ScopeObserverDelegate) {\n this.element = element\n this.schema = schema\n this.delegate = delegate\n this.valueListObserver = new ValueListObserver(this.element, this.controllerAttribute, this)\n this.scopesByIdentifierByElement = new WeakMap\n this.scopeReferenceCounts = new WeakMap\n }\n\n start() {\n this.valueListObserver.start()\n }\n\n stop() {\n this.valueListObserver.stop()\n }\n\n get controllerAttribute() {\n return this.schema.controllerAttribute\n }\n\n // Value observer delegate\n\n parseValueForToken(token: Token): Scope | undefined {\n const { element, content: identifier } = token\n const scopesByIdentifier = this.fetchScopesByIdentifierForElement(element)\n\n let scope = scopesByIdentifier.get(identifier)\n if (!scope) {\n scope = this.delegate.createScopeForElementAndIdentifier(element, identifier)\n scopesByIdentifier.set(identifier, scope)\n }\n\n return scope\n }\n\n elementMatchedValue(element: Element, value: Scope) {\n const referenceCount = (this.scopeReferenceCounts.get(value) || 0) + 1\n this.scopeReferenceCounts.set(value, referenceCount)\n if (referenceCount == 1) {\n this.delegate.scopeConnected(value)\n }\n }\n\n elementUnmatchedValue(element: Element, value: Scope) {\n const referenceCount = this.scopeReferenceCounts.get(value)\n if (referenceCount) {\n this.scopeReferenceCounts.set(value, referenceCount - 1)\n if (referenceCount == 1) {\n this.delegate.scopeDisconnected(value)\n }\n }\n }\n\n private fetchScopesByIdentifierForElement(element: Element) {\n let scopesByIdentifier = this.scopesByIdentifierByElement.get(element)\n if (!scopesByIdentifier) {\n scopesByIdentifier = new Map\n this.scopesByIdentifierByElement.set(element, scopesByIdentifier)\n }\n return scopesByIdentifier\n }\n}\n","import { Application } from \"./application\"\nimport { Context } from \"./context\"\nimport { Definition } from \"./definition\"\nimport { Module } from \"./module\"\nimport { Multimap } from \"../multimap\"\nimport { Scope } from \"./scope\"\nimport { ScopeObserver, ScopeObserverDelegate } from \"./scope_observer\"\n\nexport class Router implements ScopeObserverDelegate {\n readonly application: Application\n private scopeObserver: ScopeObserver\n private scopesByIdentifier: Multimap<string, Scope>\n private modulesByIdentifier: Map<string, Module>\n\n constructor(application: Application) {\n this.application = application\n this.scopeObserver = new ScopeObserver(this.element, this.schema, this)\n this.scopesByIdentifier = new Multimap\n this.modulesByIdentifier = new Map\n }\n\n get element() {\n return this.application.element\n }\n\n get schema() {\n return this.application.schema\n }\n\n get logger() {\n return this.application.logger\n }\n\n get controllerAttribute(): string {\n return this.schema.controllerAttribute\n }\n\n get modules() {\n return Array.from(this.modulesByIdentifier.values())\n }\n\n get contexts() {\n return this.modules.reduce((contexts, module) => contexts.concat(module.contexts), [] as Context[])\n }\n\n start() {\n this.scopeObserver.start()\n }\n\n stop() {\n this.scopeObserver.stop()\n }\n\n loadDefinition(definition: Definition) {\n this.unloadIdentifier(definition.identifier)\n const module = new Module(this.application, definition)\n this.connectModule(module)\n }\n\n unloadIdentifier(identifier: string) {\n const module = this.modulesByIdentifier.get(identifier)\n if (module) {\n this.disconnectModule(module)\n }\n }\n\n getContextForElementAndIdentifier(element: Element, identifier: string) {\n const module = this.modulesByIdentifier.get(identifier)\n if (module) {\n return module.contexts.find(context => context.element == element)\n }\n }\n\n // Error handler delegate\n\n handleError(error: Error, message: string, detail: any) {\n this.application.handleError(error, message, detail)\n }\n\n // Scope observer delegate\n\n createScopeForElementAndIdentifier(element: Element, identifier: string) {\n return new Scope(this.schema, element, identifier, this.logger)\n }\n\n scopeConnected(scope: Scope) {\n this.scopesByIdentifier.add(scope.identifier, scope)\n const module = this.modulesByIdentifier.get(scope.identifier)\n if (module) {\n module.connectContextForScope(scope)\n }\n }\n\n scopeDisconnected(scope: Scope) {\n this.scopesByIdentifier.delete(scope.identifier, scope)\n const module = this.modulesByIdentifier.get(scope.identifier)\n if (module) {\n module.disconnectContextForScope(scope)\n }\n }\n\n // Modules\n\n private connectModule(module: Module) {\n this.modulesByIdentifier.set(module.identifier, module)\n const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier)\n scopes.forEach(scope => module.connectContextForScope(scope))\n }\n\n private disconnectModule(module: Module) {\n this.modulesByIdentifier.delete(module.identifier)\n const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier)\n scopes.forEach(scope => module.disconnectContextForScope(scope))\n }\n}\n","export interface Schema {\n controllerAttribute: string\n actionAttribute: string\n targetAttribute: string\n targetAttributeForScope(identifier: string): string\n}\n\nexport const defaultSchema: Schema = {\n controllerAttribute: \"data-controller\",\n actionAttribute: \"data-action\",\n targetAttribute: \"data-target\",\n targetAttributeForScope: identifier => `data-${identifier}-target`\n}\n","import { Controller, ControllerConstructor } from \"./controller\"\nimport { Definition } from \"./definition\"\nimport { Dispatcher } from \"./dispatcher\"\nimport { ErrorHandler } from \"./error_handler\"\nimport { Logger } from \"./logger\"\nimport { Router } from \"./router\"\nimport { Schema, defaultSchema } from \"./schema\"\n\nexport class Application implements ErrorHandler {\n readonly element: Element\n readonly schema: Schema\n readonly dispatcher: Dispatcher\n readonly router: Router\n logger: Logger = console\n debug: boolean = false\n\n static start(element?: Element, schema?: Schema): Application {\n const application = new Application(element, schema)\n application.start()\n return application\n }\n\n constructor(element: Element = document.documentElement, schema: Schema = defaultSchema) {\n this.element = element\n this.schema = schema\n this.dispatcher = new Dispatcher(this)\n this.router = new Router(this)\n }\n\n async start() {\n await domReady()\n this.logDebugActivity(\"application\", \"starting\")\n this.dispatcher.start()\n this.router.start()\n this.logDebugActivity(\"application\", \"start\")\n }\n\n stop() {\n this.logDebugActivity(\"application\", \"stopping\")\n this.dispatcher.stop()\n this.router.stop()\n this.logDebugActivity(\"application\", \"stop\")\n }\n\n register(identifier: string, controllerConstructor: ControllerConstructor) {\n if ((controllerConstructor as any).shouldLoad) {\n this.load({ identifier, controllerConstructor })\n }\n }\n\n load(...definitions: Definition[]): void\n load(definitions: Definition[]): void\n load(head: Definition | Definition[], ...rest: Definition[]) {\n const definitions = Array.isArray(head) ? head : [head, ...rest]\n definitions.forEach(definition => this.router.loadDefinition(definition))\n }\n\n unload(...identifiers: string[]): void\n unload(identifiers: string[]): void\n unload(head: string | string[], ...rest: string[]) {\n const identifiers = Array.isArray(head) ? head : [head, ...rest]\n identifiers.forEach(identifier => this.router.unloadIdentifier(identifier))\n }\n\n // Controllers\n\n get controllers(): Controller[] {\n return this.router.contexts.map(context => context.controller)\n }\n\n getControllerForElementAndIdentifier(element: Element, identifier: string): Controller | null {\n const context = this.router.getContextForElementAndIdentifier(element, identifier)\n return context ? context.controller : null\n }\n\n // Error handling\n\n handleError(error: Error, message: string, detail: object) {\n this.logger.error(`%s\\n\\n%o\\n\\n%o`, message, error, detail)\n\n window.onerror?.(message, \"\", 0, 0, error)\n }\n\n // Debug logging\n\n logDebugActivity = (identifier: string, functionName: string, detail: object = {}): void => {\n if (this.debug) {\n this.logFormattedMessage(identifier, functionName, detail)\n }\n }\n\n private logFormattedMessage(identifier: string, functionName: string, detail: object = {}) {\n detail = Object.assign({ application: this }, detail)\n\n this.logger.groupCollapsed(`${identifier} #${functionName}`)\n this.logger.log(\"details:\", { ...detail })\n this.logger.groupEnd()\n }\n}\n\nfunction domReady() {\n return new Promise<void>(resolve => {\n if (document.readyState == \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => resolve())\n } else {\n resolve()\n }\n })\n}\n","import { Constructor } from \"./constructor\"\nimport { Controller } from \"./controller\"\nimport { readInheritableStaticObjectPairs } from \"./inheritable_statics\"\nimport { camelize, capitalize, dasherize } from \"./string_helpers\"\n\nexport function ValuePropertiesBlessing<T>(constructor: Constructor<T>) {\n const valueDefinitionPairs = readInheritableStaticObjectPairs<T, ValueTypeDefinition>(constructor, \"values\")\n const propertyDescriptorMap: PropertyDescriptorMap = {\n valueDescriptorMap: {\n get(this: Controller) {\n return valueDefinitionPairs.reduce((result, valueDefinitionPair) => {\n const valueDescriptor = parseValueDefinitionPair(valueDefinitionPair)\n const attributeName = this.data.getAttributeNameForKey(valueDescriptor.key)\n return Object.assign(result, { [attributeName]: valueDescriptor })\n }, {} as ValueDescriptorMap)\n }\n }\n }\n\n return valueDefinitionPairs.reduce((properties, valueDefinitionPair) => {\n return Object.assign(properties, propertiesForValueDefinitionPair(valueDefinitionPair))\n }, propertyDescriptorMap)\n}\n\nexport function propertiesForValueDefinitionPair<T>(valueDefinitionPair: ValueDefinitionPair): PropertyDescriptorMap {\n const definition = parseValueDefinitionPair(valueDefinitionPair)\n const { key, name, reader: read, writer: write } = definition\n\n return {\n [name]: {\n get(this: Controller) {\n const value = this.data.get(key)\n if (value !== null) {\n return read(value)\n } else {\n return definition.defaultValue\n }\n },\n\n set(this: Controller, value: T | undefined) {\n if (value === undefined) {\n this.data.delete(key)\n } else {\n this.data.set(key, write(value))\n }\n }\n },\n\n [`has${capitalize(name)}`]: {\n get(this: Controller): boolean {\n return this.data.has(key) || definition.hasCustomDefaultValue\n }\n }\n }\n}\n\nexport type ValueDescriptor = {\n type: ValueType,\n key: string,\n name: string,\n defaultValue: ValueTypeDefault,\n hasCustomDefaultValue: boolean,\n reader: Reader,\n writer: Writer\n}\n\nexport type ValueDescriptorMap = { [attributeName: string]: ValueDescriptor }\n\nexport type ValueDefinitionMap = { [token: string]: ValueTypeDefinition }\n\nexport type ValueDefinitionPair = [string, ValueTypeDefinition]\n\nexport type ValueTypeConstant = typeof Array | typeof Boolean | typeof Number | typeof Object | typeof String\n\nexport type ValueTypeDefault = Array<any> | Boolean | Number | Object | String\n\nexport type ValueTypeObject = { type: ValueTypeConstant, default: ValueTypeDefault }\n\nexport type ValueTypeDefinition = ValueTypeConstant | ValueTypeDefault | ValueTypeObject\n\nexport type ValueType = \"array\" | \"boolean\" | \"number\" | \"object\" | \"string\"\n\nfunction parseValueDefinitionPair([token, typeDefinition]: ValueDefinitionPair): ValueDescriptor {\n return valueDescriptorForTokenAndTypeDefinition(token, typeDefinition)\n}\n\nfunction parseValueTypeConstant(constant: ValueTypeConstant) {\n switch (constant) {\n case Array: return \"array\"\n case Boolean: return \"boolean\"\n case Number: return \"number\"\n case Object: return \"object\"\n case String: return \"string\"\n }\n}\n\nfunction parseValueTypeDefault(defaultValue: ValueTypeDefault) {\n switch (typeof defaultValue) {\n case \"boolean\": return \"boolean\"\n case \"number\": return \"number\"\n case \"string\": return \"string\"\n }\n\n if (Array.isArray(defaultValue)) return \"array\"\n if (Object.prototype.toString.call(defaultValue) === \"[object Object]\") return \"object\"\n}\n\nfunction parseValueTypeObject(typeObject: ValueTypeObject) {\n const typeFromObject = parseValueTypeConstant(typeObject.type)\n\n if (typeFromObject) {\n const defaultValueType = parseValueTypeDefault(typeObject.default)\n\n if (typeFromObject !== defaultValueType) {\n throw new Error(`Type \"${typeFromObject}\" must match the type of the default value. Given default value: \"${typeObject.default}\" as \"${defaultValueType}\"`)\n }\n\n return typeFromObject\n }\n}\n\nfunction parseValueTypeDefinition(typeDefinition: ValueTypeDefinition): ValueType {\n const typeFromObject = parseValueTypeObject(typeDefinition as ValueTypeObject)\n const typeFromDefaultValue = parseValueTypeDefault(typeDefinition as ValueTypeDefault)\n const typeFromConstant = parseValueTypeConstant(typeDefinition as ValueTypeConstant)\n\n const type = typeFromObject || typeFromDefaultValue || typeFromConstant\n if (type) return type\n\n throw new Error(`Unknown value type \"${typeDefinition}\"`)\n}\n\nfunction defaultValueForDefinition(typeDefinition: ValueTypeDefinition): ValueTypeDefault {\n const constant = parseValueTypeConstant(typeDefinition as ValueTypeConstant)\n\n if (constant) return defaultValuesByType[constant]\n\n const defaultValue = (typeDefinition as ValueTypeObject).default\n if (defaultValue !== undefined) return defaultValue\n\n return typeDefinition\n}\n\nfunction valueDescriptorForTokenAndTypeDefinition(token: string, typeDefinition: ValueTypeDefinition) {\n const key = `${dasherize(token)}-value`\n const type = parseValueTypeDefinition(typeDefinition)\n return {\n type,\n key,\n name: camelize(key),\n get defaultValue() { return defaultValueForDefinition(typeDefinition) },\n get hasCustomDefaultValue() { return parseValueTypeDefault(typeDefinition) !== undefined },\n reader: readers[type],\n writer: writers[type] || writers.default\n }\n}\n\nconst defaultValuesByType = {\n get array() { return [] },\n boolean: false,\n number: 0,\n get object() { return {} },\n string: \"\"\n}\n\ntype Reader = (value: string) => any\n\nconst readers: { [type: string]: Reader } = {\n array(value: string): any[] {\n const array = JSON.parse(value)\n if (!Array.isArray(array)) {\n throw new TypeError(\"Expected array\")\n }\n return array\n },\n\n boolean(value: string): boolean {\n return !(value == \"0\" || String(value).toLowerCase() == \"false\")\n },\n\n number(value: string): number {\n return Number(value)\n },\n\n object(value: string): object {\n const object = JSON.parse(value)\n if (object === null || typeof object != \"object\" || Array.isArray(object)) {\n throw new TypeError(\"Expected object\")\n }\n return object\n },\n\n string(value: string): string {\n return value\n }\n}\n\ntype Writer = (value: any) => string\n\nconst writers: { [type: string]: Writer } = {\n default: writeString,\n array: writeJSON,\n object: writeJSON\n}\n\nfunction writeJSON(value: any) {\n return JSON.stringify(value)\n}\n\nfunction writeString(value: any) {\n return `${value}`\n}\n","import { ClassPropertiesBlessing } from \"./class_properties\"\nimport { Constructor } from \"./constructor\"\nimport { Context } from \"./context\"\nimport { TargetPropertiesBlessing } from \"./target_properties\"\nimport { ValuePropertiesBlessing, ValueDefinitionMap } from \"./value_properties\"\n\nexport type ControllerConstructor = Constructor<Controller>\n\nexport class Controller {\n static blessings = [ ClassPropertiesBlessing, TargetPropertiesBlessing, ValuePropertiesBlessing ]\n static targets: string[] = []\n static values: ValueDefinitionMap = {}\n\n static get shouldLoad() {\n return true\n }\n\n readonly context: Context\n\n constructor(context: Context) {\n this.context = context\n }\n\n get application() {\n return this.context.application\n }\n\n get scope() {\n return this.context.scope\n }\n\n get element() {\n return this.scope.element\n }\n\n get identifier() {\n return this.scope.identifier\n }\n\n get targets() {\n return this.scope.targets\n }\n\n get classes() {\n return this.scope.classes\n }\n\n get data() {\n return this.scope.data\n }\n\n initialize() {\n // Override in your subclass to set up initial controller state\n }\n\n connect() {\n // Override in your subclass to respond when the controller is connected to the DOM\n }\n\n disconnect() {\n // Override in your subclass to respond when the controller is disconnected from the DOM\n }\n\n dispatch(eventName: string, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true } = {}) {\n const type = prefix ? `${prefix}:${eventName}` : eventName\n const event = new CustomEvent(type, { detail, bubbles, cancelable })\n target.dispatchEvent(event)\n return event\n }\n}\n","import { Constructor } from \"./constructor\"\nimport { Controller } from \"./controller\"\nimport { readInheritableStaticArrayValues } from \"./inheritable_statics\"\nimport { capitalize } from \"./string_helpers\"\n\nexport function ClassPropertiesBlessing<T>(constructor: Constructor<T>) {\n const classes = readInheritableStaticArrayValues(constructor, \"classes\")\n return classes.reduce((properties, classDefinition) => {\n return Object.assign(properties, propertiesForClassDefinition(classDefinition))\n }, {} as PropertyDescriptorMap)\n}\n\nfunction propertiesForClassDefinition(key: string) {\n return {\n [`${key}Class`]: {\n get(this: Controller) {\n const { classes } = this\n if (classes.has(key)) {\n return classes.get(key)\n } else {\n const attribute = classes.getAttributeName(key)\n throw new Error(`Missing attribute \"${attribute}\"`)\n }\n }\n },\n\n [`${key}Classes`]: {\n get(this: Controller) {\n return this.classes.getAll(key)\n }\n },\n\n [`has${capitalize(key)}Class`]: {\n get(this: Controller) {\n return this.classes.has(key)\n }\n }\n }\n}\n","import { Constructor } from \"./constructor\"\nimport { Controller } from \"./controller\"\nimport { readInheritableStaticArrayValues } from \"./inheritable_statics\"\nimport { capitalize } from \"./string_helpers\"\n\nexport function TargetPropertiesBlessing<T>(constructor: Constructor<T>) {\n const targets = readInheritableStaticArrayValues(constructor, \"targets\")\n return targets.reduce((properties, targetDefinition) => {\n return Object.assign(properties, propertiesForTargetDefinition(targetDefinition))\n }, {} as PropertyDescriptorMap)\n}\n\nfunction propertiesForTargetDefinition(name: string) {\n return {\n [`${name}Target`]: {\n get(this: Controller) {\n const target = this.targets.find(name)\n if (target) {\n return target\n } else {\n throw new Error(`Missing target element \"${name}\" for \"${this.identifier}\" controller`)\n }\n }\n },\n\n [`${name}Targets`]: {\n get(this: Controller) {\n return this.targets.findAll(name)\n }\n },\n\n [`has${capitalize(name)}Target`]: {\n get(this: Controller) {\n return this.targets.has(name)\n }\n }\n }\n}\n"],"names":["EventListener","constructor","eventTarget","eventName","eventOptions","this","unorderedBindings","Set","connect","addEventListener","disconnect","removeEventListener","bindingConnected","binding","add","bindingDisconnected","delete","handleEvent","event","extendedEvent","stopImmediatePropagation","Object","assign","immediatePropagationStopped","call","extendEvent","bindings","Array","from","sort","left","right","leftIndex","index","rightIndex","Dispatcher","application","eventListenerMaps","Map","started","start","eventListeners","forEach","eventListener","stop","values","reduce","listeners","map","concat","fetchEventListenerForBinding","handleError","error","message","detail","fetchEventListener","eventListenerMap","fetchEventListenerMapForEventTarget","cacheKey","get","createEventListener","set","parts","keys","key","push","join","descriptorPattern","parseEventTarget","eventTargetName","window","document","camelize","value","replace","_","char","toUpperCase","capitalize","charAt","slice","dasherize","toLowerCase","defaultEventNames","a","e","button","form","details","input","getAttribute","select","textarea","Error","typecast","JSON","parse","o_O","Binding","context","action","identifier","willBeInvokedByEvent","invokeWithEvent","method","controller","methodName","target","currentTarget","params","actionEvent","logDebugActivity","element","Element","contains","scope","containsElement","ElementObserver","delegate","attributes","childList","subtree","elements","mutationObserver","MutationObserver","mutations","processMutations","observe","mutationObserverInit","refresh","pause","callback","takeRecords","matches","matchElementsInTree","has","removeElement","addElement","mutation","processMutation","type","processAttributeChange","attributeName","processRemovedNodes","removedNodes","processAddedNodes","addedNodes","node","elementAttributeChanged","matchElement","nodes","elementFromNode","processTree","elementIsActive","tree","processor","nodeType","Node","ELEMENT_NODE","isConnected","elementMatched","elementUnmatched","AttributeObserver","elementObserver","selector","hasAttribute","match","querySelectorAll","elementMatchedAttribute","elementUnmatchedAttribute","elementAttributeValueChanged","StringMapObserver","stringMap","attributeOldValue","knownAttributeNames","refreshAttribute","oldValue","getStringMapKeyForAttribute","stringMapKeyAdded","stringMapValueChanged","stringMapKeyRemoved","currentAttributeNames","recordedAttributeNames","attribute","name","fetch","del","prune","size","Multimap","valuesByKey","hasKey","hasValue","some","getValuesForKey","getKeysForValue","filter","IndexedMultimap","super","keysByValue","TokenListObserver","attributeObserver","tokensByElement","tokensMatched","readTokensForElement","unmatchedTokens","matchedTokens","refreshTokensForElement","tokensUnmatched","tokens","token","tokenMatched","tokenUnmatched","previousTokens","currentTokens","firstDifferingIndex","length","Math","max","zip","findIndex","previousToken","currentToken","content","tokenString","trim","split","parseTokenString","ValueListObserver","tokenListObserver","parseResultsByToken","WeakMap","valuesByTokenByElement","fetchParseResultForToken","fetchValuesByTokenForElement","elementMatchedValue","elementUnmatchedValue","parseResult","parseToken","valuesByToken","parseValueForToken","BindingObserver","bindingsByAction","valueListObserver","actionAttribute","disconnectAllActions","schema","connectAction","disconnectAction","clear","descriptor","tagName","getDefaultEventNameForElement","forToken","descriptorString","options","test","parseActionDescriptorString","toString","eventNameSuffix","getParamsFromEventTargetAttributes","pattern","RegExp","ValueObserver","receiver","stringMapObserver","valueDescriptorMap","invokeChangedCallbacksForDefaultValues","invokeChangedCallback","writer","defaultValue","valueDescriptorNameMap","valueDescriptors","undefined","data","rawValue","rawOldValue","changedMethodName","changedMethod","reader","descriptors","hasMethodName","TargetObserver","targetsByName","disconnectAllTargets","connectTarget","disconnectTarget","targetConnected","targetDisconnected","Context","module","functionName","controllerConstructor","bindingObserver","dispatcher","valueObserver","targetObserver","initialize","parentElement","invokeControllerMethod","args","readInheritableStaticArrayValues","propertyName","ancestors","getAncestorsForConstructor","definition","isArray","getOwnStaticArrayValues","readInheritableStaticObjectPairs","pairs","getOwnStaticObjectPairs","getPrototypeOf","reverse","bless","properties","shadowConstructor","extend","shadowProperties","prototype","getOwnKeys","shadowingDescriptor","getOwnPropertyDescriptor","getShadowedDescriptor","getShadowProperties","defineProperties","shadow","blessedProperties","blessing","getBlessedProperties","getOwnPropertySymbols","object","getOwnPropertyNames","extendWithReflect","extended","Reflect","construct","arguments","create","setPrototypeOf","b","testReflectExtension","Module","blessDefinition","contextsByScope","connectedContexts","contexts","connectContextForScope","fetchContextForScope","disconnectContextForScope","ClassMap","getDataKey","getAll","getAttributeName","getAttributeNameForKey","DataMap","setAttribute","removeAttribute","Guide","logger","warn","warnedKeys","warnedKeysByObject","attributeValueContainsToken","TargetSet","targetName","find","targetNames","findTarget","findLegacyTarget","findAll","targets","findAllTargets","findAllLegacyTargets","getSelectorForTargetName","findElement","findAllElements","targetAttributeForScope","getLegacySelectorForTargetName","deprecate","targetDescriptor","targetAttribute","revisedAttributeName","guide","Scope","closest","controllerSelector","queryElements","controllerAttribute","ScopeObserver","scopesByIdentifierByElement","scopeReferenceCounts","scopesByIdentifier","fetchScopesByIdentifierForElement","createScopeForElementAndIdentifier","referenceCount","scopeConnected","scopeDisconnected","Router","scopeObserver","modulesByIdentifier","modules","loadDefinition","unloadIdentifier","connectModule","disconnectModule","getContextForElementAndIdentifier","defaultSchema","Application","documentElement","console","debug","logFormattedMessage","router","Promise","resolve","readyState","register","shouldLoad","load","head","rest","unload","controllers","getControllerForElementAndIdentifier","onerror","groupCollapsed","log","groupEnd","parseValueDefinitionPair","typeDefinition","typeFromObject","typeObject","parseValueTypeConstant","defaultValueType","parseValueTypeDefault","default","parseValueTypeObject","typeFromDefaultValue","typeFromConstant","parseValueTypeDefinition","constant","defaultValuesByType","defaultValueForDefinition","hasCustomDefaultValue","readers","writers","valueDescriptorForTokenAndTypeDefinition","Boolean","Number","String","array","boolean","number","string","TypeError","writeJSON","stringify","Controller","classes","dispatch","prefix","bubbles","cancelable","CustomEvent","dispatchEvent","classDefinition","targetDefinition","valueDefinitionPairs","propertyDescriptorMap","result","valueDefinitionPair","valueDescriptor","read","write","propertiesForValueDefinitionPair"],"mappings":"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"}
@@ -11,6 +11,6 @@ class StimulusGenerator < Rails::Generators::NamedBase # :nodoc:
11
11
 
12
12
  private
13
13
  def stimulus_attribute_value(name)
14
- name.gsub(/\//, "--")
14
+ name.gsub(/\//, "--").gsub("_", "-")
15
15
  end
16
16
  end
@@ -3,8 +3,7 @@ import { Application } from "@hotwired/stimulus"
3
3
  const application = Application.start()
4
4
 
5
5
  // Configure Stimulus development experience
6
- application.warnings = true
7
- application.debug = false
8
- window.Stimulus = application
6
+ application.debug = false
7
+ window.Stimulus = application
9
8
 
10
9
  export { application }
@@ -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
- import { registerControllersFrom } from "@hotwired/stimulus-importmap-autoloader"
5
- registerControllersFrom("controllers", application)
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-importmap-autoloader", to: "stimulus-importmap-autoloader.js"
15
+ pin "@hotwired/stimulus", to: "stimulus.min.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
@@ -2,7 +2,7 @@ module Stimulus
2
2
  class Engine < ::Rails::Engine
3
3
  initializer "stimulus.assets" do
4
4
  if Rails.application.config.respond_to?(:assets)
5
- Rails.application.config.assets.precompile += %w( stimulus.js stimulus.min.js )
5
+ Rails.application.config.assets.precompile += %w( stimulus.js stimulus.min.js stimulus.min.js.map )
6
6
  end
7
7
  end
8
8
  end
@@ -1,3 +1,3 @@
1
1
  module Stimulus
2
- VERSION = "0.6.2"
2
+ VERSION = "0.7.3"
3
3
  end
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.6.2
4
+ version: 0.7.3
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-10-07 00:00:00.000000000 Z
13
+ date: 2021-11-24 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,8 +37,10 @@ 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
43
+ - app/assets/javascripts/stimulus.min.js.map
42
44
  - lib/generators/stimulus/USAGE
43
45
  - lib/generators/stimulus/stimulus_generator.rb
44
46
  - lib/generators/stimulus/templates/controller.js.tt
@@ -59,7 +61,7 @@ licenses:
59
61
  metadata:
60
62
  homepage_uri: https://stimulus.hotwired.dev
61
63
  source_code_uri: https://github.com/hotwired/stimulus-rails
62
- post_install_message:
64
+ post_install_message:
63
65
  rdoc_options: []
64
66
  require_paths:
65
67
  - lib
@@ -74,8 +76,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
76
  - !ruby/object:Gem::Version
75
77
  version: '0'
76
78
  requirements: []
77
- rubygems_version: 3.1.4
78
- signing_key:
79
+ rubygems_version: 3.2.22
80
+ signing_key:
79
81
  specification_version: 4
80
82
  summary: A modest JavaScript framework for the HTML you already have.
81
83
  test_files: []