Class: Dommy::CustomElementRegistry
- Inherits:
-
Object
- Object
- Dommy::CustomElementRegistry
- Defined in:
- lib/dommy/custom_elements.rb
Overview
‘window.customElements` — registry mapping custom element tag names to Ruby classes that extend `HTMLElement`. Lifecycle callbacks (`connected_callback` / `disconnected_callback` / `attribute_changed_callback` / `adopted_callback`) are invoked by the document’s mutation pipeline when registered elements are added, removed, or have observed attributes mutated.
Names must contain a hyphen per the HTML spec (e.g., ‘my-button`).
Constant Summary collapse
- NAME_RE =
/\A[a-z][a-z0-9-]*-[a-z0-9-]*\z/
Instance Method Summary collapse
- #__js_call__(method, args) ⇒ Object
- #__js_get__(_key) ⇒ Object
- #define(name, klass, _options = nil) ⇒ Object
- #get(name) ⇒ Object
- #get_name(klass) ⇒ Object
-
#initialize(window) ⇒ CustomElementRegistry
constructor
A new instance of CustomElementRegistry.
-
#upgrade(root) ⇒ Object
Walk ‘root`’s subtree and re-wrap any nodes whose tag is now registered; fires ‘connectedCallback` for each upgraded node that’s currently attached to a document tree.
-
#when_defined(name) ⇒ Object
Returns a Dommy::PromiseValue that resolves with the registered constructor when ‘name` is defined (immediately if already so).
Constructor Details
#initialize(window) ⇒ CustomElementRegistry
Returns a new instance of CustomElementRegistry.
15 16 17 18 19 20 21 |
# File 'lib/dommy/custom_elements.rb', line 15 def initialize(window) @window = window # name → klass @definitions = {} # name → Array<{ resolve, reject }> @pending_promises = {} end |
Instance Method Details
#__js_call__(method, args) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/dommy/custom_elements.rb', line 86 def __js_call__(method, args) case method when "define" define(args[0], args[1], args[2]) when "get" get(args[0]) when "whenDefined" when_defined(args[0]) when "upgrade" upgrade(args[0]) end end |
#__js_get__(_key) ⇒ Object
82 83 84 |
# File 'lib/dommy/custom_elements.rb', line 82 def __js_get__(_key) nil end |
#define(name, klass, _options = nil) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/dommy/custom_elements.rb', line 23 def define(name, klass, = nil) key = name.to_s unless key.match?(NAME_RE) raise DOMException::SyntaxError, "name must be a hyphenated string, got #{name.inspect}" end raise DOMException::NotSupportedError, "#{key} already defined" if @definitions.key?(key) @definitions[key] = klass # Resolve any pending whenDefined() promises and re-wrap # already-existing nodes (upgrade). resolve_pending(key, klass) upgrade_existing(key) nil end |
#get(name) ⇒ Object
39 40 41 |
# File 'lib/dommy/custom_elements.rb', line 39 def get(name) @definitions[name.to_s] end |
#get_name(klass) ⇒ Object
43 44 45 46 |
# File 'lib/dommy/custom_elements.rb', line 43 def get_name(klass) @definitions.each { |k, v| return k if v == klass } nil end |
#upgrade(root) ⇒ Object
Walk ‘root`’s subtree and re-wrap any nodes whose tag is now registered; fires ‘connectedCallback` for each upgraded node that’s currently attached to a document tree.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/dommy/custom_elements.rb', line 66 def upgrade(root) return nil unless root.respond_to?(:__node__) walk_descendants(root.__node__) do |nk| next unless nk.element? next unless @definitions.key?(nk.name) # Force re-wrap by clearing the document's cached wrapper. @window.document.__reset_wrapper__(nk) wrapped = @window.document.wrap_node(nk) @window.document.__notify_connected__(wrapped) if wrapped end nil end |
#when_defined(name) ⇒ Object
Returns a Dommy::PromiseValue that resolves with the registered constructor when ‘name` is defined (immediately if already so).
50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/dommy/custom_elements.rb', line 50 def when_defined(name) key = name.to_s promise = PromiseValue.new(@window) if (klass = @definitions[key]) promise.fulfill(klass) else @pending_promises[key] ||= [] @pending_promises[key] << promise end promise end |