MCPcopy Create free account
hub / github.com/bigskysoftware/_hyperscript / registerComponent

Function registerComponent

src/ext/component.js:126–267  ·  view source on GitHub ↗
(templateEl, componentScript)

Source from the content-addressed store, hash-verified

124 }
125
126 function registerComponent(templateEl, componentScript) {
127 const tagName = templateEl.getAttribute('component');
128 if (!tagName.includes('-')) {
129 console.error("component name must contain a dash: '" + tagName + "'");
130 return;
131 }
132
133 // Extract <style> blocks from the raw text, wrap in @scope (tag-name),
134 // and inject a single combined <style> into document.head. Using head
135 // rather than insertAdjacentElement keeps bundle-loaded templates
136 // (whose templateEl lives in a DOMParser'd foreign document) working.
137 var raw = templateEl.textContent;
138 var combined = '';
139 var styleRegex = /<style[^>]*>([\s\S]*?)<\/style>/gi;
140 var match;
141 while ((match = styleRegex.exec(raw)) !== null) {
142 combined += match[1] + '\n';
143 }
144 if (combined) {
145 raw = raw.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');
146 templateEl.textContent = raw;
147 var scopedStyle = document.createElement('style');
148 scopedStyle.setAttribute('data-hyperscript-component', tagName);
149 scopedStyle.textContent = '@scope (' + tagName + ') {\n' + combined + '}';
150 document.head.appendChild(scopedStyle);
151 }
152
153 const templateSource = templateEl.textContent;
154
155 // Parse template once to validate - actual rendering happens per instance
156 // (We reuse the render command's approach: tokenize in "lines" mode at render time)
157
158 const ComponentClass = class extends HTMLElement {
159 connectedCallback() {
160 // Skip if already initialized
161 if (this._hypercomp_initialized) return;
162 this._hypercomp_initialized = true;
163
164 // Isolate component scope - ^var resolution stops here
165 this.setAttribute('dom-scope', 'isolated');
166
167 // Capture slot content and clear children immediately,
168 // before processNode can recurse into them
169 this._slotContent = this.innerHTML;
170 this.innerHTML = '';
171
172 // 1. Inject `attrs` proxy into element scope, then apply component-level hyperscript
173 var internalData = runtime.getInternalData(this);
174 if (!internalData.elementScope) internalData.elementScope = {};
175 internalData.elementScope.attrs = createAttrs(this);
176
177 if (componentScript) {
178 this.setAttribute('_', componentScript);
179 _hyperscript.process(this);
180 }
181
182 // 2. Render template after synchronous init completes
183 const self = this;

Callers 1

registerTemplateFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected