@webhandle/backbone-view 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -3
- package/client-js/view.js +4 -0
- package/package.json +11 -34
- package/public/js/index.js +2 -0
- package/public/js/index.js.map +1 -0
package/README.md
CHANGED
|
@@ -76,13 +76,14 @@ And don't forget to call `render`, either before or after the element is added t
|
|
|
76
76
|
import { View } from '@webhandle/backbone-view'
|
|
77
77
|
|
|
78
78
|
class DollarView extends View {
|
|
79
|
-
preinitialize() {
|
|
80
|
-
this.events = {
|
|
79
|
+
preinitialize(options) {
|
|
80
|
+
this.events = Object.assign({}, {
|
|
81
81
|
'click .one': 'oneClicked',
|
|
82
82
|
'click .': function (evt) {
|
|
83
83
|
console.log(`${this.model} it got clicked`)
|
|
84
84
|
}
|
|
85
|
-
}
|
|
85
|
+
}, options.events)
|
|
86
|
+
options.events = this.events
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
render() {
|
|
@@ -165,3 +166,15 @@ let one = new DollarView({
|
|
|
165
166
|
one.render()
|
|
166
167
|
one.appendTo(document.body)
|
|
167
168
|
```
|
|
169
|
+
|
|
170
|
+
## Webhandle Component
|
|
171
|
+
|
|
172
|
+
This can also be initialized as a Webhandle component, like:
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
import setupBackboneView from "@webhandle/backbone-view/initialize-webhandle-component.mjs"
|
|
176
|
+
setupBackboneView(webhandle)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
This will make the module `@webhandle/backbone-view` available on the browser (if you're using
|
|
180
|
+
the external resource manager).
|
package/client-js/view.js
CHANGED
|
@@ -109,6 +109,9 @@ export class View {
|
|
|
109
109
|
if (!this.el) {
|
|
110
110
|
this.setElement(this._createElement(this.tagName))
|
|
111
111
|
}
|
|
112
|
+
else {
|
|
113
|
+
this._addListeners()
|
|
114
|
+
}
|
|
112
115
|
this._setAttributes()
|
|
113
116
|
if (this.className) {
|
|
114
117
|
this.el.classList.add(this.className)
|
|
@@ -198,3 +201,4 @@ export class View {
|
|
|
198
201
|
}
|
|
199
202
|
}
|
|
200
203
|
}
|
|
204
|
+
|
package/package.json
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webhandle/backbone-view",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "client-js/index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"client-js-compress": "npx uglifyjs public/js/pages.cjs -o public/js/pages.min.cjs -c --source-map url=public/js/pages.min.cjs.map",
|
|
12
|
-
"client-js-browserify-build": "npm run client-js-pages-browserify-build",
|
|
13
|
-
"client-js-pages-browserify build": "npx browserify client-js/pages.cjs --debug | npx exorcist public/js/pages.cjs.map > public/js/pages.cjs",
|
|
14
|
-
"dev-less-watch": "onchange 'less/**/*.less' -- npm run less-build",
|
|
15
|
-
"dev-client-js-watch": "onchange 'client-js/**/*js' 'client-js-test/**/*js' -- npm run client-js-build",
|
|
16
|
-
"dev-server-js-watch": "onchange 'server-js/**/*js' -- pm2 restart $npm_package_name-web",
|
|
17
|
-
"start": "node ./web-server.js",
|
|
18
|
-
"testDebug": "node --inspect-brk node_modules/mocha/bin/mocha",
|
|
19
|
-
"bg": "parallelshell 'npm run dev-less-watch' 'npm run dev-client-js-watch'",
|
|
20
|
-
"pm2-bg": "parallelshell 'npm run dev-less-watch' 'npm run dev-client-js-watch' 'npm run dev-server-js-watch'",
|
|
21
|
-
"dev": "parallelshell 'npm run start' 'npm run dev-less-watch' 'npm run dev-client-js-watch'"
|
|
7
|
+
"test": "node test/test-view-utils.mjs",
|
|
8
|
+
"client-js-build": "webpack-cli --config backbone-view.webpack.cjs",
|
|
9
|
+
"start": "run-webhandle './client-js-test/test-server.mjs'",
|
|
10
|
+
"pm2-bg": "webpack-cli --watch --config backbone-view.webpack.cjs"
|
|
22
11
|
},
|
|
23
12
|
"repository": {
|
|
24
13
|
"type": "git",
|
|
@@ -35,23 +24,7 @@
|
|
|
35
24
|
"author": "Dan Kolz",
|
|
36
25
|
"license": "ISC",
|
|
37
26
|
"devDependencies": {
|
|
38
|
-
"
|
|
39
|
-
"chai": "^4.3.4",
|
|
40
|
-
"exorcist": "^2.0.0",
|
|
41
|
-
"express": "^4.17.1",
|
|
42
|
-
"file-sink": "^1.0.4",
|
|
43
|
-
"filter-log": "0.0.5",
|
|
44
|
-
"input-value-injector": "^1.0.8",
|
|
45
|
-
"less": "^3.10.3",
|
|
46
|
-
"mocha": "^9.1.3",
|
|
47
|
-
"node-polyfill-webpack-plugin": "^2.0.1",
|
|
48
|
-
"onchange": "^3.2.1",
|
|
49
|
-
"parallelshell": "3.0.1",
|
|
50
|
-
"tripartite": "^1.1.1",
|
|
51
|
-
"uglify-js": "^3.17.4",
|
|
52
|
-
"webhandle": "^1.0.32",
|
|
53
|
-
"webhandle-js-widget-setup": "^1.0.5",
|
|
54
|
-
"webpack-cli": "^5.1.4"
|
|
27
|
+
"@webhandle/test-assert": "^1.0.1"
|
|
55
28
|
},
|
|
56
29
|
"browserify": {
|
|
57
30
|
"transform": [
|
|
@@ -61,6 +34,10 @@
|
|
|
61
34
|
"files": [
|
|
62
35
|
"/client-js",
|
|
63
36
|
"README.md"
|
|
37
|
+
, "public/js"
|
|
64
38
|
],
|
|
65
|
-
"type": "module"
|
|
39
|
+
"type": "module",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@webhandle/initialize-webhandle-component": "^1.0.1"
|
|
42
|
+
}
|
|
66
43
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e={};function t([e,t]){let i=(e=e.trim()).split(" "),s=i.shift().trim(),r=i.join(" ").trim();return"string"==typeof t&&(t=t.trim()),{event:s,selector:r,handler:t}}e.d=(t,i)=>{for(var s in i)e.o(i,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},e.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);let i={tagName:"div",events:{}};class s{constructor(e){this.id=function(){let e=new Uint8Array(32);window.crypto.getRandomValues(e);let t=btoa(e);return t=t.replace(/\//g,"_").replace(/\+/g,"-").replace(/=+$/,""),t}(),Object.assign(this,i),this.preinitialize.apply(this,arguments),Object.assign(this,e),this._ensureElement(),this.initialize.apply(this,arguments)}preinitialize(){}initialize(){}render(){return this}remove(){this.el.parentElement.removeChild(this.el)}appendTo(e){e.appendChild(this.el)}replaceContentsOf(e){e.innerHTML="",this.appendTo(e)}setElement(e){return this.el!==e&&(this.el=e,this._addListeners()),this}_createElement(e){let t=document.createElement(e);return t.setAttribute("id",this.id),t.view=this,t}_ensureElement(){this.el?this._addListeners():this.setElement(this._createElement(this.tagName)),this._setAttributes(),this.className&&this.el.classList.add(this.className)}_setAttributes(e){if(this.attributes)for(let[e,t]of Object.entries(this.attributes))this.el.setAttribute(e,t)}_addListeners(){this.eventTriggers=Object.entries(this.events).map(t);let e=(i=this.eventTriggers,Array.from(i.reduce((e,t)=>(e.add(t.event),e),new Set)));var i;for(let t of e)this.el.addEventListener(t,this._eventHandler.bind(this))}_getCandidates(e){return"."===e?[this.el]:Array.from(this.el.querySelectorAll(e))}_eventHandler(e){for(let t of this.eventTriggers)if(e.type==t.event){let i=this._getCandidates(t.selector),s=null;for(let t of i)if(t===e.target||t.contains(e.target)){s=t;break}if(s){"string"==typeof t.handler?this[t.handler].call(this,e,s):"function"==typeof t.handler&&t.handler.call(this,e,s);break}}}}export{s as View};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","mappings":"AACA,IAAIA,EAAsB,CAAC,ECDZ,SAASC,GAAkBC,EAAKC,IAE9C,IAAIC,GADJF,EAAMA,EAAIG,QACMC,MAAM,KAClBC,EAAQH,EAAMI,QAAQH,OACtBI,EAAWL,EAAMM,KAAK,KAAKL,OAM/B,MAJoB,iBAAVF,IACTA,EAAQA,EAAME,QAGR,CACNE,MAAOA,EACPE,SAAUA,EACVE,QAASR,EAEX,CCdAH,EAAoBY,EAAI,CAACC,EAASC,KACjC,IAAI,IAAIZ,KAAOY,EACXd,EAAoBe,EAAED,EAAYZ,KAASF,EAAoBe,EAAEF,EAASX,IAC5Ec,OAAOC,eAAeJ,EAASX,EAAK,CAAEgB,YAAY,EAAMC,IAAKL,EAAWZ,MCJ3EF,EAAoBe,EAAI,CAACK,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCKlF,IAAII,EAAiB,CAEpBC,QAAS,MAEPC,OAAQ,CAAC,GASL,MAAMC,EACZ,WAAAC,CAAYC,GACXC,KAAKC,GCfQ,WACd,IAAIC,EAAQ,IAAIC,WAAW,IAC3BC,OAAOC,OAAOC,gBAAgBJ,GAC9B,IAAI9B,EAAQmC,KAAKL,GAEjB,OADA9B,EAAQA,EAAMoC,QAAQ,MAAO,KAAKA,QAAQ,MAAO,KAAKA,QAAQ,MAAO,IAC9DpC,CACR,CDSYqC,GACVxB,OAAOyB,OAAOV,KAAMN,GACpBM,KAAKW,cAAcC,MAAMZ,KAAMa,WAC/B5B,OAAOyB,OAAOV,KAAMD,GACpBC,KAAKc,iBACLd,KAAKe,WAAWH,MAAMZ,KAAMa,UAC7B,CAOA,aAAAF,GAAkB,CAMlB,UAAAI,GAAe,CAQf,MAAAC,GACC,OAAOhB,IACR,CAKA,MAAAiB,GACCjB,KAAKkB,GAAGC,cAAcC,YAAYpB,KAAKkB,GACxC,CAOA,QAAAG,CAASC,GACRA,EAAUC,YAAYvB,KAAKkB,GAC5B,CAMA,iBAAAM,CAAkBF,GACjBA,EAAUG,UAAY,GACtBzB,KAAKqB,SAASC,EACf,CAQA,UAAAI,CAAWR,GAKV,OAJIlB,KAAKkB,KAAOA,IACflB,KAAKkB,GAAKA,EACVlB,KAAK2B,iBAEC3B,IACR,CAQA,cAAA4B,CAAeC,GACd,IAAIX,EAAKY,SAASC,cAAcF,GAGhC,OAFAX,EAAGc,aAAa,KAAMhC,KAAKC,IAC3BiB,EAAGe,KAAOjC,KACHkB,CACR,CAMA,cAAAJ,GACMd,KAAKkB,GAITlB,KAAK2B,gBAHL3B,KAAK0B,WAAW1B,KAAK4B,eAAe5B,KAAKL,UAK1CK,KAAKkC,iBACDlC,KAAKmC,WACRnC,KAAKkB,GAAGkB,UAAUC,IAAIrC,KAAKmC,UAE7B,CAOA,cAAAD,CAAeI,GACd,GAAItC,KAAKsC,WACR,IAAK,IAAKnE,EAAKC,KAAUa,OAAOsD,QAAQvC,KAAKsC,YAC5CtC,KAAKkB,GAAGc,aAAa7D,EAAKC,EAG7B,CAqBA,aAAAuD,GACC3B,KAAKwC,cAAgBvD,OAAOsD,QAAQvC,KAAKJ,QAAQ6C,IAAIvE,GACrD,IAAIwE,GE1JoCF,EF0JLxC,KAAKwC,cEzJxBG,MAAMC,KAAKJ,EAAcK,OAAO,CAACC,EAAKC,KACtDD,EAAIT,IAAIU,EAAQvE,OACTsE,GACL,IAAIE,OAJO,IAA2BR,EF4JxC,IAAI,IAAIS,KAAaP,EACpB1C,KAAKkB,GAAGgC,iBAAiBD,EAAWjD,KAAKmD,cAAcC,KAAKpD,MAE9D,CAOA,cAAAqD,CAAe3E,GACd,MAAgB,MAAbA,EACK,CAACsB,KAAKkB,IAEPyB,MAAMC,KAAK5C,KAAKkB,GAAGoC,iBAAiB5E,GAC5C,CAQA,aAAAyE,CAAcI,GACb,IAAI,IAAIR,KAAW/C,KAAKwC,cACvB,GAAGe,EAAIC,MAAQT,EAAQvE,MAAO,CAC7B,IAAIiF,EAAazD,KAAKqD,eAAeN,EAAQrE,UACzCgF,EAAQ,KACZ,IAAI,IAAIC,KAAaF,EACpB,GAAGE,IAAcJ,EAAIK,QAAUD,EAAUE,SAASN,EAAIK,QAAS,CAC9DF,EAAQC,EACR,KACD,CAED,GAAGD,EAAO,CACqB,iBAApBX,EAAQnE,QACjBoB,KAAK+C,EAAQnE,SAASa,KAAKO,KAAMuD,EAAKG,GAEJ,mBAApBX,EAAQnE,SACtBmE,EAAQnE,QAAQa,KAAKO,KAAMuD,EAAKG,GAEjC,KACD,CACD,CAEF,S","sources":["webpack://@webhandle/backbone-view/webpack/bootstrap","webpack://@webhandle/backbone-view/./client-js/event-entry-mapper.js","webpack://@webhandle/backbone-view/webpack/runtime/define property getters","webpack://@webhandle/backbone-view/webpack/runtime/hasOwnProperty shorthand","webpack://@webhandle/backbone-view/./client-js/view.js","webpack://@webhandle/backbone-view/./client-js/generate-id.js","webpack://@webhandle/backbone-view/./client-js/extract-event-names.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","export default function eventEntryMapper([key, value]) {\n\tkey = key.trim()\n\tlet parts = key.split(' ')\n\tlet event = parts.shift().trim()\n\tlet selector = parts.join(' ').trim()\n\t\n\tif(typeof value === 'string') {\n\t\tvalue = value.trim()\n\t}\t\n\t\n\treturn {\n\t\tevent: event,\n\t\tselector: selector,\n\t\thandler: value\n\t}\n}","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import generateId from \"./generate-id.js\"\n// import pick from \"./pick.js\"\nimport eventEntryMapper from \"./event-entry-mapper.js\"\nimport extractEventNames from \"./extract-event-names.js\"\n\nlet defaultOptions = {\n\t// The default `tagName` of a View's element is `\"div\"`.\n\ttagName: 'div'\n\t\n\t, events: {}\n\n}\nlet viewOptions = ['model', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];\n\n/**\n * A way to connect data to be displayed, a way to display it, and an organization\n * of functions to handle events.\n */\nexport class View {\n\tconstructor(options) {\n\t\tthis.id = generateId()\n\t\tObject.assign(this, defaultOptions)\n\t\tthis.preinitialize.apply(this, arguments);\n\t\tObject.assign(this, options)\n\t\tthis._ensureElement()\n\t\tthis.initialize.apply(this, arguments);\n\t}\n\n\n\t/**\n\t * preinitialize is an empty function by default. You can override it with a function\n\t * or object. preinitialize will run before any instantiation logic is run in the View\n\t */\n\tpreinitialize() { }\n\n\t/**\n\t * Initialize is an empty function by default. Override it with your own\n\t * initialization logic.\n\t */\n\tinitialize() { }\n\n\t/**\n\t * **render** is the core function that your view should override, in order\n\t * to populate its element (`this.el`), with the appropriate HTML. The\n\t * convention is for **render** to always return `this`.\n\t * @returns this\n\t */\n\trender() {\n\t\treturn this\n\t}\n\t\n\t/**\n\t * Removes the element from the dom. Does not disable event listeners\n\t */\n\tremove() {\n\t\tthis.el.parentElement.removeChild(this.el)\n\t}\n\t\n\t/**\n\t * Adds this view as a child to a containing element. Nothing special is going on here.\n\t * This is just a shortcut for container.appendChild\n\t * @param {Element} container \n\t */\n\tappendTo(container) {\n\t\tcontainer.appendChild(this.el)\n\t}\n\n\t/**\n\t * Clears the contents of the container and adds this view.\n\t * @param {Element} container \n\t */\n\treplaceContentsOf(container) {\n\t\tcontainer.innerHTML = ''\n\t\tthis.appendTo(container)\n\t}\n\n\t/**\n\t * Set the element for this view, and if new, adds listeners to it in accordance\n\t * with the \"events\" member.\n\t * @param {Element} el The dom element which will be the root of this view\n\t * @returns this\n\t */\n\tsetElement(el) {\n\t\tif (this.el !== el) {\n\t\t\tthis.el = el\n\t\t\tthis._addListeners()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Produces a DOM element to be assigned to your view. Exposed for\n\t * subclasses using an alternative DOM manipulation API.\n\t * @param {string} name The element tag name\n\t * @returns The dom element\n\t */\n\t_createElement(name) {\n\t\tlet el = document.createElement(name)\n\t\tel.setAttribute('id', this.id)\n\t\tel.view = this\n\t\treturn el\n\t}\n\n\t/**\n\t * Ensures that the element exists. Applies attributes and className\n\t * to it regardless\n\t */\n\t_ensureElement() {\n\t\tif (!this.el) {\n\t\t\tthis.setElement(this._createElement(this.tagName))\n\t\t}\n\t\telse {\n\t\t\tthis._addListeners()\n\t\t}\n\t\tthis._setAttributes()\n\t\tif (this.className) {\n\t\t\tthis.el.classList.add(this.className)\n\t\t}\n\t}\n\n\t/**\n\t * Set attributes from a hash on this view's element. Exposed for\n\t * subclasses using an alternative DOM manipulation API.\n\t * @param {object} attributes \n\t */\n\t_setAttributes(attributes) {\n\t\tif (this.attributes) {\n\t\t\tfor (let [key, value] of Object.entries(this.attributes)) {\n\t\t\t\tthis.el.setAttribute(key, value)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * \n\t * Set callbacks, where `this.events` is a hash of\n\t * *{\"event selector\": \"callback\"}*\n\t *\n\t * {\n\t * 'mousedown .title': 'edit',\n\t * 'click .button': 'save',\n\t * 'click .open': function(e) { ... },\n\t * 'keydown .': \t 'handleKey'\n\t * }\n\t * pairs. Callbacks will be bound to the view, with `this` set properly.\n\t * \n\t * \n\t * Note that the selector `.` will match the root element and can be used\n\t * as a final chance to handle events or for events like an escape key\n\t * which are essentially global to the widget.\n\t * \n\t */\n\t_addListeners() {\n\t\tthis.eventTriggers = Object.entries(this.events).map(eventEntryMapper)\n\t\tlet eventNames = extractEventNames(this.eventTriggers)\t\t\n\n\t\tfor(let eventName of eventNames) {\n\t\t\tthis.el.addEventListener(eventName, this._eventHandler.bind(this))\n\t\t}\n\t}\n\t\n\t/**\n\t * Get the elements from the view which match the selector\n\t * @param {string} selector A css selector. `.` will select the root element\n\t * @returns An array of elements\n\t */\n\t_getCandidates(selector) {\n\t\tif(selector === '.') {\n\t\t\treturn [this.el]\n\t\t}\n\t\treturn Array.from(this.el.querySelectorAll(selector))\n\t}\n\t\n\t/**\n\t * Handles all events for all elements within the view. It attempts to find a\n\t * trigger matching the event and then process it. It will match and invoke\n\t * only one trigger.\n\t * @param {Event} evt \n\t */\n\t_eventHandler(evt) {\n\t\tfor(let trigger of this.eventTriggers) {\n\t\t\tif(evt.type == trigger.event) {\n\t\t\t\tlet candidates = this._getCandidates(trigger.selector)\n\t\t\t\tlet found = null\n\t\t\t\tfor(let candidate of candidates) {\n\t\t\t\t\tif(candidate === evt.target || candidate.contains(evt.target)) {\n\t\t\t\t\t\tfound = candidate\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(found) {\n\t\t\t\t\tif(typeof trigger.handler === 'string') {\n\t\t\t\t\t\tthis[trigger.handler].call(this, evt, found)\n\t\t\t\t\t}\t\n\t\t\t\t\telse if(typeof trigger.handler === 'function') {\n\t\t\t\t\t\ttrigger.handler.call(this, evt, found)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n","/**\n * Generates a random string id in the browser. Will probably not work\n * on the server.\n * @returns A base64 web url safe string\n */\nexport default function generateId() {\n\tlet array = new Uint8Array(32)\n\twindow.crypto.getRandomValues(array)\n\tlet value = btoa(array)\n\tvalue = value.replace(/\\//g, \"_\").replace(/\\+/g, \"-\").replace(/=+$/, \"\")\n\treturn value\n}","export default function extractEventNames(eventTriggers) {\n\tlet eventNames = Array.from(eventTriggers.reduce((acc, trigger) => {\n\t\tacc.add(trigger.event)\n\t\treturn acc\n\t}, new Set()))\n\treturn eventNames\n}"],"names":["__webpack_require__","eventEntryMapper","key","value","parts","trim","split","event","shift","selector","join","handler","d","exports","definition","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","defaultOptions","tagName","events","View","constructor","options","this","id","array","Uint8Array","window","crypto","getRandomValues","btoa","replace","generateId","assign","preinitialize","apply","arguments","_ensureElement","initialize","render","remove","el","parentElement","removeChild","appendTo","container","appendChild","replaceContentsOf","innerHTML","setElement","_addListeners","_createElement","name","document","createElement","setAttribute","view","_setAttributes","className","classList","add","attributes","entries","eventTriggers","map","eventNames","Array","from","reduce","acc","trigger","Set","eventName","addEventListener","_eventHandler","bind","_getCandidates","querySelectorAll","evt","type","candidates","found","candidate","target","contains"],"sourceRoot":""}
|