@markdy/astro 0.7.4 → 0.7.8
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/package.json +3 -3
- package/src/Markdy.astro +49 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markdy/astro",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"description": "Astro island component for MarkdyScript animations.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@markdy/renderer-dom": "0.7.
|
|
40
|
+
"@markdy/renderer-dom": "0.7.8"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"astro": ">=4.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"astro": "^
|
|
46
|
+
"astro": "^7.1.1",
|
|
47
47
|
"typescript": "^5.9.3"
|
|
48
48
|
}
|
|
49
49
|
}
|
package/src/Markdy.astro
CHANGED
|
@@ -121,24 +121,40 @@ const {
|
|
|
121
121
|
</noscript>
|
|
122
122
|
</div>
|
|
123
123
|
|
|
124
|
+
<!--
|
|
125
|
+
Rocket Loader rescue. Cloudflare Rocket Loader rewrites module script
|
|
126
|
+
tags in two ways, both of which prevent hydration:
|
|
127
|
+
(A) changes type="module" to a uuid-prefixed value while keeping the tag,
|
|
128
|
+
(B) wraps the whole script tag in an HTML comment, making it invisible to
|
|
129
|
+
querySelectorAll.
|
|
130
|
+
|
|
131
|
+
Two independent triggers run, either of which is sufficient:
|
|
132
|
+
|
|
133
|
+
1. The inline script with data-cfasync="false" runs as authored when
|
|
134
|
+
Cloudflare honours the official cfasync opt-out (the documented
|
|
135
|
+
escape hatch; works almost always in practice).
|
|
136
|
+
|
|
137
|
+
2. The img with an onerror handler is a true belt-and-suspenders
|
|
138
|
+
backup. Inline event handlers are never rewritten by Rocket Loader,
|
|
139
|
+
so this still fires when the inline script gets rewritten and never
|
|
140
|
+
executes. The invalid base64 in the data URL guarantees that the
|
|
141
|
+
decode fails synchronously without any network round trip. The
|
|
142
|
+
handler covers case (A) only — it re-injects every rewritten
|
|
143
|
+
module script — which is enough to bootstrap Markdy hydration even
|
|
144
|
+
when the main rescue script never runs.
|
|
145
|
+
-->
|
|
124
146
|
<script is:inline data-cfasync="false">
|
|
125
|
-
// ── Rocket Loader rescue ──────────────────────────────────────────────────
|
|
126
|
-
// Cloudflare Rocket Loader rewrites <script type="module" src="..."> in
|
|
127
|
-
// one of two ways, both of which prevent the hydration logic from running:
|
|
128
|
-
//
|
|
129
|
-
// A) Changes type="module" → type="{uuid}-module" (keeps tag in DOM)
|
|
130
|
-
// B) Wraps the entire tag in an HTML comment:
|
|
131
|
-
// <!--<script type="{uuid}-module" src="..."></script>-->
|
|
132
|
-
// making it invisible to querySelectorAll.
|
|
133
|
-
//
|
|
134
|
-
// `data-cfasync="false"` keeps this rescue script executable even when
|
|
135
|
-
// Rocket Loader is active. It rescues module scripts via two strategies:
|
|
136
|
-
// 1. Query the DOM for type$="-module" + src (covers case A)
|
|
137
|
-
// 2. Regex-parse the raw HTML for commented-out script tags (covers case B)
|
|
138
|
-
// Dynamically-created scripts bypass Rocket Loader entirely.
|
|
139
147
|
(function () {
|
|
140
|
-
if (window.
|
|
141
|
-
window.
|
|
148
|
+
if (window.__markdyRescued) return;
|
|
149
|
+
window.__markdyRescued = true;
|
|
150
|
+
|
|
151
|
+
// Build regexes from string parts so the literal token sequences for
|
|
152
|
+
// opening/closing HTML comments and the closing script tag never appear
|
|
153
|
+
// in this file's source. The HTML parser and Astro's JSX parser would
|
|
154
|
+
// otherwise treat them as special and corrupt the surrounding markup.
|
|
155
|
+
var OPEN = '\x3c' + '!--';
|
|
156
|
+
var CLOSE = '--' + '\x3e';
|
|
157
|
+
var CLOSE_SCRIPT = '\x3c' + '/script' + '\x3e';
|
|
142
158
|
|
|
143
159
|
var rescued = false;
|
|
144
160
|
function rescueModuleScripts() {
|
|
@@ -147,28 +163,24 @@ const {
|
|
|
147
163
|
|
|
148
164
|
var srcs = [];
|
|
149
165
|
|
|
150
|
-
//
|
|
151
|
-
// type="module" → type="{uuid}-module" (still has src attribute)
|
|
166
|
+
// Case (A): Rocket Loader kept the tag in DOM but mangled the type.
|
|
152
167
|
document.querySelectorAll('script[type$="-module"][src]').forEach(function (s) {
|
|
153
168
|
srcs.push(s.src);
|
|
154
169
|
});
|
|
155
170
|
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
// These are invisible to querySelectorAll, so we parse the raw HTML.
|
|
159
|
-
// We handle both attribute orderings (type-first or src-first).
|
|
171
|
+
// Case (B): Rocket Loader commented out the entire script tag.
|
|
172
|
+
// These are invisible to querySelectorAll, so parse the raw HTML.
|
|
160
173
|
var html = document.documentElement.innerHTML;
|
|
161
|
-
var reSrcFirst =
|
|
162
|
-
var reTypeFirst =
|
|
174
|
+
var reSrcFirst = new RegExp(OPEN + '\x3cscript\\s[^>]*src="([^"]+)"[^>]*type="[^"]*-module"[^>]*>\\s*' + CLOSE_SCRIPT + CLOSE, 'g');
|
|
175
|
+
var reTypeFirst = new RegExp(OPEN + '\x3cscript\\s[^>]*type="[^"]*-module"[^>]*src="([^"]+)"[^>]*>\\s*' + CLOSE_SCRIPT + CLOSE, 'g');
|
|
163
176
|
var m;
|
|
164
177
|
while ((m = reSrcFirst.exec(html)) !== null) { srcs.push(m[1]); }
|
|
165
178
|
while ((m = reTypeFirst.exec(html)) !== null) { srcs.push(m[1]); }
|
|
166
179
|
|
|
167
|
-
// Re-inject each found src as a real module script.
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
//
|
|
171
|
-
// is safe.
|
|
180
|
+
// Re-inject each found src as a real module script. Dynamically-created
|
|
181
|
+
// scripts bypass Rocket Loader entirely; data-cfasync="false" is added
|
|
182
|
+
// as belt-and-suspenders. Modules with the same URL only execute once,
|
|
183
|
+
// so re-injecting an already-running script is safe.
|
|
172
184
|
var seen = {};
|
|
173
185
|
srcs.forEach(function (src) {
|
|
174
186
|
if (seen[src]) return;
|
|
@@ -199,6 +211,14 @@ const {
|
|
|
199
211
|
}());
|
|
200
212
|
</script>
|
|
201
213
|
|
|
214
|
+
<img
|
|
215
|
+
src="data:image/gif;base64,!"
|
|
216
|
+
alt=""
|
|
217
|
+
aria-hidden="true"
|
|
218
|
+
style="display:none"
|
|
219
|
+
onerror="if(!window.__markdyRescued){window.__markdyRescued=true;document.querySelectorAll('script[type$="-module"][src]').forEach(function(s){var f=document.createElement('script');f.type='module';f.src=s.src;f.setAttribute('data-cfasync','false');document.head.appendChild(f);});}"
|
|
220
|
+
/>
|
|
221
|
+
|
|
202
222
|
<script>
|
|
203
223
|
// ── Hydration ────────────────────────────────────────────────────────────
|
|
204
224
|
// The renderer is dynamically imported so it is code-split from the
|