@accelerated-agency/visual-editor 0.4.5 → 0.4.7
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/dist/vite.cjs +255 -106
- package/dist/vite.js +255 -106
- package/package.json +1 -1
package/dist/vite.cjs
CHANGED
|
@@ -11,20 +11,6 @@ var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
|
11
11
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
12
12
|
|
|
13
13
|
// src/visualEditorProxyPlugin.ts
|
|
14
|
-
var SCRAPER_PROXY_HOST = process.env.SCRAPERAPI_PROXY_HOST || "proxy-server.scraperapi.com";
|
|
15
|
-
var SCRAPER_PROXY_PORT = Number(process.env.SCRAPERAPI_PROXY_PORT || "8001");
|
|
16
|
-
var SCRAPER_PROXY_USERNAME_BASE = process.env.SCRAPERAPI_PROXY_USERNAME_BASE || "scraperapi";
|
|
17
|
-
var SCRAPER_PROXY_USERNAME_PARAMS = process.env.SCRAPERAPI_PROXY_USERNAME_PARAMS || "render=true.wait_for_selector=body.follow_redirect=false.keep_headers=true";
|
|
18
|
-
var SCRAPER_PROXY_USERNAME = process.env.SCRAPERAPI_PROXY_USERNAME || [
|
|
19
|
-
SCRAPER_PROXY_USERNAME_BASE,
|
|
20
|
-
SCRAPER_PROXY_USERNAME_PARAMS
|
|
21
|
-
].filter(Boolean).join(".");
|
|
22
|
-
var SCRAPER_PROXY_PASSWORD = process.env.SCRAPERAPI_PROXY_PASSWORD || process.env.SCRAPERAPI_API_KEY;
|
|
23
|
-
var SCRAPER_API_ENDPOINT = process.env.SCRAPERAPI_ENDPOINT || "https://api.scraperapi.com/";
|
|
24
|
-
var SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED_RAW = process.env.SCRAPERAPI_REQUEST_TLS_REJECT_UNAUTHORIZED || "false";
|
|
25
|
-
var SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED = !["0", "false", "no"].includes(
|
|
26
|
-
SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED_RAW.toLowerCase()
|
|
27
|
-
);
|
|
28
14
|
var DEFAULT_TRACKING_MARKERS = [
|
|
29
15
|
"snowplow",
|
|
30
16
|
"taboola",
|
|
@@ -122,31 +108,9 @@ function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
|
122
108
|
}
|
|
123
109
|
return out;
|
|
124
110
|
}
|
|
125
|
-
var
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (scraperProxyClientPromise) return scraperProxyClientPromise;
|
|
129
|
-
scraperProxyClientPromise = (async () => {
|
|
130
|
-
if (!SCRAPER_PROXY_PASSWORD) return null;
|
|
131
|
-
try {
|
|
132
|
-
const undici = await import('undici');
|
|
133
|
-
const proxyUrl = "http://" + encodeURIComponent(SCRAPER_PROXY_USERNAME) + ":" + encodeURIComponent(SCRAPER_PROXY_PASSWORD) + "@" + SCRAPER_PROXY_HOST + ":" + String(SCRAPER_PROXY_PORT);
|
|
134
|
-
return {
|
|
135
|
-
dispatcher: new undici.ProxyAgent({
|
|
136
|
-
uri: proxyUrl,
|
|
137
|
-
requestTls: {
|
|
138
|
-
rejectUnauthorized: SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED
|
|
139
|
-
}
|
|
140
|
-
}),
|
|
141
|
-
fetchFn: undici.fetch
|
|
142
|
-
};
|
|
143
|
-
} catch (_) {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
})();
|
|
147
|
-
return scraperProxyClientPromise;
|
|
148
|
-
}
|
|
149
|
-
var iframeAlwaysShowCss = `<style id="__ce_force_show">#CybotCookiebotDialog,#CybotCookiebotDialogBodyUnderlay,#onetrust-consent-sdk,#onetrust-banner-sdk,.cc-window,.cc-banner,.cc-overlay,#cookie-notice,#cookie-banner,#cookie-consent,.cookie-notice,.cookie-banner,.cookie-consent,.cookie-popup,.cookie-bar,.cookie-message,.cookie-alert,.gdpr-banner,.gdpr-consent,.gdpr-popup,.gdpr-overlay,#gdpr-consent,#gdpr-banner,.consent-banner,.consent-popup,.consent-overlay,#consent-banner,#consent-popup,[class*="cookie-consent"],[class*="cookie-banner"],[class*="cookie-notice"],[class*="CookieConsent"],[class*="CookieBanner"],[id*="cookie-consent"],[id*="cookie-banner"],[id*="cookie-notice"],[aria-label*="cookie" i],[aria-label*="consent" i],.klaro,.klaro .cookie-modal,#usercentrics-root,.trustarc-banner,#truste-consent-track,#hs-eu-cookie-confirmation,.osano-cm-window,.osano-cm-dialog,.evidon-banner,#_evidon_banner,.js-cookie-consent,.cookie-disclaimer,.shopify-section-cookies,#shopify-section-cookies,#shopify-pc__banner,#shopify-pc__modal,.privacy-banner,.privacy-popup,[data-testid="cookie-banner"],[data-testid="consent-banner"],.amgdprcookie-bar-container,[data-amcookie-js="bar"],.amgdprjs-bar-template,.amgdprcookie-modal-container,.amgdprcookie-modal-overlay,#cmplz-cookiebanner-container,.cmplz-cookiebanner,#iubenda-cs-banner,.iubenda-cs-container,#qc-cmp2-container,.qc-cmp2-consent-info,#didomi-host,.didomi-popup-container,.didomi-notice,#termly-code-snippet-support,[class*="termly"],[class*="gdprcookie"],[class*="amgdpr"],[id*="gdpr-cookie"],[class*="cookie-modal"],[id*="cookie-modal"],[class*="cookieConsent"],[id*="cookieConsent"]{display:revert!important;visibility:visible!important;opacity:1!important;pointer-events:auto!important;height:auto!important;max-height:none!important;overflow:visible!important;}</style>`;
|
|
111
|
+
var iframeAlwaysShowCss = `<style id="__ce_force_show">
|
|
112
|
+
|
|
113
|
+
</style>`;
|
|
150
114
|
var iframeAlwaysShowCssGuardScript = `<script id="__ce_force_show_guard">(function(){try{
|
|
151
115
|
function ensureForceShowStyleLast(){
|
|
152
116
|
var style=document.getElementById("__ce_force_show");
|
|
@@ -505,7 +469,10 @@ box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.20), 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 1p
|
|
|
505
469
|
.dt-ico{width:16px;flex-shrink:0;text-align:center;color:var(--text-3);font-size:12px}
|
|
506
470
|
.dt-lbl{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,monospace;font-size:10px}
|
|
507
471
|
.dt-muted{padding:16px 12px;text-align:center;color:var(--text-3);font-size:11px;line-height:1.4}
|
|
508
|
-
|
|
472
|
+
#section-components-panel{
|
|
473
|
+
max-height: 50%;
|
|
474
|
+
overflow-y: auto;
|
|
475
|
+
}
|
|
509
476
|
/* \u2500\u2500 Right panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
510
477
|
#right-panel{
|
|
511
478
|
width:252px;background:var(--bg);border-left:1px solid var(--border);
|
|
@@ -634,6 +601,17 @@ box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.20), 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 1p
|
|
|
634
601
|
flex:1;padding:8px 2px;text-align:center;font-size:10px;color:var(--text-3);
|
|
635
602
|
cursor:pointer;border-bottom:2px solid transparent;transition:all .15s;font-weight:600;line-height:1.15
|
|
636
603
|
}
|
|
604
|
+
.lp-tab.close-section-components-panel{
|
|
605
|
+
padding: 4px 10px;
|
|
606
|
+
background: #000;
|
|
607
|
+
display: flex;
|
|
608
|
+
max-width: fit-content;
|
|
609
|
+
align-items: center;
|
|
610
|
+
justify-content: center;
|
|
611
|
+
border-radius: 2px;
|
|
612
|
+
margin: 2px;
|
|
613
|
+
color: #fff;
|
|
614
|
+
}
|
|
637
615
|
.lp-tab:hover{color:var(--text-2)}
|
|
638
616
|
.lp-tab.active{color:var(--accent-txt);border-bottom-color:var(--accent)}
|
|
639
617
|
.future-hidden{display:none!important}
|
|
@@ -1142,6 +1120,7 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
1142
1120
|
<div class="section-components-tabs">
|
|
1143
1121
|
<div class="lp-tab" onclick="switchSectionComponentsTab('components')">Components</div>
|
|
1144
1122
|
<div class="lp-tab" onclick="switchSectionComponentsTab('sections')">Sections</div>
|
|
1123
|
+
<div class="lp-tab close-section-components-panel" onclick="toggleSectionComponentsPanel()"> Close</div>
|
|
1145
1124
|
</div>
|
|
1146
1125
|
<div class="lp-body">
|
|
1147
1126
|
<div id="tab-components" class="tab-pane"></div>
|
|
@@ -3266,6 +3245,35 @@ function parseEditorUrlPayload(rawUrl) {
|
|
|
3266
3245
|
password: nestedPassword || undefined,
|
|
3267
3246
|
};
|
|
3268
3247
|
}
|
|
3248
|
+
var path = parsed.pathname || '';
|
|
3249
|
+
var isProxyPath =
|
|
3250
|
+
path === '/api/conversion-proxy' ||
|
|
3251
|
+
path.indexOf('/api/conversion-proxy/') === 0 ||
|
|
3252
|
+
path.indexOf('api/conversion-proxy') !== -1;
|
|
3253
|
+
if (isProxyPath) {
|
|
3254
|
+
var fallbackUrl = (experimentData && experimentData.pageUrl) ? String(experimentData.pageUrl) : '';
|
|
3255
|
+
if (fallbackUrl) {
|
|
3256
|
+
var recovered = new URL(fallbackUrl, window.location.href);
|
|
3257
|
+
var qp = new URLSearchParams(parsed.search || '');
|
|
3258
|
+
qp.delete('url');
|
|
3259
|
+
qp.delete('password');
|
|
3260
|
+
qp.delete('conversionProxyBaseUrl');
|
|
3261
|
+
qp.delete('trackingMarkers');
|
|
3262
|
+
qp.delete('strictObserverFreeze');
|
|
3263
|
+
qp.delete('proxy');
|
|
3264
|
+
qp.delete('raw');
|
|
3265
|
+
recovered.search = '';
|
|
3266
|
+
qp.forEach(function(v, k) { recovered.searchParams.set(k, v); });
|
|
3267
|
+
recovered.hash = parsed.hash || '';
|
|
3268
|
+
return {
|
|
3269
|
+
url: recovered.toString(),
|
|
3270
|
+
password:
|
|
3271
|
+
(experimentData && experimentData.editorPassword)
|
|
3272
|
+
? String(experimentData.editorPassword)
|
|
3273
|
+
: undefined,
|
|
3274
|
+
};
|
|
3275
|
+
}
|
|
3276
|
+
}
|
|
3269
3277
|
return {
|
|
3270
3278
|
url: parsed.toString(),
|
|
3271
3279
|
password:
|
|
@@ -3284,6 +3292,12 @@ function emitEditorUrlChangedPayload(payload) {
|
|
|
3284
3292
|
var key = String(payload.url || '') + '|' + String(payload.password || '');
|
|
3285
3293
|
if (key === lastEditorUrlPayloadKey) return;
|
|
3286
3294
|
lastEditorUrlPayloadKey = key;
|
|
3295
|
+
try {
|
|
3296
|
+
console.info('[V2 iframe-url]', {
|
|
3297
|
+
url: payload.url || '',
|
|
3298
|
+
passwordPresent: !!payload.password,
|
|
3299
|
+
});
|
|
3300
|
+
} catch(_) {}
|
|
3287
3301
|
send('editor-url-changed', payload);
|
|
3288
3302
|
}
|
|
3289
3303
|
function emitEditorUrlChanged(rawUrl) {
|
|
@@ -5056,6 +5070,67 @@ function stripDataVveInstanceSubtree(root) {
|
|
|
5056
5070
|
}
|
|
5057
5071
|
}
|
|
5058
5072
|
|
|
5073
|
+
function cssEscapeIdent(raw) {
|
|
5074
|
+
var s = raw == null ? '' : String(raw);
|
|
5075
|
+
if (!s) return '';
|
|
5076
|
+
try {
|
|
5077
|
+
if (typeof CSS !== 'undefined' && CSS && typeof CSS.escape === 'function') {
|
|
5078
|
+
return CSS.escape(s);
|
|
5079
|
+
}
|
|
5080
|
+
} catch(_) {}
|
|
5081
|
+
// Fallback escape for identifiers when CSS.escape is unavailable.
|
|
5082
|
+
return s.replace(/[^a-zA-Z0-9_-]/g, function(ch) { return '\\\\' + ch; });
|
|
5083
|
+
}
|
|
5084
|
+
|
|
5085
|
+
function unescapeCssToken(token) {
|
|
5086
|
+
if (!token) return '';
|
|
5087
|
+
var s = String(token);
|
|
5088
|
+
var out = '';
|
|
5089
|
+
for (var i = 0; i < s.length; i++) {
|
|
5090
|
+
var ch = s.charAt(i);
|
|
5091
|
+
if (ch === '\\\\' && i + 1 < s.length) {
|
|
5092
|
+
out += s.charAt(i + 1);
|
|
5093
|
+
i += 1;
|
|
5094
|
+
continue;
|
|
5095
|
+
}
|
|
5096
|
+
out += ch;
|
|
5097
|
+
}
|
|
5098
|
+
return out;
|
|
5099
|
+
}
|
|
5100
|
+
|
|
5101
|
+
function isGeneratedClassToken(token) {
|
|
5102
|
+
var t = token == null ? '' : String(token).trim();
|
|
5103
|
+
if (!t) return true;
|
|
5104
|
+
if (t.indexOf('vve-') === 0) return true;
|
|
5105
|
+
// Tailwind arbitrary values / variant-heavy utilities are often unstable in selectors.
|
|
5106
|
+
if (
|
|
5107
|
+
t.indexOf('[') !== -1 ||
|
|
5108
|
+
t.indexOf(']') !== -1 ||
|
|
5109
|
+
t.indexOf('(') !== -1 ||
|
|
5110
|
+
t.indexOf(')') !== -1 ||
|
|
5111
|
+
t.indexOf('{') !== -1 ||
|
|
5112
|
+
t.indexOf('}') !== -1 ||
|
|
5113
|
+
t.indexOf(':') !== -1
|
|
5114
|
+
) return true;
|
|
5115
|
+
// CSS-in-JS / runtime hash prefixes.
|
|
5116
|
+
if (/^(css|jsx|sc|emotion|styled|chakra|mantine|mui|ant)-/i.test(t)) return true;
|
|
5117
|
+
// Classnames with long hashy suffixes (framework/runtime generated).
|
|
5118
|
+
if (/[a-f0-9]{8,}/i.test(t)) return true;
|
|
5119
|
+
if (/^[a-zA-Z_-]+[0-9]{4,}[a-zA-Z0-9_-]*$/.test(t)) return true;
|
|
5120
|
+
if (/^[a-zA-Z0-9_-]{36,}$/.test(t)) return true;
|
|
5121
|
+
return false;
|
|
5122
|
+
}
|
|
5123
|
+
|
|
5124
|
+
function escapeSelectorClassTokens(sel) {
|
|
5125
|
+
if (!sel || typeof sel !== 'string') return '';
|
|
5126
|
+
return sel.replace(/.((?:\\.|[^s>+~:#.])+)/g, function(_m, cls) {
|
|
5127
|
+
if (!cls) return _m;
|
|
5128
|
+
// Already escaped token; keep it as-is.
|
|
5129
|
+
if (cls.indexOf('\\\\') >= 0) return '.' + cls;
|
|
5130
|
+
return '.' + cssEscapeIdent(cls);
|
|
5131
|
+
});
|
|
5132
|
+
}
|
|
5133
|
+
|
|
5059
5134
|
function buildSelector(el) {
|
|
5060
5135
|
if (!el) return '';
|
|
5061
5136
|
var doc = el.ownerDocument || document;
|
|
@@ -5067,16 +5142,16 @@ function buildSelector(el) {
|
|
|
5067
5142
|
if (doc.querySelectorAll(attrSel).length === 1) return attrSel;
|
|
5068
5143
|
} catch(_) {}
|
|
5069
5144
|
}
|
|
5070
|
-
if (el.id) return '#' + el.id;
|
|
5145
|
+
if (el.id) return '#' + cssEscapeIdent(el.id);
|
|
5071
5146
|
var parts = [], node = el, depth = 0;
|
|
5072
5147
|
while (node && node.nodeType === 1 && depth < 5) {
|
|
5073
|
-
if (node.id) { parts.unshift('#' + node.id); break; }
|
|
5148
|
+
if (node.id) { parts.unshift('#' + cssEscapeIdent(node.id)); break; }
|
|
5074
5149
|
var p = node.tagName.toLowerCase();
|
|
5075
5150
|
if (node.classList && node.classList.length) {
|
|
5076
5151
|
var clsArr = Array.from(node.classList).filter(function(c) {
|
|
5077
|
-
return c.indexOf('vve-') !== 0;
|
|
5152
|
+
return c.indexOf('vve-') !== 0 && !isGeneratedClassToken(c);
|
|
5078
5153
|
});
|
|
5079
|
-
if (clsArr.length) p += '.' + clsArr.slice(0, 2).join('.');
|
|
5154
|
+
if (clsArr.length) p += '.' + clsArr.slice(0, 2).map(function(c) { return cssEscapeIdent(c); }).join('.');
|
|
5080
5155
|
}
|
|
5081
5156
|
var idx = 1, sib = node.previousElementSibling;
|
|
5082
5157
|
while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
|
|
@@ -5088,17 +5163,32 @@ function buildSelector(el) {
|
|
|
5088
5163
|
return parts.join(' > ');
|
|
5089
5164
|
}
|
|
5090
5165
|
|
|
5166
|
+
function stripGeneratedSelectorClassTokens(sel) {
|
|
5167
|
+
if (!sel || typeof sel !== 'string') return '';
|
|
5168
|
+
var s = sel.replace(/.((?:\\.|[^s>+~:#.])+)/g, function(_m, cls) {
|
|
5169
|
+
var raw = unescapeCssToken(cls);
|
|
5170
|
+
if (isGeneratedClassToken(raw)) return '';
|
|
5171
|
+
return '.' + cssEscapeIdent(raw);
|
|
5172
|
+
});
|
|
5173
|
+
return s
|
|
5174
|
+
.replace(/.{2,}/g, '.')
|
|
5175
|
+
.replace(/s{2,}/g, ' ')
|
|
5176
|
+
.replace(/s*>s*>/g, ' > ')
|
|
5177
|
+
.trim();
|
|
5178
|
+
}
|
|
5179
|
+
|
|
5091
5180
|
/**
|
|
5092
5181
|
* Strip editor-only .vve-* class tokens from a selector string (fixes DB rows saved while an element was selected).
|
|
5093
5182
|
*/
|
|
5094
5183
|
function sanitizeSelectorForMatch(sel) {
|
|
5095
5184
|
if (!sel || typeof sel !== 'string') return '';
|
|
5096
5185
|
var s0 = sel.replace(/.vve-[a-zA-Z0-9_-]+/gi, '');
|
|
5186
|
+
s0 = stripGeneratedSelectorClassTokens(s0);
|
|
5097
5187
|
var parts = s0.split(/s*>s*/).map(function(seg) {
|
|
5098
5188
|
var t = seg.replace(/.+/g, '.').replace(/.$/, '');
|
|
5099
5189
|
return t.trim();
|
|
5100
5190
|
});
|
|
5101
|
-
return parts.filter(Boolean).join(' > ');
|
|
5191
|
+
return escapeSelectorClassTokens(parts.filter(Boolean).join(' > '));
|
|
5102
5192
|
}
|
|
5103
5193
|
|
|
5104
5194
|
/** Drop the rightmost :nth-of-type(n) (hydration / layout often shifts sibling indices). */
|
|
@@ -5142,11 +5232,12 @@ function querySelectorResolved(iframeDoc, selector) {
|
|
|
5142
5232
|
return null;
|
|
5143
5233
|
}
|
|
5144
5234
|
var alt = sanitizeSelectorForMatch(selector);
|
|
5235
|
+
var escaped = escapeSelectorClassTokens(alt || selector);
|
|
5145
5236
|
// Prefer sanitized + nth relax FIRST: raw selectors often still contain .vve-* from
|
|
5146
5237
|
// save-time selection; those only match after clicking (we re-add vve-selected).
|
|
5147
|
-
var el = walkRelax(alt || selector);
|
|
5238
|
+
var el = walkRelax(escaped || alt || selector);
|
|
5148
5239
|
if (el) return el;
|
|
5149
|
-
if (alt !== selector) {
|
|
5240
|
+
if (alt !== selector || escaped !== selector) {
|
|
5150
5241
|
el = walkRelax(selector);
|
|
5151
5242
|
if (el) return el;
|
|
5152
5243
|
}
|
|
@@ -5813,6 +5904,12 @@ window.addEventListener('load', function() {
|
|
|
5813
5904
|
if (!d || d.channel !== 'vvveb-proxy-url' || d.type !== 'editor-url-changed') return;
|
|
5814
5905
|
if (!iframe || !iframe.contentWindow || ev.source !== iframe.contentWindow) return;
|
|
5815
5906
|
var payload = d.payload || {};
|
|
5907
|
+
try {
|
|
5908
|
+
console.info('[V2 iframe-url bridge]', {
|
|
5909
|
+
url: payload.url || '',
|
|
5910
|
+
passwordPresent: !!payload.password,
|
|
5911
|
+
});
|
|
5912
|
+
} catch(_) {}
|
|
5816
5913
|
emitEditorUrlChangedPayload({
|
|
5817
5914
|
url: payload.url || undefined,
|
|
5818
5915
|
password: payload.password || undefined,
|
|
@@ -6102,8 +6199,6 @@ function createVisualEditorMiddleware(options) {
|
|
|
6102
6199
|
extraTrackingMarkersForRequest
|
|
6103
6200
|
);
|
|
6104
6201
|
const strictFreezeParam = (url.searchParams.get("strictObserverFreeze") || "").toLowerCase();
|
|
6105
|
-
const proxyParam = (url.searchParams.get("proxy") || "").toLowerCase();
|
|
6106
|
-
const useScraperProxy = proxyParam === "1" || proxyParam === "true" || proxyParam === "yes";
|
|
6107
6202
|
const strictObserverFreezeForRequest = strictFreezeParam === "1" || strictFreezeParam === "true" || strictFreezeParam === "yes" ? true : strictFreezeParam === "0" || strictFreezeParam === "false" || strictFreezeParam === "no" ? false : strictObserverFreeze;
|
|
6108
6203
|
if (!targetUrl) {
|
|
6109
6204
|
res.statusCode = 400;
|
|
@@ -6113,40 +6208,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
6113
6208
|
const parsed = new URL(targetUrl);
|
|
6114
6209
|
const origin = parsed.origin;
|
|
6115
6210
|
const method = (req.method || "GET").toUpperCase();
|
|
6116
|
-
const scraperProxyClient = useScraperProxy ? await getScraperProxyClient() : null;
|
|
6117
|
-
if (useScraperProxy && !scraperProxyClient) {
|
|
6118
|
-
res.statusCode = 500;
|
|
6119
|
-
res.setHeader("Content-Type", "application/json");
|
|
6120
|
-
res.end(
|
|
6121
|
-
JSON.stringify({
|
|
6122
|
-
error: "ScraperAPI proxy is not configured. Set SCRAPERAPI_PROXY_PASSWORD or SCRAPERAPI_API_KEY."
|
|
6123
|
-
})
|
|
6124
|
-
);
|
|
6125
|
-
return;
|
|
6126
|
-
}
|
|
6127
6211
|
const directFetch = (input, init = {}) => fetch(input, init);
|
|
6128
|
-
const scraperFetch = (input, init = {}) => {
|
|
6129
|
-
if (!SCRAPER_PROXY_PASSWORD) return directFetch(input, init);
|
|
6130
|
-
if (!useScraperProxy || !scraperProxyClient) {
|
|
6131
|
-
const scraperUrl = new URL(SCRAPER_API_ENDPOINT);
|
|
6132
|
-
scraperUrl.searchParams.set("api_key", SCRAPER_PROXY_PASSWORD);
|
|
6133
|
-
scraperUrl.searchParams.set("url", input);
|
|
6134
|
-
return fetch(scraperUrl.toString(), init);
|
|
6135
|
-
}
|
|
6136
|
-
return scraperProxyClient.fetchFn(input, {
|
|
6137
|
-
...init,
|
|
6138
|
-
dispatcher: scraperProxyClient.dispatcher
|
|
6139
|
-
});
|
|
6140
|
-
};
|
|
6141
|
-
const shouldFallbackFromScraper = async (resp) => {
|
|
6142
|
-
try {
|
|
6143
|
-
if (resp.ok) return false;
|
|
6144
|
-
const text = await resp.clone().text();
|
|
6145
|
-
return SCRAPER_BILLING_ERROR_RE.test(String(text || ""));
|
|
6146
|
-
} catch (_) {
|
|
6147
|
-
return false;
|
|
6148
|
-
}
|
|
6149
|
-
};
|
|
6150
6212
|
const workerRawFetch = (input, init = {}) => {
|
|
6151
6213
|
const workerUrl = new URL("/api/conversion-proxy", conversionProxyBaseUrlForRequest);
|
|
6152
6214
|
workerUrl.searchParams.set("url", input);
|
|
@@ -6173,19 +6235,12 @@ function createVisualEditorMiddleware(options) {
|
|
|
6173
6235
|
};
|
|
6174
6236
|
const upstreamFetch = async (input, init = {}) => {
|
|
6175
6237
|
if (conversionProxyBaseUrlForRequest) {
|
|
6238
|
+
const method2 = String(init?.method || "GET").toUpperCase();
|
|
6239
|
+
if (method2 !== "GET" && method2 !== "HEAD") {
|
|
6240
|
+
return directFetch(input, init);
|
|
6241
|
+
}
|
|
6176
6242
|
return workerRawFetch(input, init);
|
|
6177
6243
|
}
|
|
6178
|
-
const primary = await scraperFetch(input, init);
|
|
6179
|
-
if (!await shouldFallbackFromScraper(primary)) {
|
|
6180
|
-
return primary;
|
|
6181
|
-
}
|
|
6182
|
-
try {
|
|
6183
|
-
console.warn("[conversion-proxy] ScraperAPI billing/quota detected; falling back to direct fetch", {
|
|
6184
|
-
url: input,
|
|
6185
|
-
mode: useScraperProxy ? "proxy" : "simple"
|
|
6186
|
-
});
|
|
6187
|
-
} catch (_) {
|
|
6188
|
-
}
|
|
6189
6244
|
return directFetch(input, init);
|
|
6190
6245
|
};
|
|
6191
6246
|
const headers = {
|
|
@@ -6257,16 +6312,8 @@ function createVisualEditorMiddleware(options) {
|
|
|
6257
6312
|
res.end(
|
|
6258
6313
|
JSON.stringify({
|
|
6259
6314
|
error: aborted ? `Upstream request timed out after ${upstreamTimeoutMs / 1e3}s` : fetchErr?.message || "Upstream fetch failed",
|
|
6260
|
-
phase:
|
|
6261
|
-
fetchMode:
|
|
6262
|
-
scraperapi: {
|
|
6263
|
-
host: SCRAPER_PROXY_HOST,
|
|
6264
|
-
port: SCRAPER_PROXY_PORT,
|
|
6265
|
-
username: SCRAPER_PROXY_USERNAME,
|
|
6266
|
-
endpoint: SCRAPER_API_ENDPOINT,
|
|
6267
|
-
hasProxyPassword: Boolean(SCRAPER_PROXY_PASSWORD),
|
|
6268
|
-
requestTlsRejectUnauthorized: SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED
|
|
6269
|
-
},
|
|
6315
|
+
phase: conversionProxyBaseUrlForRequest ? "worker-raw-fetch" : "direct-upstream-fetch",
|
|
6316
|
+
fetchMode: conversionProxyBaseUrlForRequest ? "worker" : "direct",
|
|
6270
6317
|
cause: fetchCause && typeof fetchCause === "object" ? {
|
|
6271
6318
|
name: fetchCause.name,
|
|
6272
6319
|
code: fetchCause.code,
|
|
@@ -6452,8 +6499,51 @@ try{
|
|
|
6452
6499
|
}
|
|
6453
6500
|
}
|
|
6454
6501
|
}catch(_){}
|
|
6455
|
-
function getEditorUrlPayload(){
|
|
6456
|
-
|
|
6502
|
+
function getEditorUrlPayload(){
|
|
6503
|
+
try{
|
|
6504
|
+
var u=new URL(window.location.href);
|
|
6505
|
+
var nested=u.searchParams.get("url");
|
|
6506
|
+
if(nested){
|
|
6507
|
+
return {url:nested,password:u.searchParams.get("password")||undefined};
|
|
6508
|
+
}
|
|
6509
|
+
var p=u.pathname||"";
|
|
6510
|
+
var isProxyPath=p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0||p.indexOf("api/conversion-proxy")!==-1;
|
|
6511
|
+
if(isProxyPath){
|
|
6512
|
+
var recoveredBase=new URL(TARGET_PAGE_URL,window.location.href);
|
|
6513
|
+
var qp=new URLSearchParams(u.search||"");
|
|
6514
|
+
qp.delete("url");
|
|
6515
|
+
qp.delete("password");
|
|
6516
|
+
qp.delete("conversionProxyBaseUrl");
|
|
6517
|
+
qp.delete("trackingMarkers");
|
|
6518
|
+
qp.delete("strictObserverFreeze");
|
|
6519
|
+
qp.delete("proxy");
|
|
6520
|
+
qp.delete("raw");
|
|
6521
|
+
recoveredBase.search="";
|
|
6522
|
+
qp.forEach(function(v,k){recoveredBase.searchParams.set(k,v);});
|
|
6523
|
+
recoveredBase.hash=u.hash||"";
|
|
6524
|
+
return {url:recoveredBase.toString(),password:u.searchParams.get("password")||undefined};
|
|
6525
|
+
}
|
|
6526
|
+
return {url:u.toString(),password:u.searchParams.get("password")||undefined};
|
|
6527
|
+
}catch(_){
|
|
6528
|
+
return null;
|
|
6529
|
+
}
|
|
6530
|
+
}
|
|
6531
|
+
function notifyEditorUrlChanged(){
|
|
6532
|
+
try{
|
|
6533
|
+
var payload=getEditorUrlPayload();
|
|
6534
|
+
if(!payload) return;
|
|
6535
|
+
try{
|
|
6536
|
+
console.info("[conversion-proxy] iframe url rendered",{
|
|
6537
|
+
current:window.location.href,
|
|
6538
|
+
target:payload.url||"",
|
|
6539
|
+
passwordPresent:!!payload.password
|
|
6540
|
+
});
|
|
6541
|
+
}catch(_){}
|
|
6542
|
+
if(window.parent){
|
|
6543
|
+
window.parent.postMessage({channel:PARENT_URL_CHANNEL,type:"editor-url-changed",payload:payload},"*");
|
|
6544
|
+
}
|
|
6545
|
+
}catch(_){}
|
|
6546
|
+
}
|
|
6457
6547
|
try{notifyEditorUrlChanged();}catch(_){}
|
|
6458
6548
|
try{if(window.history&&typeof window.history.pushState==="function"){var nativePushState=window.history.pushState;window.history.pushState=function(){var ret=nativePushState.apply(window.history,arguments);setTimeout(notifyEditorUrlChanged,0);return ret;};}}catch(_){}
|
|
6459
6549
|
try{if(window.history&&typeof window.history.replaceState==="function"){var nativeReplaceState=window.history.replaceState;window.history.replaceState=function(){var ret=nativeReplaceState.apply(window.history,arguments);setTimeout(notifyEditorUrlChanged,0);return ret;};}}catch(_){}
|
|
@@ -6461,7 +6551,29 @@ try{window.addEventListener("popstate",notifyEditorUrlChanged,true);}catch(_){}
|
|
|
6461
6551
|
try{window.addEventListener("hashchange",notifyEditorUrlChanged,true);}catch(_){}
|
|
6462
6552
|
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
6463
6553
|
function toAbsolute(raw){if(isSkippable(raw))return raw;try{var base=raw.startsWith("/")||raw.startsWith("//")?TARGET_ORIGIN:TARGET_PAGE_URL;return new URL(raw,base).toString();}catch(_){return raw;}}
|
|
6464
|
-
function toProxy(raw){
|
|
6554
|
+
function toProxy(raw){
|
|
6555
|
+
if(isSkippable(raw))return null;
|
|
6556
|
+
var abs=toAbsolute(raw);
|
|
6557
|
+
if(!abs||typeof abs!=="string")return null;
|
|
6558
|
+
try{
|
|
6559
|
+
var parsed=new URL(abs);
|
|
6560
|
+
// If input is already a proxy URL, unwrap to its target url first
|
|
6561
|
+
// to avoid nested /api/conversion-proxy?url=/api/conversion-proxy?... chains.
|
|
6562
|
+
var p=(parsed.pathname||"");
|
|
6563
|
+
var isProxyPath=p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0||p.indexOf("api/conversion-proxy")!==-1;
|
|
6564
|
+
if(isProxyPath){
|
|
6565
|
+
var nested=parsed.searchParams.get("url")||"";
|
|
6566
|
+
if(nested){
|
|
6567
|
+
try{parsed=new URL(nested);}catch(_){}
|
|
6568
|
+
}
|
|
6569
|
+
}
|
|
6570
|
+
if(parsed.origin!==TARGET_ORIGIN)return null;
|
|
6571
|
+
var root="/api/conversion-proxy";
|
|
6572
|
+
return root+"?password="+encodeURIComponent(PROXY_PASSWORD||"")+"&url="+encodeURIComponent(parsed.toString());
|
|
6573
|
+
}catch(_){
|
|
6574
|
+
return null;
|
|
6575
|
+
}
|
|
6576
|
+
}
|
|
6465
6577
|
var nativeAssign=window.location.assign?window.location.assign.bind(window.location):null;
|
|
6466
6578
|
var nativeReplace=window.location.replace?window.location.replace.bind(window.location):null;
|
|
6467
6579
|
function safeNavigate(raw,mode){var abs=toAbsolute(raw);var prox=toProxy(raw);if(!prox){try{console.warn("[conversion-proxy] redirect blocked",{mode:mode,requested:raw,resolved:abs,origin:TARGET_ORIGIN});}catch(_){}return false;}try{console.info("[conversion-proxy] redirect intercepted",{mode:mode,requested:raw,resolved:abs,proxied:prox});if(mode==="replace"&&nativeReplace){nativeReplace(prox);return true;}if(nativeAssign){nativeAssign(prox);return true;}window.location.href=prox;return true;}catch(err){try{console.warn("[conversion-proxy] redirect interception failed",{mode:mode,requested:raw,resolved:abs,proxied:prox,error:err&&err.message?err.message:String(err)});}catch(_){}return false;}}
|
|
@@ -6511,12 +6623,49 @@ var PROXY_BASE_URL=_proxyCtx?_proxyCtx.searchParams.get("conversionProxyBaseUrl"
|
|
|
6511
6623
|
var PROXY_TRACKING_MARKERS=_proxyCtx?_proxyCtx.searchParams.get("trackingMarkers")||"":"";
|
|
6512
6624
|
var PROXY_STRICT_FREEZE=_proxyCtx?_proxyCtx.searchParams.get("strictObserverFreeze")||"":"";
|
|
6513
6625
|
var PROXY_UPSTREAM_MODE=_proxyCtx?_proxyCtx.searchParams.get("proxy")||"":"";
|
|
6626
|
+
var EDITOR_ORIGIN=(function(){try{return String(window.location.origin||"");}catch(_){return "";}})();
|
|
6627
|
+
var EDITOR_HOST_KEY=(function(){try{var u=new URL(EDITOR_ORIGIN);return (u.hostname||"").toLowerCase()+":"+(u.port||"");}catch(_){return "";}})();
|
|
6514
6628
|
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
6629
|
+
function isEditorHostUrl(u){
|
|
6630
|
+
try{
|
|
6631
|
+
if(!u) return false;
|
|
6632
|
+
var hostKey=(u.hostname||"").toLowerCase()+":"+(u.port||"");
|
|
6633
|
+
if(EDITOR_HOST_KEY&&hostKey===EDITOR_HOST_KEY) return true;
|
|
6634
|
+
// localhost aliases for same dev server port
|
|
6635
|
+
var host=(u.hostname||"").toLowerCase();
|
|
6636
|
+
var editorHost=EDITOR_HOST_KEY.split(":")[0]||"";
|
|
6637
|
+
var samePort=(u.port||"")===(EDITOR_HOST_KEY.split(":")[1]||"");
|
|
6638
|
+
var localAlias=(host==="localhost"||host==="127.0.0.1"||host==="[::1]");
|
|
6639
|
+
var editorLocalAlias=(editorHost==="localhost"||editorHost==="127.0.0.1"||editorHost==="[::1]");
|
|
6640
|
+
return samePort&&localAlias&&editorLocalAlias;
|
|
6641
|
+
}catch(_){
|
|
6642
|
+
return false;
|
|
6643
|
+
}
|
|
6644
|
+
}
|
|
6515
6645
|
function toProxyNetworkUrl(raw){
|
|
6516
6646
|
if(isSkippable(raw))return raw;
|
|
6517
6647
|
try{
|
|
6518
6648
|
var base=raw.startsWith("/")?TARGET_ORIGIN:TARGET_PAGE_URL;
|
|
6519
6649
|
var abs=new URL(raw,base);
|
|
6650
|
+
// Unwrap already-proxied URLs first to avoid nested proxy urls.
|
|
6651
|
+
var p0=abs.pathname||"";
|
|
6652
|
+
var isProxyPath0=p0==="/api/conversion-proxy"||p0.indexOf("/api/conversion-proxy/")===0||p0.indexOf("api/conversion-proxy")!==-1;
|
|
6653
|
+
if(isProxyPath0){
|
|
6654
|
+
var nested0=abs.searchParams.get("url")||"";
|
|
6655
|
+
if(nested0){
|
|
6656
|
+
try{abs=new URL(nested0);}catch(_){}
|
|
6657
|
+
}
|
|
6658
|
+
}
|
|
6659
|
+
// Some embedded scripts build absolute requests against editor origin
|
|
6660
|
+
// (e.g. https://localhost:4001/api/unstable/graphql.json). Remap those
|
|
6661
|
+
// paths to target origin first, then proxy as usual.
|
|
6662
|
+
if(EDITOR_ORIGIN&&isEditorHostUrl(abs)){
|
|
6663
|
+
var p=abs.pathname||"";
|
|
6664
|
+
var isRootProxyPath=p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0;
|
|
6665
|
+
if(!isRootProxyPath){
|
|
6666
|
+
abs=new URL((abs.pathname||"/")+(abs.search||"")+(abs.hash||""),TARGET_ORIGIN);
|
|
6667
|
+
}
|
|
6668
|
+
}
|
|
6520
6669
|
if(abs.origin!==TARGET_ORIGIN)return raw;
|
|
6521
6670
|
var prox=new URL(PROXY_ROOT,window.location.origin);
|
|
6522
6671
|
prox.searchParams.set("password",PROXY_PASSWORD||"");
|
package/dist/vite.js
CHANGED
|
@@ -3,20 +3,6 @@ import path from 'path';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
|
|
5
5
|
// src/visualEditorProxyPlugin.ts
|
|
6
|
-
var SCRAPER_PROXY_HOST = process.env.SCRAPERAPI_PROXY_HOST || "proxy-server.scraperapi.com";
|
|
7
|
-
var SCRAPER_PROXY_PORT = Number(process.env.SCRAPERAPI_PROXY_PORT || "8001");
|
|
8
|
-
var SCRAPER_PROXY_USERNAME_BASE = process.env.SCRAPERAPI_PROXY_USERNAME_BASE || "scraperapi";
|
|
9
|
-
var SCRAPER_PROXY_USERNAME_PARAMS = process.env.SCRAPERAPI_PROXY_USERNAME_PARAMS || "render=true.wait_for_selector=body.follow_redirect=false.keep_headers=true";
|
|
10
|
-
var SCRAPER_PROXY_USERNAME = process.env.SCRAPERAPI_PROXY_USERNAME || [
|
|
11
|
-
SCRAPER_PROXY_USERNAME_BASE,
|
|
12
|
-
SCRAPER_PROXY_USERNAME_PARAMS
|
|
13
|
-
].filter(Boolean).join(".");
|
|
14
|
-
var SCRAPER_PROXY_PASSWORD = process.env.SCRAPERAPI_PROXY_PASSWORD || process.env.SCRAPERAPI_API_KEY;
|
|
15
|
-
var SCRAPER_API_ENDPOINT = process.env.SCRAPERAPI_ENDPOINT || "https://api.scraperapi.com/";
|
|
16
|
-
var SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED_RAW = process.env.SCRAPERAPI_REQUEST_TLS_REJECT_UNAUTHORIZED || "false";
|
|
17
|
-
var SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED = !["0", "false", "no"].includes(
|
|
18
|
-
SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED_RAW.toLowerCase()
|
|
19
|
-
);
|
|
20
6
|
var DEFAULT_TRACKING_MARKERS = [
|
|
21
7
|
"snowplow",
|
|
22
8
|
"taboola",
|
|
@@ -114,31 +100,9 @@ function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
|
114
100
|
}
|
|
115
101
|
return out;
|
|
116
102
|
}
|
|
117
|
-
var
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (scraperProxyClientPromise) return scraperProxyClientPromise;
|
|
121
|
-
scraperProxyClientPromise = (async () => {
|
|
122
|
-
if (!SCRAPER_PROXY_PASSWORD) return null;
|
|
123
|
-
try {
|
|
124
|
-
const undici = await import('undici');
|
|
125
|
-
const proxyUrl = "http://" + encodeURIComponent(SCRAPER_PROXY_USERNAME) + ":" + encodeURIComponent(SCRAPER_PROXY_PASSWORD) + "@" + SCRAPER_PROXY_HOST + ":" + String(SCRAPER_PROXY_PORT);
|
|
126
|
-
return {
|
|
127
|
-
dispatcher: new undici.ProxyAgent({
|
|
128
|
-
uri: proxyUrl,
|
|
129
|
-
requestTls: {
|
|
130
|
-
rejectUnauthorized: SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED
|
|
131
|
-
}
|
|
132
|
-
}),
|
|
133
|
-
fetchFn: undici.fetch
|
|
134
|
-
};
|
|
135
|
-
} catch (_) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
})();
|
|
139
|
-
return scraperProxyClientPromise;
|
|
140
|
-
}
|
|
141
|
-
var iframeAlwaysShowCss = `<style id="__ce_force_show">#CybotCookiebotDialog,#CybotCookiebotDialogBodyUnderlay,#onetrust-consent-sdk,#onetrust-banner-sdk,.cc-window,.cc-banner,.cc-overlay,#cookie-notice,#cookie-banner,#cookie-consent,.cookie-notice,.cookie-banner,.cookie-consent,.cookie-popup,.cookie-bar,.cookie-message,.cookie-alert,.gdpr-banner,.gdpr-consent,.gdpr-popup,.gdpr-overlay,#gdpr-consent,#gdpr-banner,.consent-banner,.consent-popup,.consent-overlay,#consent-banner,#consent-popup,[class*="cookie-consent"],[class*="cookie-banner"],[class*="cookie-notice"],[class*="CookieConsent"],[class*="CookieBanner"],[id*="cookie-consent"],[id*="cookie-banner"],[id*="cookie-notice"],[aria-label*="cookie" i],[aria-label*="consent" i],.klaro,.klaro .cookie-modal,#usercentrics-root,.trustarc-banner,#truste-consent-track,#hs-eu-cookie-confirmation,.osano-cm-window,.osano-cm-dialog,.evidon-banner,#_evidon_banner,.js-cookie-consent,.cookie-disclaimer,.shopify-section-cookies,#shopify-section-cookies,#shopify-pc__banner,#shopify-pc__modal,.privacy-banner,.privacy-popup,[data-testid="cookie-banner"],[data-testid="consent-banner"],.amgdprcookie-bar-container,[data-amcookie-js="bar"],.amgdprjs-bar-template,.amgdprcookie-modal-container,.amgdprcookie-modal-overlay,#cmplz-cookiebanner-container,.cmplz-cookiebanner,#iubenda-cs-banner,.iubenda-cs-container,#qc-cmp2-container,.qc-cmp2-consent-info,#didomi-host,.didomi-popup-container,.didomi-notice,#termly-code-snippet-support,[class*="termly"],[class*="gdprcookie"],[class*="amgdpr"],[id*="gdpr-cookie"],[class*="cookie-modal"],[id*="cookie-modal"],[class*="cookieConsent"],[id*="cookieConsent"]{display:revert!important;visibility:visible!important;opacity:1!important;pointer-events:auto!important;height:auto!important;max-height:none!important;overflow:visible!important;}</style>`;
|
|
103
|
+
var iframeAlwaysShowCss = `<style id="__ce_force_show">
|
|
104
|
+
|
|
105
|
+
</style>`;
|
|
142
106
|
var iframeAlwaysShowCssGuardScript = `<script id="__ce_force_show_guard">(function(){try{
|
|
143
107
|
function ensureForceShowStyleLast(){
|
|
144
108
|
var style=document.getElementById("__ce_force_show");
|
|
@@ -497,7 +461,10 @@ box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.20), 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 1p
|
|
|
497
461
|
.dt-ico{width:16px;flex-shrink:0;text-align:center;color:var(--text-3);font-size:12px}
|
|
498
462
|
.dt-lbl{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,monospace;font-size:10px}
|
|
499
463
|
.dt-muted{padding:16px 12px;text-align:center;color:var(--text-3);font-size:11px;line-height:1.4}
|
|
500
|
-
|
|
464
|
+
#section-components-panel{
|
|
465
|
+
max-height: 50%;
|
|
466
|
+
overflow-y: auto;
|
|
467
|
+
}
|
|
501
468
|
/* \u2500\u2500 Right panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
502
469
|
#right-panel{
|
|
503
470
|
width:252px;background:var(--bg);border-left:1px solid var(--border);
|
|
@@ -626,6 +593,17 @@ box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.20), 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 1p
|
|
|
626
593
|
flex:1;padding:8px 2px;text-align:center;font-size:10px;color:var(--text-3);
|
|
627
594
|
cursor:pointer;border-bottom:2px solid transparent;transition:all .15s;font-weight:600;line-height:1.15
|
|
628
595
|
}
|
|
596
|
+
.lp-tab.close-section-components-panel{
|
|
597
|
+
padding: 4px 10px;
|
|
598
|
+
background: #000;
|
|
599
|
+
display: flex;
|
|
600
|
+
max-width: fit-content;
|
|
601
|
+
align-items: center;
|
|
602
|
+
justify-content: center;
|
|
603
|
+
border-radius: 2px;
|
|
604
|
+
margin: 2px;
|
|
605
|
+
color: #fff;
|
|
606
|
+
}
|
|
629
607
|
.lp-tab:hover{color:var(--text-2)}
|
|
630
608
|
.lp-tab.active{color:var(--accent-txt);border-bottom-color:var(--accent)}
|
|
631
609
|
.future-hidden{display:none!important}
|
|
@@ -1134,6 +1112,7 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
1134
1112
|
<div class="section-components-tabs">
|
|
1135
1113
|
<div class="lp-tab" onclick="switchSectionComponentsTab('components')">Components</div>
|
|
1136
1114
|
<div class="lp-tab" onclick="switchSectionComponentsTab('sections')">Sections</div>
|
|
1115
|
+
<div class="lp-tab close-section-components-panel" onclick="toggleSectionComponentsPanel()"> Close</div>
|
|
1137
1116
|
</div>
|
|
1138
1117
|
<div class="lp-body">
|
|
1139
1118
|
<div id="tab-components" class="tab-pane"></div>
|
|
@@ -3258,6 +3237,35 @@ function parseEditorUrlPayload(rawUrl) {
|
|
|
3258
3237
|
password: nestedPassword || undefined,
|
|
3259
3238
|
};
|
|
3260
3239
|
}
|
|
3240
|
+
var path = parsed.pathname || '';
|
|
3241
|
+
var isProxyPath =
|
|
3242
|
+
path === '/api/conversion-proxy' ||
|
|
3243
|
+
path.indexOf('/api/conversion-proxy/') === 0 ||
|
|
3244
|
+
path.indexOf('api/conversion-proxy') !== -1;
|
|
3245
|
+
if (isProxyPath) {
|
|
3246
|
+
var fallbackUrl = (experimentData && experimentData.pageUrl) ? String(experimentData.pageUrl) : '';
|
|
3247
|
+
if (fallbackUrl) {
|
|
3248
|
+
var recovered = new URL(fallbackUrl, window.location.href);
|
|
3249
|
+
var qp = new URLSearchParams(parsed.search || '');
|
|
3250
|
+
qp.delete('url');
|
|
3251
|
+
qp.delete('password');
|
|
3252
|
+
qp.delete('conversionProxyBaseUrl');
|
|
3253
|
+
qp.delete('trackingMarkers');
|
|
3254
|
+
qp.delete('strictObserverFreeze');
|
|
3255
|
+
qp.delete('proxy');
|
|
3256
|
+
qp.delete('raw');
|
|
3257
|
+
recovered.search = '';
|
|
3258
|
+
qp.forEach(function(v, k) { recovered.searchParams.set(k, v); });
|
|
3259
|
+
recovered.hash = parsed.hash || '';
|
|
3260
|
+
return {
|
|
3261
|
+
url: recovered.toString(),
|
|
3262
|
+
password:
|
|
3263
|
+
(experimentData && experimentData.editorPassword)
|
|
3264
|
+
? String(experimentData.editorPassword)
|
|
3265
|
+
: undefined,
|
|
3266
|
+
};
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3261
3269
|
return {
|
|
3262
3270
|
url: parsed.toString(),
|
|
3263
3271
|
password:
|
|
@@ -3276,6 +3284,12 @@ function emitEditorUrlChangedPayload(payload) {
|
|
|
3276
3284
|
var key = String(payload.url || '') + '|' + String(payload.password || '');
|
|
3277
3285
|
if (key === lastEditorUrlPayloadKey) return;
|
|
3278
3286
|
lastEditorUrlPayloadKey = key;
|
|
3287
|
+
try {
|
|
3288
|
+
console.info('[V2 iframe-url]', {
|
|
3289
|
+
url: payload.url || '',
|
|
3290
|
+
passwordPresent: !!payload.password,
|
|
3291
|
+
});
|
|
3292
|
+
} catch(_) {}
|
|
3279
3293
|
send('editor-url-changed', payload);
|
|
3280
3294
|
}
|
|
3281
3295
|
function emitEditorUrlChanged(rawUrl) {
|
|
@@ -5048,6 +5062,67 @@ function stripDataVveInstanceSubtree(root) {
|
|
|
5048
5062
|
}
|
|
5049
5063
|
}
|
|
5050
5064
|
|
|
5065
|
+
function cssEscapeIdent(raw) {
|
|
5066
|
+
var s = raw == null ? '' : String(raw);
|
|
5067
|
+
if (!s) return '';
|
|
5068
|
+
try {
|
|
5069
|
+
if (typeof CSS !== 'undefined' && CSS && typeof CSS.escape === 'function') {
|
|
5070
|
+
return CSS.escape(s);
|
|
5071
|
+
}
|
|
5072
|
+
} catch(_) {}
|
|
5073
|
+
// Fallback escape for identifiers when CSS.escape is unavailable.
|
|
5074
|
+
return s.replace(/[^a-zA-Z0-9_-]/g, function(ch) { return '\\\\' + ch; });
|
|
5075
|
+
}
|
|
5076
|
+
|
|
5077
|
+
function unescapeCssToken(token) {
|
|
5078
|
+
if (!token) return '';
|
|
5079
|
+
var s = String(token);
|
|
5080
|
+
var out = '';
|
|
5081
|
+
for (var i = 0; i < s.length; i++) {
|
|
5082
|
+
var ch = s.charAt(i);
|
|
5083
|
+
if (ch === '\\\\' && i + 1 < s.length) {
|
|
5084
|
+
out += s.charAt(i + 1);
|
|
5085
|
+
i += 1;
|
|
5086
|
+
continue;
|
|
5087
|
+
}
|
|
5088
|
+
out += ch;
|
|
5089
|
+
}
|
|
5090
|
+
return out;
|
|
5091
|
+
}
|
|
5092
|
+
|
|
5093
|
+
function isGeneratedClassToken(token) {
|
|
5094
|
+
var t = token == null ? '' : String(token).trim();
|
|
5095
|
+
if (!t) return true;
|
|
5096
|
+
if (t.indexOf('vve-') === 0) return true;
|
|
5097
|
+
// Tailwind arbitrary values / variant-heavy utilities are often unstable in selectors.
|
|
5098
|
+
if (
|
|
5099
|
+
t.indexOf('[') !== -1 ||
|
|
5100
|
+
t.indexOf(']') !== -1 ||
|
|
5101
|
+
t.indexOf('(') !== -1 ||
|
|
5102
|
+
t.indexOf(')') !== -1 ||
|
|
5103
|
+
t.indexOf('{') !== -1 ||
|
|
5104
|
+
t.indexOf('}') !== -1 ||
|
|
5105
|
+
t.indexOf(':') !== -1
|
|
5106
|
+
) return true;
|
|
5107
|
+
// CSS-in-JS / runtime hash prefixes.
|
|
5108
|
+
if (/^(css|jsx|sc|emotion|styled|chakra|mantine|mui|ant)-/i.test(t)) return true;
|
|
5109
|
+
// Classnames with long hashy suffixes (framework/runtime generated).
|
|
5110
|
+
if (/[a-f0-9]{8,}/i.test(t)) return true;
|
|
5111
|
+
if (/^[a-zA-Z_-]+[0-9]{4,}[a-zA-Z0-9_-]*$/.test(t)) return true;
|
|
5112
|
+
if (/^[a-zA-Z0-9_-]{36,}$/.test(t)) return true;
|
|
5113
|
+
return false;
|
|
5114
|
+
}
|
|
5115
|
+
|
|
5116
|
+
function escapeSelectorClassTokens(sel) {
|
|
5117
|
+
if (!sel || typeof sel !== 'string') return '';
|
|
5118
|
+
return sel.replace(/.((?:\\.|[^s>+~:#.])+)/g, function(_m, cls) {
|
|
5119
|
+
if (!cls) return _m;
|
|
5120
|
+
// Already escaped token; keep it as-is.
|
|
5121
|
+
if (cls.indexOf('\\\\') >= 0) return '.' + cls;
|
|
5122
|
+
return '.' + cssEscapeIdent(cls);
|
|
5123
|
+
});
|
|
5124
|
+
}
|
|
5125
|
+
|
|
5051
5126
|
function buildSelector(el) {
|
|
5052
5127
|
if (!el) return '';
|
|
5053
5128
|
var doc = el.ownerDocument || document;
|
|
@@ -5059,16 +5134,16 @@ function buildSelector(el) {
|
|
|
5059
5134
|
if (doc.querySelectorAll(attrSel).length === 1) return attrSel;
|
|
5060
5135
|
} catch(_) {}
|
|
5061
5136
|
}
|
|
5062
|
-
if (el.id) return '#' + el.id;
|
|
5137
|
+
if (el.id) return '#' + cssEscapeIdent(el.id);
|
|
5063
5138
|
var parts = [], node = el, depth = 0;
|
|
5064
5139
|
while (node && node.nodeType === 1 && depth < 5) {
|
|
5065
|
-
if (node.id) { parts.unshift('#' + node.id); break; }
|
|
5140
|
+
if (node.id) { parts.unshift('#' + cssEscapeIdent(node.id)); break; }
|
|
5066
5141
|
var p = node.tagName.toLowerCase();
|
|
5067
5142
|
if (node.classList && node.classList.length) {
|
|
5068
5143
|
var clsArr = Array.from(node.classList).filter(function(c) {
|
|
5069
|
-
return c.indexOf('vve-') !== 0;
|
|
5144
|
+
return c.indexOf('vve-') !== 0 && !isGeneratedClassToken(c);
|
|
5070
5145
|
});
|
|
5071
|
-
if (clsArr.length) p += '.' + clsArr.slice(0, 2).join('.');
|
|
5146
|
+
if (clsArr.length) p += '.' + clsArr.slice(0, 2).map(function(c) { return cssEscapeIdent(c); }).join('.');
|
|
5072
5147
|
}
|
|
5073
5148
|
var idx = 1, sib = node.previousElementSibling;
|
|
5074
5149
|
while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
|
|
@@ -5080,17 +5155,32 @@ function buildSelector(el) {
|
|
|
5080
5155
|
return parts.join(' > ');
|
|
5081
5156
|
}
|
|
5082
5157
|
|
|
5158
|
+
function stripGeneratedSelectorClassTokens(sel) {
|
|
5159
|
+
if (!sel || typeof sel !== 'string') return '';
|
|
5160
|
+
var s = sel.replace(/.((?:\\.|[^s>+~:#.])+)/g, function(_m, cls) {
|
|
5161
|
+
var raw = unescapeCssToken(cls);
|
|
5162
|
+
if (isGeneratedClassToken(raw)) return '';
|
|
5163
|
+
return '.' + cssEscapeIdent(raw);
|
|
5164
|
+
});
|
|
5165
|
+
return s
|
|
5166
|
+
.replace(/.{2,}/g, '.')
|
|
5167
|
+
.replace(/s{2,}/g, ' ')
|
|
5168
|
+
.replace(/s*>s*>/g, ' > ')
|
|
5169
|
+
.trim();
|
|
5170
|
+
}
|
|
5171
|
+
|
|
5083
5172
|
/**
|
|
5084
5173
|
* Strip editor-only .vve-* class tokens from a selector string (fixes DB rows saved while an element was selected).
|
|
5085
5174
|
*/
|
|
5086
5175
|
function sanitizeSelectorForMatch(sel) {
|
|
5087
5176
|
if (!sel || typeof sel !== 'string') return '';
|
|
5088
5177
|
var s0 = sel.replace(/.vve-[a-zA-Z0-9_-]+/gi, '');
|
|
5178
|
+
s0 = stripGeneratedSelectorClassTokens(s0);
|
|
5089
5179
|
var parts = s0.split(/s*>s*/).map(function(seg) {
|
|
5090
5180
|
var t = seg.replace(/.+/g, '.').replace(/.$/, '');
|
|
5091
5181
|
return t.trim();
|
|
5092
5182
|
});
|
|
5093
|
-
return parts.filter(Boolean).join(' > ');
|
|
5183
|
+
return escapeSelectorClassTokens(parts.filter(Boolean).join(' > '));
|
|
5094
5184
|
}
|
|
5095
5185
|
|
|
5096
5186
|
/** Drop the rightmost :nth-of-type(n) (hydration / layout often shifts sibling indices). */
|
|
@@ -5134,11 +5224,12 @@ function querySelectorResolved(iframeDoc, selector) {
|
|
|
5134
5224
|
return null;
|
|
5135
5225
|
}
|
|
5136
5226
|
var alt = sanitizeSelectorForMatch(selector);
|
|
5227
|
+
var escaped = escapeSelectorClassTokens(alt || selector);
|
|
5137
5228
|
// Prefer sanitized + nth relax FIRST: raw selectors often still contain .vve-* from
|
|
5138
5229
|
// save-time selection; those only match after clicking (we re-add vve-selected).
|
|
5139
|
-
var el = walkRelax(alt || selector);
|
|
5230
|
+
var el = walkRelax(escaped || alt || selector);
|
|
5140
5231
|
if (el) return el;
|
|
5141
|
-
if (alt !== selector) {
|
|
5232
|
+
if (alt !== selector || escaped !== selector) {
|
|
5142
5233
|
el = walkRelax(selector);
|
|
5143
5234
|
if (el) return el;
|
|
5144
5235
|
}
|
|
@@ -5805,6 +5896,12 @@ window.addEventListener('load', function() {
|
|
|
5805
5896
|
if (!d || d.channel !== 'vvveb-proxy-url' || d.type !== 'editor-url-changed') return;
|
|
5806
5897
|
if (!iframe || !iframe.contentWindow || ev.source !== iframe.contentWindow) return;
|
|
5807
5898
|
var payload = d.payload || {};
|
|
5899
|
+
try {
|
|
5900
|
+
console.info('[V2 iframe-url bridge]', {
|
|
5901
|
+
url: payload.url || '',
|
|
5902
|
+
passwordPresent: !!payload.password,
|
|
5903
|
+
});
|
|
5904
|
+
} catch(_) {}
|
|
5808
5905
|
emitEditorUrlChangedPayload({
|
|
5809
5906
|
url: payload.url || undefined,
|
|
5810
5907
|
password: payload.password || undefined,
|
|
@@ -6094,8 +6191,6 @@ function createVisualEditorMiddleware(options) {
|
|
|
6094
6191
|
extraTrackingMarkersForRequest
|
|
6095
6192
|
);
|
|
6096
6193
|
const strictFreezeParam = (url.searchParams.get("strictObserverFreeze") || "").toLowerCase();
|
|
6097
|
-
const proxyParam = (url.searchParams.get("proxy") || "").toLowerCase();
|
|
6098
|
-
const useScraperProxy = proxyParam === "1" || proxyParam === "true" || proxyParam === "yes";
|
|
6099
6194
|
const strictObserverFreezeForRequest = strictFreezeParam === "1" || strictFreezeParam === "true" || strictFreezeParam === "yes" ? true : strictFreezeParam === "0" || strictFreezeParam === "false" || strictFreezeParam === "no" ? false : strictObserverFreeze;
|
|
6100
6195
|
if (!targetUrl) {
|
|
6101
6196
|
res.statusCode = 400;
|
|
@@ -6105,40 +6200,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
6105
6200
|
const parsed = new URL(targetUrl);
|
|
6106
6201
|
const origin = parsed.origin;
|
|
6107
6202
|
const method = (req.method || "GET").toUpperCase();
|
|
6108
|
-
const scraperProxyClient = useScraperProxy ? await getScraperProxyClient() : null;
|
|
6109
|
-
if (useScraperProxy && !scraperProxyClient) {
|
|
6110
|
-
res.statusCode = 500;
|
|
6111
|
-
res.setHeader("Content-Type", "application/json");
|
|
6112
|
-
res.end(
|
|
6113
|
-
JSON.stringify({
|
|
6114
|
-
error: "ScraperAPI proxy is not configured. Set SCRAPERAPI_PROXY_PASSWORD or SCRAPERAPI_API_KEY."
|
|
6115
|
-
})
|
|
6116
|
-
);
|
|
6117
|
-
return;
|
|
6118
|
-
}
|
|
6119
6203
|
const directFetch = (input, init = {}) => fetch(input, init);
|
|
6120
|
-
const scraperFetch = (input, init = {}) => {
|
|
6121
|
-
if (!SCRAPER_PROXY_PASSWORD) return directFetch(input, init);
|
|
6122
|
-
if (!useScraperProxy || !scraperProxyClient) {
|
|
6123
|
-
const scraperUrl = new URL(SCRAPER_API_ENDPOINT);
|
|
6124
|
-
scraperUrl.searchParams.set("api_key", SCRAPER_PROXY_PASSWORD);
|
|
6125
|
-
scraperUrl.searchParams.set("url", input);
|
|
6126
|
-
return fetch(scraperUrl.toString(), init);
|
|
6127
|
-
}
|
|
6128
|
-
return scraperProxyClient.fetchFn(input, {
|
|
6129
|
-
...init,
|
|
6130
|
-
dispatcher: scraperProxyClient.dispatcher
|
|
6131
|
-
});
|
|
6132
|
-
};
|
|
6133
|
-
const shouldFallbackFromScraper = async (resp) => {
|
|
6134
|
-
try {
|
|
6135
|
-
if (resp.ok) return false;
|
|
6136
|
-
const text = await resp.clone().text();
|
|
6137
|
-
return SCRAPER_BILLING_ERROR_RE.test(String(text || ""));
|
|
6138
|
-
} catch (_) {
|
|
6139
|
-
return false;
|
|
6140
|
-
}
|
|
6141
|
-
};
|
|
6142
6204
|
const workerRawFetch = (input, init = {}) => {
|
|
6143
6205
|
const workerUrl = new URL("/api/conversion-proxy", conversionProxyBaseUrlForRequest);
|
|
6144
6206
|
workerUrl.searchParams.set("url", input);
|
|
@@ -6165,19 +6227,12 @@ function createVisualEditorMiddleware(options) {
|
|
|
6165
6227
|
};
|
|
6166
6228
|
const upstreamFetch = async (input, init = {}) => {
|
|
6167
6229
|
if (conversionProxyBaseUrlForRequest) {
|
|
6230
|
+
const method2 = String(init?.method || "GET").toUpperCase();
|
|
6231
|
+
if (method2 !== "GET" && method2 !== "HEAD") {
|
|
6232
|
+
return directFetch(input, init);
|
|
6233
|
+
}
|
|
6168
6234
|
return workerRawFetch(input, init);
|
|
6169
6235
|
}
|
|
6170
|
-
const primary = await scraperFetch(input, init);
|
|
6171
|
-
if (!await shouldFallbackFromScraper(primary)) {
|
|
6172
|
-
return primary;
|
|
6173
|
-
}
|
|
6174
|
-
try {
|
|
6175
|
-
console.warn("[conversion-proxy] ScraperAPI billing/quota detected; falling back to direct fetch", {
|
|
6176
|
-
url: input,
|
|
6177
|
-
mode: useScraperProxy ? "proxy" : "simple"
|
|
6178
|
-
});
|
|
6179
|
-
} catch (_) {
|
|
6180
|
-
}
|
|
6181
6236
|
return directFetch(input, init);
|
|
6182
6237
|
};
|
|
6183
6238
|
const headers = {
|
|
@@ -6249,16 +6304,8 @@ function createVisualEditorMiddleware(options) {
|
|
|
6249
6304
|
res.end(
|
|
6250
6305
|
JSON.stringify({
|
|
6251
6306
|
error: aborted ? `Upstream request timed out after ${upstreamTimeoutMs / 1e3}s` : fetchErr?.message || "Upstream fetch failed",
|
|
6252
|
-
phase:
|
|
6253
|
-
fetchMode:
|
|
6254
|
-
scraperapi: {
|
|
6255
|
-
host: SCRAPER_PROXY_HOST,
|
|
6256
|
-
port: SCRAPER_PROXY_PORT,
|
|
6257
|
-
username: SCRAPER_PROXY_USERNAME,
|
|
6258
|
-
endpoint: SCRAPER_API_ENDPOINT,
|
|
6259
|
-
hasProxyPassword: Boolean(SCRAPER_PROXY_PASSWORD),
|
|
6260
|
-
requestTlsRejectUnauthorized: SCRAPER_REQUEST_TLS_REJECT_UNAUTHORIZED
|
|
6261
|
-
},
|
|
6307
|
+
phase: conversionProxyBaseUrlForRequest ? "worker-raw-fetch" : "direct-upstream-fetch",
|
|
6308
|
+
fetchMode: conversionProxyBaseUrlForRequest ? "worker" : "direct",
|
|
6262
6309
|
cause: fetchCause && typeof fetchCause === "object" ? {
|
|
6263
6310
|
name: fetchCause.name,
|
|
6264
6311
|
code: fetchCause.code,
|
|
@@ -6444,8 +6491,51 @@ try{
|
|
|
6444
6491
|
}
|
|
6445
6492
|
}
|
|
6446
6493
|
}catch(_){}
|
|
6447
|
-
function getEditorUrlPayload(){
|
|
6448
|
-
|
|
6494
|
+
function getEditorUrlPayload(){
|
|
6495
|
+
try{
|
|
6496
|
+
var u=new URL(window.location.href);
|
|
6497
|
+
var nested=u.searchParams.get("url");
|
|
6498
|
+
if(nested){
|
|
6499
|
+
return {url:nested,password:u.searchParams.get("password")||undefined};
|
|
6500
|
+
}
|
|
6501
|
+
var p=u.pathname||"";
|
|
6502
|
+
var isProxyPath=p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0||p.indexOf("api/conversion-proxy")!==-1;
|
|
6503
|
+
if(isProxyPath){
|
|
6504
|
+
var recoveredBase=new URL(TARGET_PAGE_URL,window.location.href);
|
|
6505
|
+
var qp=new URLSearchParams(u.search||"");
|
|
6506
|
+
qp.delete("url");
|
|
6507
|
+
qp.delete("password");
|
|
6508
|
+
qp.delete("conversionProxyBaseUrl");
|
|
6509
|
+
qp.delete("trackingMarkers");
|
|
6510
|
+
qp.delete("strictObserverFreeze");
|
|
6511
|
+
qp.delete("proxy");
|
|
6512
|
+
qp.delete("raw");
|
|
6513
|
+
recoveredBase.search="";
|
|
6514
|
+
qp.forEach(function(v,k){recoveredBase.searchParams.set(k,v);});
|
|
6515
|
+
recoveredBase.hash=u.hash||"";
|
|
6516
|
+
return {url:recoveredBase.toString(),password:u.searchParams.get("password")||undefined};
|
|
6517
|
+
}
|
|
6518
|
+
return {url:u.toString(),password:u.searchParams.get("password")||undefined};
|
|
6519
|
+
}catch(_){
|
|
6520
|
+
return null;
|
|
6521
|
+
}
|
|
6522
|
+
}
|
|
6523
|
+
function notifyEditorUrlChanged(){
|
|
6524
|
+
try{
|
|
6525
|
+
var payload=getEditorUrlPayload();
|
|
6526
|
+
if(!payload) return;
|
|
6527
|
+
try{
|
|
6528
|
+
console.info("[conversion-proxy] iframe url rendered",{
|
|
6529
|
+
current:window.location.href,
|
|
6530
|
+
target:payload.url||"",
|
|
6531
|
+
passwordPresent:!!payload.password
|
|
6532
|
+
});
|
|
6533
|
+
}catch(_){}
|
|
6534
|
+
if(window.parent){
|
|
6535
|
+
window.parent.postMessage({channel:PARENT_URL_CHANNEL,type:"editor-url-changed",payload:payload},"*");
|
|
6536
|
+
}
|
|
6537
|
+
}catch(_){}
|
|
6538
|
+
}
|
|
6449
6539
|
try{notifyEditorUrlChanged();}catch(_){}
|
|
6450
6540
|
try{if(window.history&&typeof window.history.pushState==="function"){var nativePushState=window.history.pushState;window.history.pushState=function(){var ret=nativePushState.apply(window.history,arguments);setTimeout(notifyEditorUrlChanged,0);return ret;};}}catch(_){}
|
|
6451
6541
|
try{if(window.history&&typeof window.history.replaceState==="function"){var nativeReplaceState=window.history.replaceState;window.history.replaceState=function(){var ret=nativeReplaceState.apply(window.history,arguments);setTimeout(notifyEditorUrlChanged,0);return ret;};}}catch(_){}
|
|
@@ -6453,7 +6543,29 @@ try{window.addEventListener("popstate",notifyEditorUrlChanged,true);}catch(_){}
|
|
|
6453
6543
|
try{window.addEventListener("hashchange",notifyEditorUrlChanged,true);}catch(_){}
|
|
6454
6544
|
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
6455
6545
|
function toAbsolute(raw){if(isSkippable(raw))return raw;try{var base=raw.startsWith("/")||raw.startsWith("//")?TARGET_ORIGIN:TARGET_PAGE_URL;return new URL(raw,base).toString();}catch(_){return raw;}}
|
|
6456
|
-
function toProxy(raw){
|
|
6546
|
+
function toProxy(raw){
|
|
6547
|
+
if(isSkippable(raw))return null;
|
|
6548
|
+
var abs=toAbsolute(raw);
|
|
6549
|
+
if(!abs||typeof abs!=="string")return null;
|
|
6550
|
+
try{
|
|
6551
|
+
var parsed=new URL(abs);
|
|
6552
|
+
// If input is already a proxy URL, unwrap to its target url first
|
|
6553
|
+
// to avoid nested /api/conversion-proxy?url=/api/conversion-proxy?... chains.
|
|
6554
|
+
var p=(parsed.pathname||"");
|
|
6555
|
+
var isProxyPath=p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0||p.indexOf("api/conversion-proxy")!==-1;
|
|
6556
|
+
if(isProxyPath){
|
|
6557
|
+
var nested=parsed.searchParams.get("url")||"";
|
|
6558
|
+
if(nested){
|
|
6559
|
+
try{parsed=new URL(nested);}catch(_){}
|
|
6560
|
+
}
|
|
6561
|
+
}
|
|
6562
|
+
if(parsed.origin!==TARGET_ORIGIN)return null;
|
|
6563
|
+
var root="/api/conversion-proxy";
|
|
6564
|
+
return root+"?password="+encodeURIComponent(PROXY_PASSWORD||"")+"&url="+encodeURIComponent(parsed.toString());
|
|
6565
|
+
}catch(_){
|
|
6566
|
+
return null;
|
|
6567
|
+
}
|
|
6568
|
+
}
|
|
6457
6569
|
var nativeAssign=window.location.assign?window.location.assign.bind(window.location):null;
|
|
6458
6570
|
var nativeReplace=window.location.replace?window.location.replace.bind(window.location):null;
|
|
6459
6571
|
function safeNavigate(raw,mode){var abs=toAbsolute(raw);var prox=toProxy(raw);if(!prox){try{console.warn("[conversion-proxy] redirect blocked",{mode:mode,requested:raw,resolved:abs,origin:TARGET_ORIGIN});}catch(_){}return false;}try{console.info("[conversion-proxy] redirect intercepted",{mode:mode,requested:raw,resolved:abs,proxied:prox});if(mode==="replace"&&nativeReplace){nativeReplace(prox);return true;}if(nativeAssign){nativeAssign(prox);return true;}window.location.href=prox;return true;}catch(err){try{console.warn("[conversion-proxy] redirect interception failed",{mode:mode,requested:raw,resolved:abs,proxied:prox,error:err&&err.message?err.message:String(err)});}catch(_){}return false;}}
|
|
@@ -6503,12 +6615,49 @@ var PROXY_BASE_URL=_proxyCtx?_proxyCtx.searchParams.get("conversionProxyBaseUrl"
|
|
|
6503
6615
|
var PROXY_TRACKING_MARKERS=_proxyCtx?_proxyCtx.searchParams.get("trackingMarkers")||"":"";
|
|
6504
6616
|
var PROXY_STRICT_FREEZE=_proxyCtx?_proxyCtx.searchParams.get("strictObserverFreeze")||"":"";
|
|
6505
6617
|
var PROXY_UPSTREAM_MODE=_proxyCtx?_proxyCtx.searchParams.get("proxy")||"":"";
|
|
6618
|
+
var EDITOR_ORIGIN=(function(){try{return String(window.location.origin||"");}catch(_){return "";}})();
|
|
6619
|
+
var EDITOR_HOST_KEY=(function(){try{var u=new URL(EDITOR_ORIGIN);return (u.hostname||"").toLowerCase()+":"+(u.port||"");}catch(_){return "";}})();
|
|
6506
6620
|
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
6621
|
+
function isEditorHostUrl(u){
|
|
6622
|
+
try{
|
|
6623
|
+
if(!u) return false;
|
|
6624
|
+
var hostKey=(u.hostname||"").toLowerCase()+":"+(u.port||"");
|
|
6625
|
+
if(EDITOR_HOST_KEY&&hostKey===EDITOR_HOST_KEY) return true;
|
|
6626
|
+
// localhost aliases for same dev server port
|
|
6627
|
+
var host=(u.hostname||"").toLowerCase();
|
|
6628
|
+
var editorHost=EDITOR_HOST_KEY.split(":")[0]||"";
|
|
6629
|
+
var samePort=(u.port||"")===(EDITOR_HOST_KEY.split(":")[1]||"");
|
|
6630
|
+
var localAlias=(host==="localhost"||host==="127.0.0.1"||host==="[::1]");
|
|
6631
|
+
var editorLocalAlias=(editorHost==="localhost"||editorHost==="127.0.0.1"||editorHost==="[::1]");
|
|
6632
|
+
return samePort&&localAlias&&editorLocalAlias;
|
|
6633
|
+
}catch(_){
|
|
6634
|
+
return false;
|
|
6635
|
+
}
|
|
6636
|
+
}
|
|
6507
6637
|
function toProxyNetworkUrl(raw){
|
|
6508
6638
|
if(isSkippable(raw))return raw;
|
|
6509
6639
|
try{
|
|
6510
6640
|
var base=raw.startsWith("/")?TARGET_ORIGIN:TARGET_PAGE_URL;
|
|
6511
6641
|
var abs=new URL(raw,base);
|
|
6642
|
+
// Unwrap already-proxied URLs first to avoid nested proxy urls.
|
|
6643
|
+
var p0=abs.pathname||"";
|
|
6644
|
+
var isProxyPath0=p0==="/api/conversion-proxy"||p0.indexOf("/api/conversion-proxy/")===0||p0.indexOf("api/conversion-proxy")!==-1;
|
|
6645
|
+
if(isProxyPath0){
|
|
6646
|
+
var nested0=abs.searchParams.get("url")||"";
|
|
6647
|
+
if(nested0){
|
|
6648
|
+
try{abs=new URL(nested0);}catch(_){}
|
|
6649
|
+
}
|
|
6650
|
+
}
|
|
6651
|
+
// Some embedded scripts build absolute requests against editor origin
|
|
6652
|
+
// (e.g. https://localhost:4001/api/unstable/graphql.json). Remap those
|
|
6653
|
+
// paths to target origin first, then proxy as usual.
|
|
6654
|
+
if(EDITOR_ORIGIN&&isEditorHostUrl(abs)){
|
|
6655
|
+
var p=abs.pathname||"";
|
|
6656
|
+
var isRootProxyPath=p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0;
|
|
6657
|
+
if(!isRootProxyPath){
|
|
6658
|
+
abs=new URL((abs.pathname||"/")+(abs.search||"")+(abs.hash||""),TARGET_ORIGIN);
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6512
6661
|
if(abs.origin!==TARGET_ORIGIN)return raw;
|
|
6513
6662
|
var prox=new URL(PROXY_ROOT,window.location.origin);
|
|
6514
6663
|
prox.searchParams.set("password",PROXY_PASSWORD||"");
|