compex-sinatra 0.1.0
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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +12 -0
- data/lib/compex/sinatra/version.rb +7 -0
- data/lib/compex/sinatra.rb +160 -0
- data/sample/app.rb +118 -0
- data/sample/public/bundle.js +591 -0
- data/sample/public/bundle.js.map +7 -0
- metadata +53 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8e6491a833f9a894746517767d7633e3e1e40e9cf7a17041546d149aadf67a43
|
|
4
|
+
data.tar.gz: 56eba6739cd4558f535a9d6da9f8ca4c886ba627059dfcb11f45a4e36eea1e5d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7c410f0e7f41ed38f380d0ac7568b43ee7452d8683c0bb37d41f1d9984d382b01a1c12b0d83d3062aad4cf2a9dba5f4793078df6ab92eda2eba3d0e01c65562c
|
|
7
|
+
data.tar.gz: 6f6d69564b820c8b577f01ef57acbe10975c8a1924e582b97ff36d971f97f819ba52c8d2f57ddf61db9691acedab4a5110de7fed760abaaacb3879019d6ac4fc
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vito Sartori
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Compex::Sinatra
|
|
2
|
+
|
|
3
|
+
TODO: Delete this and the text below, and describe your gem
|
|
4
|
+
|
|
5
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/compex/sinatra`. To experiment with that code, run `bin/console` for an interactive prompt.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
|
10
|
+
|
|
11
|
+
Install the gem and add to the application's Gemfile by executing:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
TODO: Write usage instructions here
|
|
26
|
+
|
|
27
|
+
## Development
|
|
28
|
+
|
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
30
|
+
|
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
32
|
+
|
|
33
|
+
## Contributing
|
|
34
|
+
|
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/compex-sinatra. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/compex-sinatra/blob/master/CODE_OF_CONDUCT.md).
|
|
36
|
+
|
|
37
|
+
## License
|
|
38
|
+
|
|
39
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
40
|
+
|
|
41
|
+
## Code of Conduct
|
|
42
|
+
|
|
43
|
+
Everyone interacting in the Compex::Sinatra project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/compex-sinatra/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sinatra/base'
|
|
4
|
+
require 'compex'
|
|
5
|
+
require 'debug'
|
|
6
|
+
|
|
7
|
+
require_relative "sinatra/version"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
module Sinatra
|
|
11
|
+
module CompEx
|
|
12
|
+
SINATRA_REQUIRED_HASHES_KEY = '__compex_sinatra_required_hashes'
|
|
13
|
+
|
|
14
|
+
def _get_template_engine
|
|
15
|
+
settings.respond_to?(:template_engine) ? settings.template_engine : nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def component(klass, **props)
|
|
19
|
+
layout_name = props.delete(:layout) || :layout
|
|
20
|
+
engine = props.delete(:engine) || _get_template_engine || :erb
|
|
21
|
+
layout_entry = settings.templates[layout_name]
|
|
22
|
+
|
|
23
|
+
# Do not include layouts when loading via XHR
|
|
24
|
+
layout_entry = nil unless request.env['HTTP_X_COMPEX_LOAD'].nil?
|
|
25
|
+
|
|
26
|
+
comp = klass.new(**props)
|
|
27
|
+
html = comp.render_html
|
|
28
|
+
|
|
29
|
+
request.env[SINATRA_REQUIRED_HASHES_KEY] =
|
|
30
|
+
if request.env.key?(SINATRA_REQUIRED_HASHES_KEY)
|
|
31
|
+
request.env[SINATRA_REQUIRED_HASHES_KEY]
|
|
32
|
+
.append(*comp.required_hashes)
|
|
33
|
+
.uniq
|
|
34
|
+
else
|
|
35
|
+
comp.required_hashes
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if layout_entry
|
|
39
|
+
proc, _file, _line = layout_entry
|
|
40
|
+
source = proc.call
|
|
41
|
+
Tilt[engine].new { source }.render(self) { html }
|
|
42
|
+
else
|
|
43
|
+
html
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module Helpers
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class RequiredHashesInjector
|
|
51
|
+
def initialize(app)
|
|
52
|
+
@app = app
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def call(env)
|
|
56
|
+
status, headers, body = @app.call(env)
|
|
57
|
+
|
|
58
|
+
if status == 200 && env[SINATRA_REQUIRED_HASHES_KEY]
|
|
59
|
+
headers['X-CompEx-RequiredHashes'] = env[SINATRA_REQUIRED_HASHES_KEY].join(',')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
[status, headers, body]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class ScriptInjector
|
|
67
|
+
def initialize(app)
|
|
68
|
+
@app = app
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def call(env)
|
|
72
|
+
status, headers, body = @app.call(env)
|
|
73
|
+
return [status, headers, body] unless headers["Content-Type"]&.include?("text/html")
|
|
74
|
+
|
|
75
|
+
content = +""
|
|
76
|
+
body.each { |chunk| content << chunk }
|
|
77
|
+
body.close if body.respond_to?(:close)
|
|
78
|
+
|
|
79
|
+
# Inject scripts before </body>
|
|
80
|
+
scripts = env.fetch(SINATRA_REQUIRED_HASHES_KEY, [])
|
|
81
|
+
.filter { |v| v.start_with? ("j") }
|
|
82
|
+
unless scripts.empty?
|
|
83
|
+
result = scripts.map do |id|
|
|
84
|
+
asset = ::CompEx::AssetProvider.provide(id)
|
|
85
|
+
next unless asset # TODO: Warn?
|
|
86
|
+
|
|
87
|
+
"<script type=\"text/javascript\" cx-asset=\"#{id}\">#{asset}</script>"
|
|
88
|
+
end
|
|
89
|
+
content.sub!(%r{</body>}i, "#{result.join}</body>")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
headers["Content-Length"] = content.bytesize.to_s
|
|
93
|
+
body = [content]
|
|
94
|
+
|
|
95
|
+
[status, headers, body]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class StyleInjector
|
|
100
|
+
def initialize(app)
|
|
101
|
+
@app = app
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def call(env)
|
|
105
|
+
status, headers, body = @app.call(env)
|
|
106
|
+
return [status, headers, body] unless headers["Content-Type"]&.include?("text/html")
|
|
107
|
+
|
|
108
|
+
content = +""
|
|
109
|
+
body.each { |chunk| content << chunk }
|
|
110
|
+
body.close if body.respond_to?(:close)
|
|
111
|
+
|
|
112
|
+
# Inject styles before </head>
|
|
113
|
+
styles = env.fetch(SINATRA_REQUIRED_HASHES_KEY, [])
|
|
114
|
+
.filter { |v| v.start_with? ("c") }
|
|
115
|
+
unless styles.empty?
|
|
116
|
+
result = styles.map do |id|
|
|
117
|
+
asset = ::CompEx::AssetProvider.provide(id)
|
|
118
|
+
next unless asset # TODO: Warn?
|
|
119
|
+
|
|
120
|
+
"<style cx-asset=\"#{id}\">#{asset}</style>"
|
|
121
|
+
end
|
|
122
|
+
content.sub!(%r{</head>}i, "#{result.join}</head>")
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
headers["Content-Length"] = content.bytesize.to_s
|
|
126
|
+
body = [content]
|
|
127
|
+
|
|
128
|
+
[status, headers, body]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.registered(app)
|
|
133
|
+
app.helpers Sinatra::CompEx::Helpers
|
|
134
|
+
app.use Sinatra::CompEx::RequiredHashesInjector
|
|
135
|
+
app.use Sinatra::CompEx::StyleInjector
|
|
136
|
+
app.use Sinatra::CompEx::ScriptInjector
|
|
137
|
+
|
|
138
|
+
app.get '/_compex/assets' do
|
|
139
|
+
hashes = request.params.fetch('h', '').split(',').map(&:strip)
|
|
140
|
+
result = []
|
|
141
|
+
hashes.each do |h|
|
|
142
|
+
asset = ::CompEx::AssetProvider.provide(h)
|
|
143
|
+
next result << nil unless asset
|
|
144
|
+
|
|
145
|
+
result << {
|
|
146
|
+
type: h.start_with?("j_") ? "script" : "style",
|
|
147
|
+
hash: h,
|
|
148
|
+
source: asset,
|
|
149
|
+
}
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
headers "Content-Type" => "application/json"
|
|
153
|
+
result.to_json
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
helpers Sinatra::CompEx
|
|
159
|
+
register Sinatra::CompEx
|
|
160
|
+
end
|
data/sample/app.rb
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'compex/sinatra'
|
|
2
|
+
|
|
3
|
+
require 'sinatra'
|
|
4
|
+
|
|
5
|
+
class MyComponent < CompEx::Base
|
|
6
|
+
html <<~HTML
|
|
7
|
+
<div class="base">
|
|
8
|
+
<Counter />
|
|
9
|
+
<MyForm cx-on:namespace:eventName="customHandler" />
|
|
10
|
+
</div>
|
|
11
|
+
HTML
|
|
12
|
+
|
|
13
|
+
style <<~CSS
|
|
14
|
+
.base { font-family: sans-serif; }
|
|
15
|
+
CSS
|
|
16
|
+
|
|
17
|
+
js <<~JS
|
|
18
|
+
class Component {
|
|
19
|
+
onClick(ev) { console.log("OnClick", ev) }
|
|
20
|
+
customHandler(ev) { console.log("customHandler", ev) }
|
|
21
|
+
}
|
|
22
|
+
JS
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class Counter < CompEx::Base
|
|
26
|
+
html <<~HTML
|
|
27
|
+
<div>
|
|
28
|
+
<div cx-ref="counter">0</div>
|
|
29
|
+
<button cx-click="onIncr">+</button><button cx-click="onDecr">-</button>
|
|
30
|
+
</div>
|
|
31
|
+
HTML
|
|
32
|
+
|
|
33
|
+
js <<~JS
|
|
34
|
+
class Component {
|
|
35
|
+
async mount() {
|
|
36
|
+
this.value = 0;
|
|
37
|
+
this.updateText();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
updateText() {
|
|
41
|
+
this.counter.innerText = `${this.value}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
onIncr() {
|
|
45
|
+
this.value++;
|
|
46
|
+
this.updateText();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
onDecr() {
|
|
50
|
+
this.value--;
|
|
51
|
+
this.updateText();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
JS
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class MyForm < CompEx::Base
|
|
58
|
+
html <<~HTML
|
|
59
|
+
Accepted? <input type="checkbox" cx-bind="accepted" cx-change="onChange" /> <br/>
|
|
60
|
+
<input type="checkbox" cx-bind="bla" value="a" />
|
|
61
|
+
<input type="checkbox" cx-bind="bla" value="b" />
|
|
62
|
+
<input type="checkbox" cx-bind="bla" value="c" /> <br/>
|
|
63
|
+
<input type="radio" cx-bind="ble" value="a" />
|
|
64
|
+
<input type="radio" cx-bind="ble" value="b" />
|
|
65
|
+
<input type="radio" cx-bind="ble" value="c" /> <br />
|
|
66
|
+
<select cx-bind="bli">
|
|
67
|
+
<option value="foo">Foo</option>
|
|
68
|
+
<option value="bar">Bar</option>
|
|
69
|
+
<option value="baz">Baz</option>
|
|
70
|
+
</select> <br />
|
|
71
|
+
<select multiple cx-bind="blo">
|
|
72
|
+
<option value="foo">Foo</option>
|
|
73
|
+
<option value="bar">Bar</option>
|
|
74
|
+
<option value="baz">Baz</option>
|
|
75
|
+
</select><br/>
|
|
76
|
+
<button cx-click="dispatchCustomEvent">Custom Event</button>
|
|
77
|
+
HTML
|
|
78
|
+
|
|
79
|
+
js <<~JS
|
|
80
|
+
class Component {
|
|
81
|
+
async mount() {
|
|
82
|
+
window.xxx = this;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
onChange(el) {
|
|
86
|
+
debugger;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
dispatchCustomEvent() {
|
|
90
|
+
this.emit("namespace:eventName", { test: true });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
JS
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
set :template_engine, :erb
|
|
97
|
+
|
|
98
|
+
template(:layout) do
|
|
99
|
+
<<~HTML
|
|
100
|
+
<!DOCTYPE html>
|
|
101
|
+
<html>
|
|
102
|
+
<head>
|
|
103
|
+
<meta charset="utf-8">
|
|
104
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
105
|
+
<title>My App</title>
|
|
106
|
+
<script type="text/javascript" src="bundle.js"></script>
|
|
107
|
+
</head>
|
|
108
|
+
<body>
|
|
109
|
+
<%= yield %>
|
|
110
|
+
</body>
|
|
111
|
+
</html>
|
|
112
|
+
HTML
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
get '/' do
|
|
117
|
+
component(MyComponent)
|
|
118
|
+
end
|
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
|
|
23
|
+
// src/utils.js
|
|
24
|
+
var utils_exports = {};
|
|
25
|
+
__export(utils_exports, {
|
|
26
|
+
default: () => utils_default
|
|
27
|
+
});
|
|
28
|
+
var Utils, utils_default;
|
|
29
|
+
var init_utils = __esm({
|
|
30
|
+
"src/utils.js"() {
|
|
31
|
+
Utils = {
|
|
32
|
+
isCheckable(node) {
|
|
33
|
+
const name = node.nodeName;
|
|
34
|
+
const type = node.type;
|
|
35
|
+
return name && name.toLowerCase() === "input" && (type === "checkbox" || type === "radio");
|
|
36
|
+
},
|
|
37
|
+
getValueForNode(node) {
|
|
38
|
+
let value = "";
|
|
39
|
+
if (!node) return value;
|
|
40
|
+
value = this.isCheckable(node) ? node.checked : node.value;
|
|
41
|
+
return value;
|
|
42
|
+
},
|
|
43
|
+
setValueForNode(node, value) {
|
|
44
|
+
if (!node) return;
|
|
45
|
+
if (this.isCheckable(node)) {
|
|
46
|
+
node.checked = value !== "false" && !!value;
|
|
47
|
+
} else {
|
|
48
|
+
node.value = value;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
getSelectionForNode(node) {
|
|
52
|
+
if ("selectionStart" in node) {
|
|
53
|
+
return {
|
|
54
|
+
start: node.selectionStart,
|
|
55
|
+
end: node.selectionEnd
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return { start: 0, end: 0 };
|
|
59
|
+
},
|
|
60
|
+
setSelectionForNode(node, bounds) {
|
|
61
|
+
if (!("selectionStart" in node)) return;
|
|
62
|
+
const start = bounds.start;
|
|
63
|
+
let end = bounds.end;
|
|
64
|
+
if (end === void 0) end = start;
|
|
65
|
+
node.selectionStart = start;
|
|
66
|
+
node.selectionEnd = Math.min(end, node.value.length);
|
|
67
|
+
},
|
|
68
|
+
randomID() {
|
|
69
|
+
const bytes = new Uint8Array(8);
|
|
70
|
+
crypto.getRandomValues(bytes);
|
|
71
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
utils_default = Utils;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// src/eventing.js
|
|
79
|
+
var eventing_exports = {};
|
|
80
|
+
__export(eventing_exports, {
|
|
81
|
+
default: () => eventing_default
|
|
82
|
+
});
|
|
83
|
+
var globalEventsListener, SyntheticEvent, Eventing, eventing_default;
|
|
84
|
+
var init_eventing = __esm({
|
|
85
|
+
"src/eventing.js"() {
|
|
86
|
+
globalEventsListener = "_compex_install" + Math.random().toString(36).slice(2);
|
|
87
|
+
SyntheticEvent = class {
|
|
88
|
+
constructor(type, target = null, options = {}) {
|
|
89
|
+
const {
|
|
90
|
+
detail = null,
|
|
91
|
+
bubbles = false,
|
|
92
|
+
cancelable = false,
|
|
93
|
+
composed = false
|
|
94
|
+
} = options || {};
|
|
95
|
+
this.type = String(type);
|
|
96
|
+
this.target = target;
|
|
97
|
+
this.currentTarget = null;
|
|
98
|
+
this.eventPhase = 0;
|
|
99
|
+
this.bubbles = !!bubbles;
|
|
100
|
+
this.cancelable = !!cancelable;
|
|
101
|
+
this.composed = !!composed;
|
|
102
|
+
this.detail = detail;
|
|
103
|
+
this.defaultPrevented = false;
|
|
104
|
+
this.cancelBubble = false;
|
|
105
|
+
this.timeStamp = performance.now();
|
|
106
|
+
this._path = null;
|
|
107
|
+
}
|
|
108
|
+
stopPropagation() {
|
|
109
|
+
this.cancelBubble = true;
|
|
110
|
+
}
|
|
111
|
+
stopImmediatePropagation() {
|
|
112
|
+
this.cancelBubble = true;
|
|
113
|
+
this._immediateStopped = true;
|
|
114
|
+
}
|
|
115
|
+
preventDefault() {
|
|
116
|
+
if (this.cancelable) {
|
|
117
|
+
this.defaultPrevented = true;
|
|
118
|
+
this.returnValue = false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
composedPath() {
|
|
122
|
+
if (this._path) return [...this._path];
|
|
123
|
+
const path = [];
|
|
124
|
+
let node = this.target;
|
|
125
|
+
while (node) {
|
|
126
|
+
path.push(node);
|
|
127
|
+
node = node.parent || node.host || null;
|
|
128
|
+
}
|
|
129
|
+
return path;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
Eventing = class _Eventing {
|
|
133
|
+
static eventListenerSet = /* @__PURE__ */ new Set();
|
|
134
|
+
static domEventTypes = ["abort", "beforeinput", "beforetoggle", "blur", "canplay", "canplaythrough", "cancel", "change", "click", "close", "compositionend", "compositionstart", "compositionupdate", "contextmenu", "copy", "cut", "dblclick", "auxclick", "drag", "dragend", "dragenter", "dragexit", "dragleave", "dragover", "dragstart", "drop", "durationchange", "emptied", "encrypted", "ended", "error", "focus", "focusin", "focusout", "fullscreenchange", "gotpointercapture", "hashchange", "input", "invalid", "keydown", "keypress", "keyup", "load", "loadstart", "loadeddata", "loadedmetadata", "lostpointercapture", "message", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup", "paste", "pause", "play", "playing", "pointercancel", "pointerdown", "pointerenter", "pointerleave", "pointermove", "pointerout", "pointerover", "pointerup", "popstate", "progress", "ratechange", "reset", "resize", "scroll", "scrollend", "seeked", "seeking", "select", "selectstart", "selectionchange", "stalled", "submit", "suspend", "timeupdate", "toggle", "touchcancel", "touchend", "touchmove", "touchstart", "volumechange", "waiting", "wheel"];
|
|
135
|
+
// List of events that need to be individually attached to media elements.
|
|
136
|
+
static mediaEventTypes = ["abort", "canplay", "canplaythrough", "durationchange", "emptied", "encrypted", "ended", "error", "loadeddata", "loadedmetadata", "loadstart", "pause", "play", "playing", "progress", "ratechange", "resize", "seeked", "seeking", "stalled", "suspend", "timeupdate", "volumechange", "waiting"];
|
|
137
|
+
// We should not delegate these events to the container, but rather
|
|
138
|
+
// set them on the actual target element itself. This is primarily
|
|
139
|
+
// because these events do not consistently bubble in the DOM.
|
|
140
|
+
static nonDelegatedEvents = /* @__PURE__ */ new Set([
|
|
141
|
+
"beforetoggle",
|
|
142
|
+
"cancel",
|
|
143
|
+
"close",
|
|
144
|
+
"invalid",
|
|
145
|
+
"load",
|
|
146
|
+
"scroll",
|
|
147
|
+
"scrollend",
|
|
148
|
+
"toggle",
|
|
149
|
+
// In order to reduce bytes, we insert the above array of media events
|
|
150
|
+
// into this Set. Note: the "error" event isn't an exclusive media event,
|
|
151
|
+
// and can occur on other elements too. Rather than duplicate that event,
|
|
152
|
+
// we just take it from the media events array.
|
|
153
|
+
...this.mediaEventTypes
|
|
154
|
+
]);
|
|
155
|
+
static cxEventAttributes = new Set(_Eventing.domEventTypes.map((i) => `cx-${i}`));
|
|
156
|
+
static cxEventSelector = _Eventing.cxEventAttributes.values().map((i) => `:scope > :not([cx-controller]) [${i}], :scope > [${i}]`).toArray().join(",");
|
|
157
|
+
static controllerHandles = /* @__PURE__ */ new Map();
|
|
158
|
+
static eventHandles = /* @__PURE__ */ new Map();
|
|
159
|
+
static attachHandler(ctrl, el, name, handler) {
|
|
160
|
+
if (this.controllerHandles.has(ctrl)) {
|
|
161
|
+
this.controllerHandles.get(ctrl).push(handler);
|
|
162
|
+
} else {
|
|
163
|
+
this.controllerHandles.set(ctrl, [handler]);
|
|
164
|
+
}
|
|
165
|
+
this.registerHandler(el, name, handler);
|
|
166
|
+
}
|
|
167
|
+
static registerHandler(el, name, handler) {
|
|
168
|
+
if (this.eventHandles.has(name)) {
|
|
169
|
+
if (this.eventHandles.get(name).has(el)) {
|
|
170
|
+
this.eventHandles.get(name).get(el).push(handler);
|
|
171
|
+
} else {
|
|
172
|
+
this.eventHandles.get(name).set(el, [handler]);
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
this.eventHandles.set(name, /* @__PURE__ */ new Map([[el, [handler]]]));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
static installEventHandlers() {
|
|
179
|
+
if (document[globalEventsListener]) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
document[globalEventsListener] = true;
|
|
183
|
+
for (const ev of CompEx.Eventing.domEventTypes) {
|
|
184
|
+
const isCapturePhaseListener = CompEx.Eventing.nonDelegatedEvents.has(ev);
|
|
185
|
+
this.installNativeEventHandler(ev, isCapturePhaseListener);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
static installNativeEventHandler(ev, isCapturePhaseListener) {
|
|
189
|
+
const listenerSetKey = this.eventListenerKey(ev, isCapturePhaseListener);
|
|
190
|
+
if (this.eventListenerSet.has(listenerSetKey)) return;
|
|
191
|
+
document.addEventListener(ev, this.eventHandler(isCapturePhaseListener), isCapturePhaseListener);
|
|
192
|
+
this.eventListenerSet.add(listenerSetKey);
|
|
193
|
+
}
|
|
194
|
+
static eventHandler(isCapturePhaseListener) {
|
|
195
|
+
return isCapturePhaseListener ? this.captureEventHandler.bind(this) : this.bubbleEventHandler.bind(this);
|
|
196
|
+
}
|
|
197
|
+
static captureEventHandler(ev) {
|
|
198
|
+
debugger;
|
|
199
|
+
}
|
|
200
|
+
static bubbleEventHandler(ev) {
|
|
201
|
+
const handles = this.eventHandles.get(ev.type);
|
|
202
|
+
if (!handles) return;
|
|
203
|
+
const elHandlers = handles.get(ev.target);
|
|
204
|
+
if (!elHandlers) return;
|
|
205
|
+
for (const handler of elHandlers) {
|
|
206
|
+
handler(ev);
|
|
207
|
+
if (ev.defaultPrevented) return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
static dispatchSyntheticEvent(type, target, detail = null) {
|
|
211
|
+
const ev = new SyntheticEvent(type, target, detail);
|
|
212
|
+
const handles = this.eventHandles.get(ev.type);
|
|
213
|
+
if (!handles) return;
|
|
214
|
+
for (const handler of handles.values().toArray().flat()) {
|
|
215
|
+
handler(ev);
|
|
216
|
+
if (ev.defaultPrevented) return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
static eventListenerKey(name, isCapturePhaseListener) {
|
|
220
|
+
return `${name}__${isCapturePhaseListener ? "capture" : "bubble"}`;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
eventing_default = Eventing;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// src/runtime.js
|
|
228
|
+
var runtime_exports = {};
|
|
229
|
+
__export(runtime_exports, {
|
|
230
|
+
default: () => runtime_default
|
|
231
|
+
});
|
|
232
|
+
var Runtime, runtime_default;
|
|
233
|
+
var init_runtime = __esm({
|
|
234
|
+
"src/runtime.js"() {
|
|
235
|
+
Runtime = class {
|
|
236
|
+
static registry = {};
|
|
237
|
+
static instances = /* @__PURE__ */ new WeakMap();
|
|
238
|
+
static observer = new MutationObserver((muts) => {
|
|
239
|
+
for (const mut of muts) {
|
|
240
|
+
for (const node of mut.addedNodes) {
|
|
241
|
+
if (node.nodeType !== Node.ELEMENT_NODE || !node.getAttribute("cx-controller")) continue;
|
|
242
|
+
this.attachController(node);
|
|
243
|
+
}
|
|
244
|
+
for (const node of mut.removedNodes) {
|
|
245
|
+
if (node.nodeType !== Node.ELEMENT_NODE || !node.getAttribute("cx-controller")) continue;
|
|
246
|
+
this.detachController(node);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
static loadedHashesSet = /* @__PURE__ */ new Set();
|
|
251
|
+
static attachController(node) {
|
|
252
|
+
const ctrlName = node.getAttribute("cx-controller");
|
|
253
|
+
const ctrl = this.registry[ctrlName];
|
|
254
|
+
if (!ctrl) {
|
|
255
|
+
console.warn(`Missing JS controller for element ${node}: ${ctrlName}`);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const inst = new ctrl(node);
|
|
259
|
+
this.instances.set(node, inst);
|
|
260
|
+
let mountRet = inst.mount();
|
|
261
|
+
if (mountRet instanceof Promise) {
|
|
262
|
+
mountRet.catch(console.error.bind(console));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
static detachController(node) {
|
|
266
|
+
const inst = this.instances[node];
|
|
267
|
+
if (!inst) return;
|
|
268
|
+
inst.unmount().catch(console.error.bind(console)).finally(() => {
|
|
269
|
+
this.instances.delete(node);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
static install() {
|
|
273
|
+
this.installed = true;
|
|
274
|
+
CompEx.Eventing.installEventHandlers();
|
|
275
|
+
for (const el of document.querySelectorAll("[cx-controller]")) this.attachController(el);
|
|
276
|
+
for (const el of document.querySelectorAll("[cx-asset]")) this.loadedHashesSet.add(el.getAttribute("cx-asset"));
|
|
277
|
+
this.observer.observe(document, { childList: true });
|
|
278
|
+
}
|
|
279
|
+
static register(name, klass) {
|
|
280
|
+
this.registry[name] = klass;
|
|
281
|
+
console.log(`CompEx: Registered ${name}`);
|
|
282
|
+
}
|
|
283
|
+
static async handleRequiredHashesHeader(value) {
|
|
284
|
+
if (!value) return;
|
|
285
|
+
const toRequire = value.split(",").filter((v) => !this.loadedHashesSet.has(v));
|
|
286
|
+
const requireParams = new URLSearchParams([["h", toRequire]]);
|
|
287
|
+
const resp = await fetch("/_compex/assets?" + requireParams.toString(), {
|
|
288
|
+
method: "GET"
|
|
289
|
+
});
|
|
290
|
+
if (!resp.ok) {
|
|
291
|
+
console.error(resp.message);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const json = await resp.json();
|
|
295
|
+
for (const [idx, item] of json.entries()) {
|
|
296
|
+
if (!item) {
|
|
297
|
+
console.warn(`CompEx: Could not retrieve asset for hash ${toRequire[idx]}`);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
switch (item.type) {
|
|
301
|
+
case "style": {
|
|
302
|
+
const st = document.createElement("style");
|
|
303
|
+
st.setAttribute("cx-asset", item.hash);
|
|
304
|
+
st.textContent = item.source;
|
|
305
|
+
document.head.append(st);
|
|
306
|
+
this.loadedHashesSet.add(item.hash);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
case "script": {
|
|
310
|
+
const sc = document.createElement("script");
|
|
311
|
+
sc.setAttribute("cx-asset", item.hash);
|
|
312
|
+
sc.innerHTML = item.source;
|
|
313
|
+
document.head.append(sc);
|
|
314
|
+
this.loadedHashesSet.add(item.hash);
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
default: {
|
|
318
|
+
console.error(`Unknown asset of type ${item.type}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
runtime_default = Runtime;
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// src/multibind.js
|
|
329
|
+
var multibind_exports = {};
|
|
330
|
+
__export(multibind_exports, {
|
|
331
|
+
default: () => multibind_default
|
|
332
|
+
});
|
|
333
|
+
var MultiBind, multibind_default;
|
|
334
|
+
var init_multibind = __esm({
|
|
335
|
+
"src/multibind.js"() {
|
|
336
|
+
MultiBind = class {
|
|
337
|
+
constructor(els) {
|
|
338
|
+
this.els = els;
|
|
339
|
+
this.isSingle = els[0].type.toLowerCase() === "radio";
|
|
340
|
+
}
|
|
341
|
+
get values() {
|
|
342
|
+
if (this.isSingle) {
|
|
343
|
+
const sel = this.els.find((el) => el.checked);
|
|
344
|
+
return sel ? sel.value : void 0;
|
|
345
|
+
}
|
|
346
|
+
return this.els.filter((el) => el.checked).map((el) => el.value);
|
|
347
|
+
}
|
|
348
|
+
set values(values) {
|
|
349
|
+
if (this.isSingle) {
|
|
350
|
+
if (Array.isArray(values)) {
|
|
351
|
+
console.warn("CompEx: Setting an array to a radio group binding has no effect.");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const toSel = this.els.find((el) => el.value === values);
|
|
355
|
+
if (toSel) toSel.checked = true;
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (!Array.isArray(values)) {
|
|
359
|
+
values = [values];
|
|
360
|
+
}
|
|
361
|
+
const vals = new Set(values);
|
|
362
|
+
for (const el of this.els) {
|
|
363
|
+
el.checked = vals.has(el.value);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
multibind_default = MultiBind;
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// src/component.js
|
|
372
|
+
var component_exports = {};
|
|
373
|
+
__export(component_exports, {
|
|
374
|
+
default: () => component_default
|
|
375
|
+
});
|
|
376
|
+
var Component, component_default;
|
|
377
|
+
var init_component = __esm({
|
|
378
|
+
"src/component.js"() {
|
|
379
|
+
Component = class {
|
|
380
|
+
constructor(root) {
|
|
381
|
+
this.props = {};
|
|
382
|
+
this.root = root;
|
|
383
|
+
this.bindings = /* @__PURE__ */ new Map();
|
|
384
|
+
this.unsafeAttachRefs();
|
|
385
|
+
this.unsafeAttachProps();
|
|
386
|
+
this.unsafeAttachBinds();
|
|
387
|
+
this.unsafeAttachEvents();
|
|
388
|
+
}
|
|
389
|
+
unsafeAttachRefs() {
|
|
390
|
+
const els = this.root.querySelectorAll(":scope > :not([cx-controller]) [cx-ref], :scope > [cx-ref]");
|
|
391
|
+
for (const el of els) {
|
|
392
|
+
this[el.getAttribute("cx-ref")] = el;
|
|
393
|
+
}
|
|
394
|
+
if (this.root.getAttribute("cx-ref")) {
|
|
395
|
+
this[this.root.getAttribute("cx-ref")] = this.root;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
unsafeAttachProps() {
|
|
399
|
+
const bag = this.root.querySelector("script[type='vendor/compex-data-bag']");
|
|
400
|
+
if (!bag) return;
|
|
401
|
+
try {
|
|
402
|
+
this.props = JSON.parse(bag.textContent);
|
|
403
|
+
} catch (ex) {
|
|
404
|
+
console.error("CompEx: Failed parsing data bag", ex);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
unsafeAttachEvents() {
|
|
408
|
+
for (const el of this.root.querySelectorAll(CompEx.Eventing.cxEventSelector)) {
|
|
409
|
+
this.unsafeAttachEventsForNode(el);
|
|
410
|
+
}
|
|
411
|
+
for (const el of this.root.querySelectorAll(":scope > :not([cx-controller]) [cx-custom-handlers], :scope > [cx-custom-handlers]")) {
|
|
412
|
+
this.unsafeAttachCustomEventsForNode(el);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
unsafeAttachCustomEventsForNode(el) {
|
|
416
|
+
const descriptor = el.getAttribute("cx-custom-handlers");
|
|
417
|
+
if (!descriptor) return;
|
|
418
|
+
const descriptors = descriptor.split(",").map((i) => i.split("->"));
|
|
419
|
+
for (const [name, handler] of descriptors) {
|
|
420
|
+
this.unsafeAttachSingleEvent(this.root, name, handler);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
unsafeAttachEventsForNode(el) {
|
|
424
|
+
for (const attr of el.getAttributeNames()) {
|
|
425
|
+
if (!CompEx.Eventing.cxEventAttributes.has(attr)) return;
|
|
426
|
+
this.unsafeAttachSingleEvent(el, attr.replace("cx-", ""), el.getAttribute(attr));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
unsafeAttachSingleEvent(root, name, handlerName) {
|
|
430
|
+
const handler = this[handlerName];
|
|
431
|
+
if (!handler) {
|
|
432
|
+
console.warn(`Ignored attaching event: Handler ${handlerName} is not defined on`, root);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (typeof handler !== "function") {
|
|
436
|
+
console.warn(`Ignored attaching event: Handler ${handlerName} is not a function on`, root);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
CompEx.Eventing.attachHandler(this, root, name, handler.bind(this));
|
|
440
|
+
}
|
|
441
|
+
unsafeAttachBinds() {
|
|
442
|
+
for (const el of this.root.querySelectorAll(":scope > :not([cx-controller]) [cx-bind], :scope > [cx-bind]")) {
|
|
443
|
+
const name = el.getAttribute("cx-bind");
|
|
444
|
+
if (this.bindings.has(name)) {
|
|
445
|
+
this.bindings.get(name).push(el);
|
|
446
|
+
} else {
|
|
447
|
+
this.bindings.set(name, [el]);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
for (const [k, v] of this.bindings.entries()) {
|
|
451
|
+
if (v.length > 1) {
|
|
452
|
+
this.unsafeAttachMultiInputBind(k, v);
|
|
453
|
+
} else if (v[0].tagName.toLowerCase() === "select") {
|
|
454
|
+
this.unsafeAttachSelectBind(k, v[0]);
|
|
455
|
+
} else {
|
|
456
|
+
this.unsafeAttachSingleInputBind(k, v[0]);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
unsafeAttachSelectBind(k, el) {
|
|
461
|
+
const opts = [...el.querySelectorAll("option")];
|
|
462
|
+
const isMultiple = el.hasAttribute("multiple");
|
|
463
|
+
console.log("unsafeAttachSelectBind", k, el, isMultiple);
|
|
464
|
+
const set = (val) => {
|
|
465
|
+
if (!isMultiple && Array.isArray(val)) {
|
|
466
|
+
console.warn(`CompEx: Setting an array to a non-multiple Select (cx-bind="${k}") has no effect.`);
|
|
467
|
+
} else if (isMultiple) {
|
|
468
|
+
val = Array.isArray(val) ? val : [val];
|
|
469
|
+
const selOpts = new Set(val);
|
|
470
|
+
for (const el2 of opts) {
|
|
471
|
+
el2.selected = selOpts.has(el2.value);
|
|
472
|
+
}
|
|
473
|
+
} else {
|
|
474
|
+
for (const el2 of opts) {
|
|
475
|
+
el2.selected = el2.value === val;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
const get = () => {
|
|
480
|
+
const selected = opts.filter((el2) => el2.selected);
|
|
481
|
+
if (!isMultiple) return selected.length === 1 ? selected[0].value : void 0;
|
|
482
|
+
return selected.map((el2) => el2.value);
|
|
483
|
+
};
|
|
484
|
+
this.unsafeCreateLocalProperty(k, get, set);
|
|
485
|
+
}
|
|
486
|
+
unsafeAttachMultiInputBind(k, els) {
|
|
487
|
+
const nodeTags = els.map((el) => el.tagName.toLowerCase());
|
|
488
|
+
const isInput = nodeTags.includes("input");
|
|
489
|
+
if (isInput) {
|
|
490
|
+
console.log(nodeTags);
|
|
491
|
+
if (!nodeTags.every((tag) => tag === "input")) {
|
|
492
|
+
throw new Error(`cx-bind="${k}": All bindings under the same name are required to be inputs.`);
|
|
493
|
+
}
|
|
494
|
+
} else {
|
|
495
|
+
}
|
|
496
|
+
if (isInput) {
|
|
497
|
+
const inputTypes = els.map((el) => el.type.toLowerCase());
|
|
498
|
+
if (inputTypes.some((t) => t !== "checkbox" && t !== "radio")) {
|
|
499
|
+
throw new Error(`cx-bind="${k}": Only checkbox and radio inputs are supported in multi-bind input elements.`);
|
|
500
|
+
}
|
|
501
|
+
const firstType = inputTypes[0];
|
|
502
|
+
if (inputTypes.some((t) => t !== firstType)) {
|
|
503
|
+
throw new Error(`cx-bind="${k}": Inputs must have the same type "${firstType}"`);
|
|
504
|
+
}
|
|
505
|
+
if (els.some((el) => !el.getAttribute("value"))) {
|
|
506
|
+
throw new Error(`cx-bind="${k}": All inputs in a group must have a value`);
|
|
507
|
+
}
|
|
508
|
+
if (inputTypes[0] === "radio" && els.some((el) => !el.name)) {
|
|
509
|
+
let name;
|
|
510
|
+
const nameEl = els.find((el) => Boolean(el.name));
|
|
511
|
+
name = nameEl ? nameEl.name : `compex-radio-${CompEx.Utils.randomID()}`;
|
|
512
|
+
for (const el of els) el.name = name;
|
|
513
|
+
}
|
|
514
|
+
const mb = new CompEx.MultiBind(els);
|
|
515
|
+
this.unsafeCreateLocalProperty(k, () => mb.values, (v) => mb.values = v);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
unsafeAttachSingleInputBind(name, el) {
|
|
519
|
+
const getter = () => CompEx.Utils.getValueForNode(el);
|
|
520
|
+
const setter = (val) => CompEx.Utils.setValueForNode(el, val);
|
|
521
|
+
this.unsafeCreateLocalProperty(name, getter, setter);
|
|
522
|
+
}
|
|
523
|
+
unsafeCreateLocalProperty(name, getter, setter) {
|
|
524
|
+
Object.defineProperty(this, name, {
|
|
525
|
+
get() {
|
|
526
|
+
return getter();
|
|
527
|
+
},
|
|
528
|
+
set(newValue) {
|
|
529
|
+
setter(newValue);
|
|
530
|
+
},
|
|
531
|
+
enumerable: true,
|
|
532
|
+
configurable: true
|
|
533
|
+
});
|
|
534
|
+
console.log(`CompEx: Registered prop ${name}`);
|
|
535
|
+
}
|
|
536
|
+
async mount() {
|
|
537
|
+
}
|
|
538
|
+
async unmount() {
|
|
539
|
+
}
|
|
540
|
+
emit(name, detail) {
|
|
541
|
+
detail = detail || {};
|
|
542
|
+
detail.controller = this;
|
|
543
|
+
CompEx.Eventing.dispatchSyntheticEvent(name, this.root, detail);
|
|
544
|
+
}
|
|
545
|
+
async loadComponent(path) {
|
|
546
|
+
const result = await fetch(path, {
|
|
547
|
+
method: "GET",
|
|
548
|
+
mode: "cors",
|
|
549
|
+
credentials: "same-origin",
|
|
550
|
+
headers: {
|
|
551
|
+
"Accept": "text/html",
|
|
552
|
+
"X-CompEx-Load": "true"
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
if (result.ok) {
|
|
556
|
+
const loadProm = CompEx.Runtime.handleRequiredHashesHeader(result.headers.get("X-CompEx-RequiredHashes"));
|
|
557
|
+
const div = document.createElement("div");
|
|
558
|
+
div.innerHTML = await result.text();
|
|
559
|
+
await loadProm;
|
|
560
|
+
return div.firstChild;
|
|
561
|
+
} else {
|
|
562
|
+
throw result.error;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
component_default = Component;
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// src/main.js
|
|
571
|
+
((w, d) => {
|
|
572
|
+
const Utils2 = (init_utils(), __toCommonJS(utils_exports)).default;
|
|
573
|
+
const Eventing2 = (init_eventing(), __toCommonJS(eventing_exports)).default;
|
|
574
|
+
const Runtime2 = (init_runtime(), __toCommonJS(runtime_exports)).default;
|
|
575
|
+
const MultiBind2 = (init_multibind(), __toCommonJS(multibind_exports)).default;
|
|
576
|
+
const Component2 = (init_component(), __toCommonJS(component_exports)).default;
|
|
577
|
+
w.CompEx = class CompEx {
|
|
578
|
+
static Runtime = Runtime2;
|
|
579
|
+
static Component = Component2;
|
|
580
|
+
static Utils = Utils2;
|
|
581
|
+
static Eventing = Eventing2;
|
|
582
|
+
static MultiBind = MultiBind2;
|
|
583
|
+
};
|
|
584
|
+
if (d.readyState === "loading") {
|
|
585
|
+
addEventListener("DOMContentLoaded", () => CompEx.Runtime.install());
|
|
586
|
+
} else {
|
|
587
|
+
CompEx.Runtime.install();
|
|
588
|
+
}
|
|
589
|
+
})(globalThis, document);
|
|
590
|
+
})();
|
|
591
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/utils.js", "../src/eventing.js", "../src/runtime.js", "../src/multibind.js", "../src/component.js", "../src/main.js"],
|
|
4
|
+
"sourcesContent": ["const Utils = {\n isCheckable(node) {\n const name = node.nodeName;\n const type = node.type;\n\n return name && name.toLowerCase() === 'input' &&\n (type === 'checkbox' || type === 'radio');\n },\n\n getValueForNode(node) {\n let value = '';\n if (!node) return value;\n\n value = this.isCheckable(node) ? node.checked : node.value;\n\n return value;\n },\n\n setValueForNode(node, value) {\n if (!node) return;\n\n if (this.isCheckable(node)) {\n node.checked = value !== \"false\" && !!value;\n } else {\n node.value = value;\n }\n },\n\n getSelectionForNode(node) {\n if ('selectionStart' in node) {\n return {\n start: node.selectionStart,\n end: node.selectionEnd,\n };\n }\n\n return {start: 0, end: 0};\n },\n setSelectionForNode(node, bounds) {\n if (!('selectionStart' in node)) return;\n\n const start = bounds.start;\n let end = bounds.end;\n if (end === undefined) end = start;\n\n node.selectionStart = start;\n node.selectionEnd = Math.min(end, node.value.length);\n },\n\n randomID() {\n const bytes = new Uint8Array(8);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n },\n};\n\nexport default Utils;\n", "const globalEventsListener = '_compex_install' + Math.random().toString(36).slice(2);\n\nclass SyntheticEvent {\n constructor(type, target = null, options = {}) {\n\n const {\n detail = null,\n bubbles = false,\n cancelable = false,\n composed = false\n } = options || {};\n\n // Core readonly-like properties\n this.type = String(type);\n this.target = target;\n this.currentTarget = null; // set by dispatch system\n this.eventPhase = 0; // NONE = 0, CAPTURING_PHASE = 1, AT_TARGET = 2, BUBBLING_PHASE = 3\n\n // EventInit\n this.bubbles = !!bubbles;\n this.cancelable = !!cancelable;\n this.composed = !!composed;\n this.detail = detail;\n\n // State\n this.defaultPrevented = false;\n this.cancelBubble = false; // used by legacy code (stopPropagation)\n this.timeStamp = performance.now();\n this._path = null;\n }\n\n stopPropagation() {\n this.cancelBubble = true;\n }\n\n stopImmediatePropagation() {\n this.cancelBubble = true;\n this._immediateStopped = true;\n }\n\n preventDefault() {\n if (this.cancelable) {\n this.defaultPrevented = true;\n this.returnValue = false;\n }\n }\n\n composedPath() {\n // If a custom path was set by the dispatch system, return it.\n if (this._path) return [...this._path];\n\n // Otherwise, derive it from target hierarchy.\n const path = [];\n let node = this.target;\n while (node) {\n path.push(node);\n node = node.parent || node.host || null;\n }\n return path;\n }\n}\n\nclass Eventing {\n static eventListenerSet = new Set();\n static domEventTypes = ['abort', 'beforeinput', 'beforetoggle', 'blur', 'canplay', 'canplaythrough', 'cancel', 'change', 'click', 'close', 'compositionend', 'compositionstart', 'compositionupdate', 'contextmenu', 'copy', 'cut', 'dblclick', 'auxclick', 'drag', 'dragend', 'dragenter', 'dragexit', 'dragleave', 'dragover', 'dragstart', 'drop', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'focus', 'focusin', 'focusout', 'fullscreenchange', 'gotpointercapture', 'hashchange', 'input', 'invalid', 'keydown', 'keypress', 'keyup', 'load', 'loadstart', 'loadeddata', 'loadedmetadata', 'lostpointercapture', 'message', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'paste', 'pause', 'play', 'playing', 'pointercancel', 'pointerdown', 'pointerenter', 'pointerleave', 'pointermove', 'pointerout', 'pointerover', 'pointerup', 'popstate', 'progress', 'ratechange', 'reset', 'resize', 'scroll', 'scrollend', 'seeked', 'seeking', 'select', 'selectstart', 'selectionchange', 'stalled', 'submit', 'suspend', 'timeupdate', 'toggle', 'touchcancel', 'touchend', 'touchmove', 'touchstart', 'volumechange', 'waiting', 'wheel'];\n // List of events that need to be individually attached to media elements.\n static mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'resize', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting'];\n\n // We should not delegate these events to the container, but rather\n // set them on the actual target element itself. This is primarily\n // because these events do not consistently bubble in the DOM.\n static nonDelegatedEvents = new Set([\n 'beforetoggle',\n 'cancel',\n 'close',\n 'invalid',\n 'load',\n 'scroll',\n 'scrollend',\n 'toggle',\n // In order to reduce bytes, we insert the above array of media events\n // into this Set. Note: the \"error\" event isn't an exclusive media event,\n // and can occur on other elements too. Rather than duplicate that event,\n // we just take it from the media events array.\n ...this.mediaEventTypes,\n ]);\n static cxEventAttributes = new Set(Eventing.domEventTypes.map(i => `cx-${i}`));\n static cxEventSelector = Eventing.cxEventAttributes.values().map(i => `:scope > :not([cx-controller]) [${i}], :scope > [${i}]`).toArray().join(\",\");\n static controllerHandles = new Map();\n static eventHandles = new Map();\n\n static attachHandler(ctrl, el, name, handler) {\n if (this.controllerHandles.has(ctrl)) {\n this.controllerHandles.get(ctrl).push(handler);\n } else {\n this.controllerHandles.set(ctrl, [handler]);\n }\n this.registerHandler(el, name, handler);\n }\n\n static registerHandler(el, name, handler) {\n if (this.eventHandles.has(name)) {\n if (this.eventHandles.get(name).has(el)) {\n this.eventHandles.get(name).get(el).push(handler);\n } else {\n this.eventHandles.get(name).set(el, [handler]);\n }\n } else {\n this.eventHandles.set(name, new Map([[el, [handler]]]));\n }\n }\n\n static installEventHandlers() {\n if (document[globalEventsListener]) {\n return;\n }\n document[globalEventsListener] = true;\n\n for (const ev of CompEx.Eventing.domEventTypes) {\n const isCapturePhaseListener = CompEx.Eventing.nonDelegatedEvents.has(ev);\n this.installNativeEventHandler(ev, isCapturePhaseListener);\n }\n }\n\n static installNativeEventHandler(ev, isCapturePhaseListener) {\n // Ensure we don\u2019t add duplicate listeners\n const listenerSetKey = this.eventListenerKey(ev, isCapturePhaseListener);\n if (this.eventListenerSet.has(listenerSetKey)) return;\n\n document.addEventListener(ev, this.eventHandler(isCapturePhaseListener), isCapturePhaseListener);\n this.eventListenerSet.add(listenerSetKey);\n }\n\n static eventHandler(isCapturePhaseListener) {\n return isCapturePhaseListener ? this.captureEventHandler.bind(this) : this.bubbleEventHandler.bind(this);\n }\n\n static captureEventHandler(ev) {\n debugger;\n }\n\n static bubbleEventHandler(ev) {\n const handles = this.eventHandles.get(ev.type);\n if (!handles) return;\n const elHandlers = handles.get(ev.target);\n if (!elHandlers) return;\n for (const handler of elHandlers) {\n handler(ev);\n if (ev.defaultPrevented) return;\n }\n }\n\n static dispatchSyntheticEvent(type, target, detail = null) {\n const ev = new SyntheticEvent(type, target, detail);\n const handles = this.eventHandles.get(ev.type);\n if (!handles) return;\n\n for (const handler of handles.values().toArray().flat()) {\n handler(ev);\n if (ev.defaultPrevented) return;\n }\n }\n\n static eventListenerKey(name, isCapturePhaseListener) {\n return `${name}__${isCapturePhaseListener ? 'capture' : 'bubble'}`;\n }\n}\n\nexport default Eventing;\n", "class Runtime {\n static registry = {};\n static instances = new WeakMap();\n static observer = new MutationObserver(muts => {\n for (const mut of muts) {\n for (const node of mut.addedNodes) {\n if (node.nodeType !== Node.ELEMENT_NODE || !node.getAttribute(\"cx-controller\")) continue;\n this.attachController(node);\n }\n\n for (const node of mut.removedNodes) {\n if (node.nodeType !== Node.ELEMENT_NODE || !node.getAttribute(\"cx-controller\")) continue;\n this.detachController(node);\n }\n }\n });\n static loadedHashesSet = new Set();\n\n static attachController(node) {\n const ctrlName = node.getAttribute('cx-controller');\n const ctrl = this.registry[ctrlName];\n if (!ctrl) {\n console.warn(`Missing JS controller for element ${node}: ${ctrlName}`);\n return;\n }\n const inst = new ctrl(node);\n this.instances.set(node, inst);\n let mountRet = inst.mount();\n if (mountRet instanceof Promise) {\n mountRet.catch(console.error.bind(console));\n }\n }\n\n static detachController(node) {\n const inst = this.instances[node];\n if (!inst) return;\n\n inst.unmount()\n .catch(console.error.bind(console))\n .finally(() => {\n this.instances.delete(node);\n });\n }\n\n static install() {\n this.installed = true;\n CompEx.Eventing.installEventHandlers();\n for (const el of document.querySelectorAll('[cx-controller]')) this.attachController(el);\n\n for (const el of document.querySelectorAll('[cx-asset]')) this.loadedHashesSet.add(el.getAttribute('cx-asset'));\n\n this.observer.observe(document, {childList: true});\n }\n\n static register(name, klass) {\n this.registry[name] = klass;\n console.log(`CompEx: Registered ${name}`);\n }\n\n static async handleRequiredHashesHeader(value) {\n if (!value) return;\n const toRequire = value\n .split(\",\")\n .filter(v => !this.loadedHashesSet.has(v));\n const requireParams = new URLSearchParams([[\"h\", toRequire]]);\n const resp = await fetch(\"/_compex/assets?\" + requireParams.toString(), {\n method: \"GET\",\n });\n if (!resp.ok) {\n console.error(resp.message);\n return;\n }\n\n // /_assets returns a one-dimensional array containing data for each of the required\n // hashes.\n const json = await resp.json();\n for (const [idx, item] of json.entries()) {\n if (!item) {\n console.warn(`CompEx: Could not retrieve asset for hash ${toRequire[idx]}`)\n continue;\n }\n\n switch (item.type) {\n case \"style\": {\n const st = document.createElement(\"style\");\n st.setAttribute(\"cx-asset\", item.hash);\n st.textContent = item.source;\n document.head.append(st);\n this.loadedHashesSet.add(item.hash);\n break;\n }\n case \"script\": {\n const sc = document.createElement(\"script\");\n sc.setAttribute(\"cx-asset\", item.hash);\n sc.innerHTML = item.source;\n document.head.append(sc);\n this.loadedHashesSet.add(item.hash);\n break;\n }\n default: {\n console.error(`Unknown asset of type ${item.type}`);\n }\n }\n }\n }\n}\n\nexport default Runtime;\n", "class MultiBind {\n constructor(els) {\n this.els = els;\n this.isSingle = els[0].type.toLowerCase() === 'radio';\n }\n\n get values() {\n if (this.isSingle) {\n const sel = this.els.find(el => el.checked);\n return sel ? sel.value : undefined;\n }\n\n return this.els\n .filter(el => el.checked)\n .map(el => el.value);\n }\n\n set values(values) {\n if (this.isSingle) {\n if (Array.isArray(values)) {\n console.warn(\"CompEx: Setting an array to a radio group binding has no effect.\");\n return;\n }\n const toSel = this.els.find(el => el.value === values);\n if (toSel) toSel.checked = true;\n return;\n }\n\n if (!Array.isArray(values)) {\n values = [values];\n }\n const vals = new Set(values);\n for (const el of this.els) {\n el.checked = vals.has(el.value);\n }\n }\n}\n\nexport default MultiBind;\n", "class Component {\n constructor(root) {\n this.props = {};\n this.root = root;\n this.bindings = new Map();\n this.unsafeAttachRefs();\n this.unsafeAttachProps();\n this.unsafeAttachBinds();\n this.unsafeAttachEvents();\n }\n\n unsafeAttachRefs() {\n const els = this.root.querySelectorAll(':scope > :not([cx-controller]) [cx-ref], :scope > [cx-ref]');\n for (const el of els) {\n this[el.getAttribute('cx-ref')] = el;\n }\n if (this.root.getAttribute('cx-ref')) {\n this[this.root.getAttribute('cx-ref')] = this.root;\n }\n }\n\n unsafeAttachProps() {\n const bag = this.root.querySelector(\"script[type='vendor/compex-data-bag']\")\n if (!bag) return;\n\n try {\n this.props = JSON.parse(bag.textContent);\n } catch (ex) {\n console.error(\"CompEx: Failed parsing data bag\", ex);\n }\n }\n\n unsafeAttachEvents() {\n for (const el of this.root.querySelectorAll(CompEx.Eventing.cxEventSelector)) {\n this.unsafeAttachEventsForNode(el);\n }\n for (const el of this.root.querySelectorAll(':scope > :not([cx-controller]) [cx-custom-handlers], :scope > [cx-custom-handlers]')) {\n this.unsafeAttachCustomEventsForNode(el)\n }\n }\n\n unsafeAttachCustomEventsForNode(el) {\n const descriptor = el.getAttribute(\"cx-custom-handlers\");\n if (!descriptor) return;\n\n const descriptors = descriptor.split(\",\").map(i => i.split(\"->\"));\n for (const [name, handler] of descriptors) {\n this.unsafeAttachSingleEvent(this.root, name, handler)\n }\n }\n\n unsafeAttachEventsForNode(el) {\n for (const attr of el.getAttributeNames()) {\n if (!CompEx.Eventing.cxEventAttributes.has(attr)) return;\n this.unsafeAttachSingleEvent(el, attr.replace(\"cx-\", \"\"), el.getAttribute(attr))\n }\n }\n\n unsafeAttachSingleEvent(root, name, handlerName) {\n const handler = this[handlerName];\n if (!handler) {\n console.warn(`Ignored attaching event: Handler ${handlerName} is not defined on`, root);\n return;\n }\n if (typeof handler !== 'function') {\n console.warn(`Ignored attaching event: Handler ${handlerName} is not a function on`, root);\n return;\n }\n\n CompEx.Eventing.attachHandler(this, root, name, handler.bind(this));\n }\n\n unsafeAttachBinds() {\n // First, collect all bindings, so we can decide what to do when we have multiple options.\n for (const el of this.root.querySelectorAll(':scope > :not([cx-controller]) [cx-bind], :scope > [cx-bind]')) {\n const name = el.getAttribute('cx-bind');\n if (this.bindings.has(name)) {\n this.bindings.get(name).push(el);\n } else {\n this.bindings.set(name, [el]);\n }\n }\n\n // TODO: Support namespaced bindings like login.username, login.password.\n\n // Then, process every set of bindings. For instance, bindings with multiple elements like\n // radios and checkboxes can be handled through their own values instead of a reference to\n // the element itself. This also changes how we set values.\n\n // TODO: Warn on conflicting bindings\n\n for (const [k, v] of this.bindings.entries()) {\n if (v.length > 1) {\n this.unsafeAttachMultiInputBind(k, v);\n } else if (v[0].tagName.toLowerCase() === 'select') {\n this.unsafeAttachSelectBind(k, v[0]);\n } else {\n this.unsafeAttachSingleInputBind(k, v[0]);\n }\n }\n }\n\n unsafeAttachSelectBind(k, el) {\n const opts = [...el.querySelectorAll('option')];\n const isMultiple = el.hasAttribute('multiple');\n\n console.log(\"unsafeAttachSelectBind\", k, el, isMultiple);\n\n const set = (val) => {\n if (!isMultiple && Array.isArray(val)) {\n console.warn(`CompEx: Setting an array to a non-multiple Select (cx-bind=\"${k}\") has no effect.`);\n } else if (isMultiple) {\n val = Array.isArray(val) ? val : [val];\n const selOpts = new Set(val);\n for (const el of opts) {\n el.selected = selOpts.has(el.value)\n }\n } else {\n for (const el of opts) {\n el.selected = el.value === val;\n }\n }\n }\n\n const get = () => {\n const selected = opts.filter(el => el.selected);\n if (!isMultiple) return selected.length === 1 ? selected[0].value : undefined;\n return selected.map(el => el.value);\n }\n\n this.unsafeCreateLocalProperty(k, get, set);\n }\n\n unsafeAttachMultiInputBind(k, els) {\n // Collect all element types, all input types, all values.\n const nodeTags = els.map(el => el.tagName.toLowerCase());\n const isInput = nodeTags.includes(\"input\");\n if (isInput) {\n // If one tag is an input, every tag must be an input.\n console.log(nodeTags);\n if (!nodeTags.every(tag => tag === \"input\")) {\n throw new Error(`cx-bind=\"${k}\": All bindings under the same name are required to be inputs.`);\n }\n } else {\n // TODO: Expect all nodes to be the same type?\n }\n\n if (isInput) {\n const inputTypes = els.map(el => el.type.toLowerCase());\n // Here's some checks:\n // 1. All inputs must be of the same type.\n // 2. All inputs must have a value.\n // 3. Only radio and checkboxes can be part of a group of binds.\n if (inputTypes.some(t => t !== \"checkbox\" && t !== \"radio\")) {\n throw new Error(`cx-bind=\"${k}\": Only checkbox and radio inputs are supported in multi-bind input elements.`);\n }\n const firstType = inputTypes[0];\n if (inputTypes.some(t => t !== firstType)) {\n throw new Error(`cx-bind=\"${k}\": Inputs must have the same type \"${firstType}\"`);\n }\n\n if (els.some(el => !el.getAttribute(\"value\"))) {\n throw new Error(`cx-bind=\"${k}\": All inputs in a group must have a value`);\n }\n\n if (inputTypes[0] === \"radio\" && els.some(el => !el.name)) {\n // All radios must have the same name. Either synthesize or reuse one.\n let name;\n // Make sure we don't have a name for the group. In case at least one element\n // has a name, reuse it.\n const nameEl = els.find(el => Boolean(el.name));\n name = nameEl ? nameEl.name : `compex-radio-${CompEx.Utils.randomID()}`;\n for (const el of els) el.name = name\n }\n\n const mb = new CompEx.MultiBind(els);\n this.unsafeCreateLocalProperty(k, () => mb.values, (v) => mb.values = v);\n }\n }\n\n unsafeAttachSingleInputBind(name, el) {\n const getter = () => CompEx.Utils.getValueForNode(el);\n const setter = (val) => CompEx.Utils.setValueForNode(el, val);\n this.unsafeCreateLocalProperty(name, getter, setter);\n }\n\n unsafeCreateLocalProperty(name, getter, setter) {\n Object.defineProperty(this, name, {\n get() {\n return getter()\n },\n set(newValue) {\n setter(newValue)\n },\n enumerable: true,\n configurable: true,\n });\n console.log(`CompEx: Registered prop ${name}`);\n }\n\n async mount() {}\n\n async unmount() {}\n\n emit(name, detail) {\n detail = detail || {};\n detail.controller = this;\n CompEx.Eventing.dispatchSyntheticEvent(name, this.root, detail);\n }\n\n async loadComponent(path) {\n const result = await fetch(path, {\n method: 'GET',\n mode: 'cors',\n credentials: 'same-origin',\n headers: {\n 'Accept': 'text/html',\n 'X-CompEx-Load': 'true',\n }\n });\n if (result.ok) {\n const loadProm = CompEx.Runtime.handleRequiredHashesHeader(result.headers.get('X-CompEx-RequiredHashes'));\n const div = document.createElement('div');\n div.innerHTML = await result.text();\n await loadProm;\n return div.firstChild;\n } else {\n throw result.error;\n }\n }\n}\n\nexport default Component;\n", "((w, d) => {\n\n const Utils = require(\"./utils.js\").default;\n const Eventing = require(\"./eventing.js\").default;\n\n const Runtime = require(\"./runtime.js\").default;\n const MultiBind = require(\"./multibind.js\").default;\n const Component = require(\"./component.js\").default;\n\n w.CompEx = class CompEx {\n static Runtime = Runtime;\n static Component = Component;\n static Utils = Utils;\n static Eventing = Eventing;\n static MultiBind = MultiBind;\n }\n\n if (d.readyState === 'loading') {\n addEventListener(\"DOMContentLoaded\", () => CompEx.Runtime.install());\n } else {\n CompEx.Runtime.install();\n }\n})(globalThis, document);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["el", "Utils", "Eventing", "Runtime", "MultiBind", "Component"]
|
|
7
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: compex-sinatra
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Vito Sartori
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2025-10-23 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: CompEx bindings for Sinatra
|
|
13
|
+
email:
|
|
14
|
+
- hey@vito.io
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- ".rspec"
|
|
20
|
+
- ".rubocop.yml"
|
|
21
|
+
- LICENSE.txt
|
|
22
|
+
- README.md
|
|
23
|
+
- Rakefile
|
|
24
|
+
- lib/compex/sinatra.rb
|
|
25
|
+
- lib/compex/sinatra/version.rb
|
|
26
|
+
- sample/app.rb
|
|
27
|
+
- sample/public/bundle.js
|
|
28
|
+
- sample/public/bundle.js.map
|
|
29
|
+
homepage: https://github.com/heyvito/compex
|
|
30
|
+
licenses:
|
|
31
|
+
- MIT
|
|
32
|
+
metadata:
|
|
33
|
+
allowed_push_host: https://rubygems.org
|
|
34
|
+
homepage_uri: https://github.com/heyvito/compex
|
|
35
|
+
source_code_uri: https://github.com/heyvito/compex/tree/master/compex-sinatra
|
|
36
|
+
rdoc_options: []
|
|
37
|
+
require_paths:
|
|
38
|
+
- lib
|
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: 3.1.0
|
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0'
|
|
49
|
+
requirements: []
|
|
50
|
+
rubygems_version: 3.6.2
|
|
51
|
+
specification_version: 4
|
|
52
|
+
summary: CompEx bindings for Sinatra
|
|
53
|
+
test_files: []
|