@dinoreic/fez 0.4.0 → 0.5.2

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.
@@ -2,8 +2,8 @@
2
2
  const log_pretty_print = (html) => {
3
3
  const parts = html
4
4
  .split(/(<\/?[^>]+>)/g)
5
- .map(p => p.trim())
6
- .filter(p => p);
5
+ .map((p) => p.trim())
6
+ .filter((p) => p);
7
7
 
8
8
  let indent = 0;
9
9
  const lines = [];
@@ -14,41 +14,48 @@ const log_pretty_print = (html) => {
14
14
  const nextNextPart = parts[i + 2];
15
15
 
16
16
  // Check if it's a tag
17
- if (part.startsWith('<')) {
17
+ if (part.startsWith("<")) {
18
18
  // Check if this is an opening tag followed by text and then its closing tag
19
- if (!part.startsWith('</') && !part.endsWith('/>') && nextPart && !nextPart.startsWith('<') && nextNextPart && nextNextPart.startsWith('</')) {
19
+ if (
20
+ !part.startsWith("</") &&
21
+ !part.endsWith("/>") &&
22
+ nextPart &&
23
+ !nextPart.startsWith("<") &&
24
+ nextNextPart &&
25
+ nextNextPart.startsWith("</")
26
+ ) {
20
27
  // Combine them on one line
21
28
  const actualIndent = Math.max(0, indent);
22
- lines.push(' '.repeat(actualIndent) + part + nextPart + nextNextPart);
29
+ lines.push(" ".repeat(actualIndent) + part + nextPart + nextNextPart);
23
30
  i += 2; // Skip the next two parts
24
31
  }
25
32
  // Closing tag
26
- else if (part.startsWith('</')) {
33
+ else if (part.startsWith("</")) {
27
34
  indent--;
28
35
  const actualIndent = Math.max(0, indent);
29
- lines.push(' '.repeat(actualIndent) + part);
36
+ lines.push(" ".repeat(actualIndent) + part);
30
37
  }
31
38
  // Self-closing tag
32
- else if (part.endsWith('/>') || part.includes(' />')) {
39
+ else if (part.endsWith("/>") || part.includes(" />")) {
33
40
  const actualIndent = Math.max(0, indent);
34
- lines.push(' '.repeat(actualIndent) + part);
41
+ lines.push(" ".repeat(actualIndent) + part);
35
42
  }
36
43
  // Opening tag
37
44
  else {
38
45
  const actualIndent = Math.max(0, indent);
39
- lines.push(' '.repeat(actualIndent) + part);
46
+ lines.push(" ".repeat(actualIndent) + part);
40
47
  indent++;
41
48
  }
42
49
  }
43
50
  // Text node
44
51
  else if (part) {
45
52
  const actualIndent = Math.max(0, indent);
46
- lines.push(' '.repeat(actualIndent) + part);
53
+ lines.push(" ".repeat(actualIndent) + part);
47
54
  }
48
55
  }
49
56
 
50
- return lines.join('\n');
51
- }
57
+ return lines.join("\n");
58
+ };
52
59
 
53
60
  const LOG = (() => {
54
61
  const logs = [];
@@ -57,11 +64,11 @@ const LOG = (() => {
57
64
  let renderContent = null; // Will hold the render function
58
65
 
59
66
  // Add ESC key handler and arrow key navigation
60
- document.addEventListener('keydown', (e) => {
61
- if (e.key === 'Escape') {
67
+ document.addEventListener("keydown", (e) => {
68
+ if (e.key === "Escape") {
62
69
  e.preventDefault();
63
- const dialog = document.getElementById('dump-dialog');
64
- const button = document.getElementById('log-reopen-button');
70
+ const dialog = document.getElementById("dump-dialog");
71
+ const button = document.getElementById("log-reopen-button");
65
72
 
66
73
  if (dialog) {
67
74
  // Close dialog
@@ -72,25 +79,30 @@ const LOG = (() => {
72
79
  button.remove();
73
80
  showLogDialog();
74
81
  }
75
- } else if (e.key === 'ArrowLeft' || e.key === 'ArrowRight' || e.key === 'ArrowUp' || e.key === 'ArrowDown') {
76
- const dialog = document.getElementById('dump-dialog');
82
+ } else if (
83
+ e.key === "ArrowLeft" ||
84
+ e.key === "ArrowRight" ||
85
+ e.key === "ArrowUp" ||
86
+ e.key === "ArrowDown"
87
+ ) {
88
+ const dialog = document.getElementById("dump-dialog");
77
89
  if (dialog && logs.length > 0) {
78
90
  e.preventDefault();
79
- if (e.key === 'ArrowLeft' && currentIndex > 0) {
91
+ if (e.key === "ArrowLeft" && currentIndex > 0) {
80
92
  currentIndex--;
81
- localStorage.setItem('_LOG_INDEX', currentIndex);
93
+ localStorage.setItem("_LOG_INDEX", currentIndex);
82
94
  renderContent();
83
- } else if (e.key === 'ArrowRight' && currentIndex < logs.length - 1) {
95
+ } else if (e.key === "ArrowRight" && currentIndex < logs.length - 1) {
84
96
  currentIndex++;
85
- localStorage.setItem('_LOG_INDEX', currentIndex);
97
+ localStorage.setItem("_LOG_INDEX", currentIndex);
86
98
  renderContent();
87
- } else if (e.key === 'ArrowUp' && currentIndex > 0) {
99
+ } else if (e.key === "ArrowUp" && currentIndex > 0) {
88
100
  currentIndex = Math.max(0, currentIndex - 5);
89
- localStorage.setItem('_LOG_INDEX', currentIndex);
101
+ localStorage.setItem("_LOG_INDEX", currentIndex);
90
102
  renderContent();
91
- } else if (e.key === 'ArrowDown' && currentIndex < logs.length - 1) {
103
+ } else if (e.key === "ArrowDown" && currentIndex < logs.length - 1) {
92
104
  currentIndex = Math.min(logs.length - 1, currentIndex + 5);
93
- localStorage.setItem('_LOG_INDEX', currentIndex);
105
+ localStorage.setItem("_LOG_INDEX", currentIndex);
94
106
  renderContent();
95
107
  }
96
108
  }
@@ -98,17 +110,18 @@ const LOG = (() => {
98
110
  });
99
111
 
100
112
  const createLogButton = () => {
101
- let btn = document.getElementById('log-reopen-button');
113
+ let btn = document.getElementById("log-reopen-button");
102
114
  if (!btn) {
103
- btn = document.body.appendChild(document.createElement('button'));
104
- btn.id = 'log-reopen-button';
105
- btn.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:4px"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>LOG';
115
+ btn = document.body.appendChild(document.createElement("button"));
116
+ btn.id = "log-reopen-button";
117
+ btn.innerHTML =
118
+ '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:4px"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>LOG';
106
119
  btn.style.cssText =
107
- 'position:fixed; top: 10px; right: 10px;' +
108
- 'padding:10px 20px;background:#ff3333;color:#fff;border:none;' +
109
- 'cursor:pointer;font:14px/1.4 monospace;z-index:2147483647;' +
110
- 'border-radius:8px;display:flex;align-items:center;' +
111
- 'opacity:1;visibility:visible;box-shadow:0 4px 12px rgba(255,51,51,0.3)';
120
+ "position:fixed; top: 10px; right: 10px;" +
121
+ "padding:10px 20px;background:#ff3333;color:#fff;border:none;" +
122
+ "cursor:pointer;font:14px/1.4 monospace;z-index:2147483647;" +
123
+ "border-radius:8px;display:flex;align-items:center;" +
124
+ "opacity:1;visibility:visible;box-shadow:0 4px 12px rgba(255,51,51,0.3)";
112
125
  btn.onclick = () => {
113
126
  btn.remove();
114
127
  showLogDialog();
@@ -117,20 +130,23 @@ const LOG = (() => {
117
130
  };
118
131
 
119
132
  const showLogDialog = () => {
120
- let d = document.getElementById('dump-dialog');
133
+ // Remove any existing log button when showing dialog
134
+ const existingBtn = document.getElementById("log-reopen-button");
135
+ if (existingBtn) existingBtn.remove();
136
+
137
+ let d = document.getElementById("dump-dialog");
121
138
  if (!d) {
122
- d = document.body.appendChild(document.createElement('div'));
123
- d.id = 'dump-dialog';
124
- const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
139
+ d = document.body.appendChild(document.createElement("div"));
140
+ d.id = "dump-dialog";
125
141
  d.style.cssText =
126
- 'position:absolute; top:' + (scrollTop + 20) + 'px; left: 20px; right:20px;' +
127
- 'background:#fff; border:1px solid #333; box-shadow:0 0 10px rgba(0,0,0,0.5);' +
128
- 'padding:20px; overflow:auto; z-index:2147483646; font:13px/1.4 monospace;' +
129
- 'white-space:pre; display:block; opacity:1; visibility:visible';
142
+ "position:fixed; top:20px; left:20px; right:20px; max-height:calc(100vh - 40px);" +
143
+ "background:#fff; border:1px solid #333; box-shadow:0 0 10px rgba(0,0,0,0.5);" +
144
+ "padding:20px; overflow:auto; z-index:2147483646; font:13px/1.4 monospace;" +
145
+ "white-space:pre; display:block; opacity:1; visibility:visible";
130
146
  }
131
147
 
132
148
  // Check if we have a saved index and it's still valid
133
- const savedIndex = parseInt(localStorage.getItem('_LOG_INDEX'));
149
+ const savedIndex = parseInt(localStorage.getItem("_LOG_INDEX"));
134
150
  if (!isNaN(savedIndex) && savedIndex >= 0 && savedIndex < logs.length) {
135
151
  currentIndex = savedIndex;
136
152
  } else {
@@ -138,36 +154,42 @@ const LOG = (() => {
138
154
  }
139
155
 
140
156
  renderContent = () => {
141
- const buttons = logs.map((_, i) => {
142
- let bgColor = '#f0f0f0'; // default
143
- if (i !== currentIndex) {
144
- if (logTypes[i] === 'object') {
145
- bgColor = '#d6e3ef'; // super light blue
146
- } else if (logTypes[i] === 'array') {
147
- bgColor = '#d8d5ef'; // super light indigo
157
+ const buttons = logs
158
+ .map((_, i) => {
159
+ let bgColor = "#f0f0f0"; // default
160
+ if (i !== currentIndex) {
161
+ if (logTypes[i] === "object") {
162
+ bgColor = "#d6e3ef"; // super light blue
163
+ } else if (logTypes[i] === "array") {
164
+ bgColor = "#d8d5ef"; // super light indigo
165
+ }
148
166
  }
149
- }
150
- return `<button style="font-size: 14px; font-weight: 400; padding:2px 6px; margin: 0 2px 2px 0;cursor:pointer;background:${i === currentIndex ? '#333' : bgColor};color:${i === currentIndex ? '#fff' : '#000'}" data-index="${i}">${i + 1}</button>`
151
- }).join('');
167
+ return `<button style="font-size: 14px; font-weight: 400; padding:2px 6px; margin: 0 2px 2px 0;cursor:pointer;background:${i === currentIndex ? "#333" : bgColor};color:${i === currentIndex ? "#fff" : "#000"}" data-index="${i}">${i + 1}</button>`;
168
+ })
169
+ .join("");
152
170
 
153
171
  d.innerHTML =
154
172
  '<div style="display:flex;flex-direction:column;height:100%">' +
155
173
  '<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px">' +
156
- '<div style="display:flex;flex-wrap:wrap;gap:4px;flex:1;margin-right:10px">' + buttons + '</div>' +
174
+ '<div style="display:flex;flex-wrap:wrap;gap:4px;flex:1;margin-right:10px">' +
175
+ buttons +
176
+ "</div>" +
157
177
  '<button style="padding:4px 8px;cursor:pointer;flex-shrink:0">&times;</button>' +
158
- '</div>' +
159
- '<xmp style="font-family:monospace;flex:1;overflow:auto;margin:0;padding:0;color:#000;background:#fff;font-size:14px;line-height:22px">' + logs[currentIndex] + '</xmp>' +
160
- '</div>';
178
+ "</div>" +
179
+ '<xmp style="font-family:monospace;flex:1;overflow:auto;margin:0;padding:0;color:#000;background:#fff;font-size:14px;line-height:22px">' +
180
+ logs[currentIndex] +
181
+ "</xmp>" +
182
+ "</div>";
161
183
 
162
184
  d.querySelector('button[style*="flex-shrink:0"]').onclick = () => {
163
185
  d.remove();
164
186
  createLogButton();
165
187
  };
166
188
 
167
- d.querySelectorAll('button[data-index]').forEach(btn => {
189
+ d.querySelectorAll("button[data-index]").forEach((btn) => {
168
190
  btn.onclick = () => {
169
191
  currentIndex = parseInt(btn.dataset.index);
170
- localStorage.setItem('_LOG_INDEX', currentIndex);
192
+ localStorage.setItem("_LOG_INDEX", currentIndex);
171
193
  renderContent();
172
194
  };
173
195
  });
@@ -176,10 +198,10 @@ const LOG = (() => {
176
198
  renderContent();
177
199
  };
178
200
 
179
- return o => {
201
+ return (o) => {
180
202
  if (!document.body) {
181
- window.requestAnimationFrame( () => LOG(o) )
182
- return
203
+ window.requestAnimationFrame(() => LOG(o));
204
+ return;
183
205
  }
184
206
 
185
207
  // Store the original type
@@ -187,37 +209,45 @@ const LOG = (() => {
187
209
 
188
210
  if (o instanceof Node) {
189
211
  if (o.nodeType === Node.TEXT_NODE) {
190
- o = o.textContent || String(o)
212
+ o = o.textContent || String(o);
191
213
  } else {
192
- o = log_pretty_print(o.outerHTML)
214
+ o = log_pretty_print(o.outerHTML);
193
215
  }
194
216
  }
195
217
 
196
- if (o === undefined) { o = 'undefined' }
197
- if (o === null) { o = 'null' }
218
+ if (o === undefined) {
219
+ o = "undefined";
220
+ }
221
+ if (o === null) {
222
+ o = "null";
223
+ }
198
224
 
199
225
  if (Array.isArray(o)) {
200
- originalType = 'array';
201
- } else if (typeof o === 'object' && o !== null) {
202
- originalType = 'object';
226
+ originalType = "array";
227
+ } else if (typeof o === "object" && o !== null) {
228
+ originalType = "object";
203
229
  }
204
230
 
205
- if (typeof o != 'string') {
206
- o = JSON.stringify(o, (key, value) => {
207
- if (typeof value === 'function') {
208
- return String(value);
209
- }
210
- return value;
211
- }, 2).replaceAll('<', '&lt;')
231
+ if (typeof o != "string") {
232
+ o = JSON.stringify(
233
+ o,
234
+ (key, value) => {
235
+ if (typeof value === "function") {
236
+ return String(value);
237
+ }
238
+ return value;
239
+ },
240
+ 2,
241
+ ).replaceAll("<", "&lt;");
212
242
  }
213
243
 
214
- o = o.trim()
244
+ o = o.trim();
215
245
 
216
246
  logs.push(o + `\n\ntype: ${originalType}`);
217
247
  logTypes.push(originalType);
218
248
 
219
249
  // Check if log dialog is open by checking for element
220
- const isOpen = !!document.getElementById('dump-dialog');
250
+ const isOpen = !!document.getElementById("dump-dialog");
221
251
 
222
252
  if (!isOpen) {
223
253
  // Show log dialog by default
@@ -225,7 +255,7 @@ const LOG = (() => {
225
255
  } else {
226
256
  // Update current index to the new log and refresh
227
257
  currentIndex = logs.length - 1;
228
- localStorage.setItem('_LOG_INDEX', currentIndex);
258
+ localStorage.setItem("_LOG_INDEX", currentIndex);
229
259
  if (renderContent) {
230
260
  renderContent();
231
261
  }
@@ -233,8 +263,8 @@ const LOG = (() => {
233
263
  };
234
264
  })();
235
265
 
236
- if (typeof window !== 'undefined' && !window.LOG) {
237
- window.LOG = LOG
266
+ if (typeof window !== "undefined" && !window.LOG) {
267
+ window.LOG = LOG;
238
268
  }
239
269
 
240
- export default LOG
270
+ export default LOG;
@@ -75,7 +75,7 @@ const highlightAll = () => {
75
75
  // Add click handler to dump the node
76
76
  label.addEventListener('click', (e) => {
77
77
  e.stopPropagation();
78
- Fez.dump(el);
78
+ Fez.log(el);
79
79
  });
80
80
 
81
81
  overlay.appendChild(label);
package/src/fez.js CHANGED
@@ -1,65 +1,87 @@
1
- // base class for custom dom objects
2
- import FezBase from './fez/instance.js'
3
- if (typeof window !== 'undefined') window.FezBase = FezBase
1
+ /**
2
+ * Fez - Runtime Custom DOM Elements Library
3
+ *
4
+ * Entry point that:
5
+ * - Exports FezBase and Fez
6
+ * - Sets up auto-compilation observer
7
+ * - Handles garbage collection
8
+ */
9
+
10
+ // =============================================================================
11
+ // EXPORTS
12
+ // =============================================================================
4
13
 
5
- // base class for custom dom objects
14
+ import FezBase from './fez/instance.js'
6
15
  import Fez from './fez/root.js'
7
- if (typeof window !== 'undefined') window.Fez = Fez
8
16
 
9
- // Load defaults after Fez is properly initialized
17
+ // Expose to window
18
+ if (typeof window !== 'undefined') {
19
+ window.FezBase = FezBase
20
+ window.Fez = Fez
21
+ }
22
+
23
+ // Load default components
10
24
  import('./fez/defaults.js')
11
25
 
12
- // clear all unattached nodes
13
- setInterval(() => {
14
- for (const [key, el] of Fez.instances) {
15
- if (!el?.isConnected) {
16
- // Fez.error(`Found junk instance that is not connected ${el.fezName}`)
17
- el.fez?.fezOnDestroy()
18
- Fez.instances.delete(key)
19
- }
20
- }
21
- }, 5_000)
26
+ // =============================================================================
27
+ // AUTO-COMPILATION OBSERVER
28
+ // =============================================================================
22
29
 
23
- // define Fez observer
24
- const observer = new MutationObserver((mutations) => {
30
+ // Watch for template/xmp/script[fez] elements and compile them
31
+ const observer = new MutationObserver(mutations => {
25
32
  for (const { addedNodes, removedNodes } of mutations) {
26
- addedNodes.forEach((node) => {
27
- if (node.nodeType !== 1) return; // only elements
33
+ // Compile new fez templates
34
+ addedNodes.forEach(node => {
35
+ if (node.nodeType !== 1) return
28
36
 
29
- if (node.matches('template[fez], xmp[fez], script[fez]')) {
30
- Fez.compile(node);
31
- node.remove();
37
+ if (node.matches?.('template[fez], xmp[fez], script[fez]')) {
38
+ Fez.compile(node)
39
+ node.remove()
32
40
  }
33
41
 
34
- if (node.querySelectorAll) {
35
- const nestedTemplates = node.querySelectorAll('template[fez], xmp[fez], script[fez]');
36
- nestedTemplates.forEach(template => {
37
- Fez.compile(template);
38
- template.remove();
39
- });
40
- }
41
- });
42
+ node.querySelectorAll?.('template[fez], xmp[fez], script[fez]').forEach(tpl => {
43
+ Fez.compile(tpl)
44
+ tpl.remove()
45
+ })
46
+ })
47
+
48
+ // Cleanup removed components
49
+ // Use microtask to check if node was just moved (will be reconnected)
50
+ // vs actually removed from the document
51
+ removedNodes.forEach(node => {
52
+ if (node.nodeType !== 1) return
42
53
 
43
- removedNodes.forEach((node) => {
44
- if (node.nodeType === 1 && node.querySelectorAll) {
45
- const fezElements = node.querySelectorAll('.fez, :scope.fez');
46
- fezElements
47
- .forEach(el => {
48
- if (el.fez && el.root) {
54
+ // Helper to cleanup a single element
55
+ const cleanup = (el) => {
56
+ if (el.fez && !el.fez._destroyed) {
57
+ // Delay cleanup to check if node is reconnected (just moved, not removed)
58
+ queueMicrotask(() => {
59
+ // If still not connected and not destroyed, cleanup
60
+ if (!el.isConnected && el.fez && !el.fez._destroyed) {
49
61
  Fez.instances.delete(el.fez.UID)
50
62
  el.fez.fezOnDestroy()
51
63
  }
52
- });
64
+ })
65
+ }
53
66
  }
54
- });
67
+
68
+ // Check if removed node itself is a fez component
69
+ cleanup(node)
70
+
71
+ // Check all children for fez components
72
+ node.querySelectorAll?.('.fez')?.forEach(cleanup)
73
+ })
55
74
  }
56
- });
75
+ })
57
76
 
58
- // start observing the whole document
59
77
  observer.observe(document.documentElement, {
60
78
  childList: true,
61
79
  subtree: true
62
- });
80
+ })
81
+
82
+ // =============================================================================
83
+ // MODULE EXPORTS
84
+ // =============================================================================
63
85
 
64
86
  export default Fez
65
- export { Fez }
87
+ export { Fez, FezBase }
package/src/rollup.js CHANGED
@@ -13,7 +13,7 @@ const transformFez = (code, filePath) => {
13
13
  const baseName = filePath.split('/').pop().split('.');
14
14
 
15
15
  if (baseName[1] === 'fez') {
16
- code = code.replace(/`/g, '\\`').replace(/\$/g, '\\$');
16
+ code = code.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$');
17
17
  return `Fez.compile('${baseName[0]}', \`\n${code}\`)`;
18
18
  }
19
19
  }
@@ -1,3 +1,6 @@
1
+ # export let props // to get props object
2
+ # export let fast // to say we so not accept slots
3
+
1
4
  # get node attributes
2
5
  getAttributes = (node) ->
3
6
  attrs = {}
@@ -6,8 +9,11 @@ getAttributes = (node) ->
6
9
  if el.name.startsWith('on') && el.value[0] == '('
7
10
  el.value = new Function('arg1, arg2', "(#{el.value})(arg1, arg2)")
8
11
  if el.name.startsWith(':')
9
- el.value = new Function("return (#{el.value})").bind(node)()
10
- el.name = el.name.replace(':', '')
12
+ try
13
+ el.value = new Function("return (#{el.value})").bind(node)()
14
+ el.name = el.name.replace(':', '')
15
+ catch e
16
+ console.error "Error evaluating #{el.name}=\"#{el.value}\" for #{node.tagName}: #{e.message}"
11
17
  attrs[el.name] = el.value
12
18
 
13
19
  if attrs['data-props']
@@ -100,18 +106,19 @@ Svelte.connect = (name, klass) ->
100
106
  # %s-menu-vertical{ fast_connect: true }
101
107
 
102
108
  # connect @, name, klass
103
- # if @firstChild && (klass.prototype.hasOwnProperty('fast') || @getAttribute('fast_connect') || @getAttribute('data-props') || @getAttribute('data-json-template'))
104
- # connect @, name, klass
105
- # else
106
- # requestAnimationFrame =>
107
- # connect @, name, klass
108
109
 
109
- if document.readyState == 'loading'
110
- document.addEventListener 'DOMContentLoaded',
111
- => connect(@, name, klass)
112
- , once: true
110
+ if this.childNodes[0] || this.nextSibling || klass.prototype.hasOwnProperty('fast') || klass.prototype.hasOwnProperty('FAST') || @getAttribute('fast_connect') || @getAttribute('data-props') || @getAttribute('data-json-template')
111
+ connect @, name, klass
113
112
  else
114
- connect(@, name, klass)
113
+ requestAnimationFrame =>
114
+ connect @, name, klass
115
+
116
+ # if document.readyState == 'loading'
117
+ # document.addEventListener 'DOMContentLoaded',
118
+ # => connect(@, name, klass)
119
+ # , once: true
120
+ # else
121
+ # connect(@, name, klass)
115
122
 
116
123
  # Creates HTML tag
117
124
  Svelte.tag = (tag, opts = {}, html = '') ->
@@ -120,3 +127,5 @@ Svelte.tag = (tag, opts = {}, html = '') ->
120
127
 
121
128
  Svelte.bind = Svelte.connect
122
129
  window.Svelte = Svelte
130
+
131
+ export default Svelte