@accelerated-agency/visual-editor 0.4.1 → 0.4.3
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/index.js +23 -3
- package/dist/vite.cjs +52 -16
- package/dist/vite.js +52 -16
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -4657,7 +4657,6 @@ function PlatformVisualEditor({
|
|
|
4657
4657
|
}),
|
|
4658
4658
|
[experiment]
|
|
4659
4659
|
);
|
|
4660
|
-
console.log("loadPayload", loadPayload);
|
|
4661
4660
|
useEffect(() => {
|
|
4662
4661
|
if (!editorReady) return;
|
|
4663
4662
|
const payloadKey = JSON.stringify(loadPayload);
|
|
@@ -4807,6 +4806,7 @@ function PlatformVisualEditorV2({
|
|
|
4807
4806
|
// channel kept for API compatibility; VvvebJs uses its own internal channel
|
|
4808
4807
|
embeddedGlobalKey = "__CONVERSION_EMBEDDED__",
|
|
4809
4808
|
proxyBaseUrl = "",
|
|
4809
|
+
conversionProxyBaseUrl = "",
|
|
4810
4810
|
strictObserverFreeze = false,
|
|
4811
4811
|
trackingMarkers = [],
|
|
4812
4812
|
className = "fixed inset-0 z-[9999] flex flex-col bg-white",
|
|
@@ -4839,6 +4839,7 @@ function PlatformVisualEditorV2({
|
|
|
4839
4839
|
}) {
|
|
4840
4840
|
const iframeRef = useRef(null);
|
|
4841
4841
|
const [editorReady, setEditorReady] = useState(false);
|
|
4842
|
+
const [iframeLoaded, setIframeLoaded] = useState(false);
|
|
4842
4843
|
const [isSaving, setIsSaving] = useState(false);
|
|
4843
4844
|
const [dirty, setDirty] = useState(false);
|
|
4844
4845
|
const dirtyRef = useRef(false);
|
|
@@ -4870,11 +4871,12 @@ function PlatformVisualEditorV2({
|
|
|
4870
4871
|
status: experiment?.status,
|
|
4871
4872
|
pageUrl: experiment?.pageUrl,
|
|
4872
4873
|
editorPassword: experiment?.editorPassword,
|
|
4874
|
+
conversionProxyBaseUrl: typeof conversionProxyBaseUrl === "string" ? conversionProxyBaseUrl.trim().replace(/\/+$/, "") : "",
|
|
4873
4875
|
strictObserverFreeze: !!strictObserverFreeze,
|
|
4874
4876
|
trackingMarkers: Array.isArray(trackingMarkers) ? trackingMarkers.filter((m) => typeof m === "string" && m.trim().length > 0) : [],
|
|
4875
4877
|
variations: experiment?.variations ?? []
|
|
4876
4878
|
}),
|
|
4877
|
-
[experiment, strictObserverFreeze, trackingMarkers]
|
|
4879
|
+
[conversionProxyBaseUrl, experiment, strictObserverFreeze, trackingMarkers]
|
|
4878
4880
|
);
|
|
4879
4881
|
const editorSrc = useMemo(() => {
|
|
4880
4882
|
const safeBaseUrl = normalizeProxyBaseUrl(proxyBaseUrl);
|
|
@@ -4968,6 +4970,23 @@ function PlatformVisualEditorV2({
|
|
|
4968
4970
|
window.addEventListener("message", listener);
|
|
4969
4971
|
return () => window.removeEventListener("message", listener);
|
|
4970
4972
|
}, [handleMessage]);
|
|
4973
|
+
useEffect(() => {
|
|
4974
|
+
if (!iframeLoaded || editorReady) return;
|
|
4975
|
+
let attempts = 0;
|
|
4976
|
+
const maxAttempts = 12;
|
|
4977
|
+
const tickMs = 500;
|
|
4978
|
+
const tryBootstrap = () => {
|
|
4979
|
+
if (editorReady) return;
|
|
4980
|
+
attempts += 1;
|
|
4981
|
+
sendToVvveb("load-experiment", loadPayload);
|
|
4982
|
+
if (attempts >= maxAttempts) {
|
|
4983
|
+
clearInterval(timer);
|
|
4984
|
+
}
|
|
4985
|
+
};
|
|
4986
|
+
tryBootstrap();
|
|
4987
|
+
const timer = window.setInterval(tryBootstrap, tickMs);
|
|
4988
|
+
return () => window.clearInterval(timer);
|
|
4989
|
+
}, [iframeLoaded, editorReady, loadPayload, sendToVvveb]);
|
|
4971
4990
|
useCallback(
|
|
4972
4991
|
(tab) => onTabChange?.(tab),
|
|
4973
4992
|
[onTabChange]
|
|
@@ -4987,7 +5006,8 @@ function PlatformVisualEditorV2({
|
|
|
4987
5006
|
src: editorSrc,
|
|
4988
5007
|
className: "w-full h-full border-0",
|
|
4989
5008
|
title: "Vvveb Visual Editor",
|
|
4990
|
-
allow: "same-origin"
|
|
5009
|
+
allow: "same-origin",
|
|
5010
|
+
onLoad: () => setIframeLoaded(true)
|
|
4991
5011
|
}
|
|
4992
5012
|
) }) });
|
|
4993
5013
|
}
|
package/dist/vite.cjs
CHANGED
|
@@ -1140,6 +1140,8 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
1140
1140
|
</div>
|
|
1141
1141
|
|
|
1142
1142
|
<!-- CDN scripts -->
|
|
1143
|
+
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
|
1144
|
+
<script src="https://cdn.jsdelivr.net/npm/jquery-ui-dist@1.13.3/jquery-ui.min.js"></script>
|
|
1143
1145
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
1144
1146
|
<script>
|
|
1145
1147
|
window.__veLoadFallback = function(el, candidates){
|
|
@@ -1166,15 +1168,7 @@ window.__veLoadFallback = function(el, candidates){
|
|
|
1166
1168
|
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/inputs.js"
|
|
1167
1169
|
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/inputs.js||https://unpkg.com/vvvebjs@latest/libs/builder/inputs.js')"
|
|
1168
1170
|
></script>
|
|
1169
|
-
<!-- components.js
|
|
1170
|
-
<script
|
|
1171
|
-
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components.js"
|
|
1172
|
-
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components.js||https://unpkg.com/vvvebjs@latest/libs/builder/components.js')"
|
|
1173
|
-
></script>
|
|
1174
|
-
// <script
|
|
1175
|
-
// src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-widgets.js"
|
|
1176
|
-
// onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-widgets.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-widgets.js')"
|
|
1177
|
-
// ></script>
|
|
1171
|
+
<!-- components.js removed (frequently missing on npm CDN); safety stubs below prevent bootstrap/widgets loader errors -->
|
|
1178
1172
|
<script>
|
|
1179
1173
|
/* Safety stub: if components.js didn't define these, create empty arrays so
|
|
1180
1174
|
components-bootstrap5.js doesn't throw ReferenceError on load. */
|
|
@@ -1203,7 +1197,7 @@ if (window.Vvveb && window.Vvveb.Components) {
|
|
|
1203
1197
|
</script>
|
|
1204
1198
|
<script
|
|
1205
1199
|
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap4.js"
|
|
1206
|
-
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap4.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-bootstrap4.js')"
|
|
1200
|
+
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap5.js||https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap4.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-bootstrap5.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-bootstrap4.js')"
|
|
1207
1201
|
></script>
|
|
1208
1202
|
<script
|
|
1209
1203
|
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-widgets.js"
|
|
@@ -2436,12 +2430,24 @@ function handleLoadExperiment(data) {
|
|
|
2436
2430
|
var extraTrackingMarkers = Array.isArray(data && data.trackingMarkers)
|
|
2437
2431
|
? data.trackingMarkers.filter(function(m){return typeof m === 'string' && m.trim().length > 0;})
|
|
2438
2432
|
: [];
|
|
2433
|
+
var conversionProxyBaseUrl = (typeof (data && data.conversionProxyBaseUrl) === 'string'
|
|
2434
|
+
? data.conversionProxyBaseUrl
|
|
2435
|
+
: '').trim().replace(/\\/+$/, '');
|
|
2436
|
+
var proxyPath = '/api/conversion-proxy';
|
|
2437
|
+
// Keep iframe navigation same-origin for DOM access (selection/editing).
|
|
2438
|
+
// If conversionProxyBaseUrl is provided, middleware delegates upstream fetches
|
|
2439
|
+
// server-side while browser URLs stay local.
|
|
2440
|
+
var proxyRoot = proxyPath;
|
|
2439
2441
|
var trackingMarkersParam = extraTrackingMarkers.length
|
|
2440
2442
|
? '&trackingMarkers=' + encodeURIComponent(JSON.stringify(extraTrackingMarkers))
|
|
2441
2443
|
: '';
|
|
2442
|
-
var
|
|
2444
|
+
var conversionProxyBaseUrlParam = conversionProxyBaseUrl
|
|
2445
|
+
? '&conversionProxyBaseUrl=' + encodeURIComponent(conversionProxyBaseUrl)
|
|
2446
|
+
: '';
|
|
2447
|
+
var proxyUrl = proxyRoot + '?password=' + encodeURIComponent(data.editorPassword || '') +
|
|
2443
2448
|
'&url=' + encodeURIComponent(pageUrl) +
|
|
2444
2449
|
'&strictObserverFreeze=' + encodeURIComponent(data && data.strictObserverFreeze ? '1' : '0') +
|
|
2450
|
+
conversionProxyBaseUrlParam +
|
|
2445
2451
|
trackingMarkersParam;
|
|
2446
2452
|
|
|
2447
2453
|
// Parent often re-posts load-experiment when React re-renders (new object identity) or
|
|
@@ -5527,6 +5533,8 @@ function createVisualEditorMiddleware(options) {
|
|
|
5527
5533
|
const url = new URL(req.url || "", "http://localhost");
|
|
5528
5534
|
const targetUrl = url.searchParams.get("url");
|
|
5529
5535
|
const password = url.searchParams.get("password") || "";
|
|
5536
|
+
const conversionProxyBaseUrlForRequest = (url.searchParams.get("conversionProxyBaseUrl") || "").trim().replace(/\/+$/, "");
|
|
5537
|
+
const proxyRootForRequest = "/api/conversion-proxy";
|
|
5530
5538
|
const extraTrackingMarkersForRequest = parseTrackingMarkersParam(
|
|
5531
5539
|
url.searchParams.get("trackingMarkers")
|
|
5532
5540
|
);
|
|
@@ -5579,7 +5587,34 @@ function createVisualEditorMiddleware(options) {
|
|
|
5579
5587
|
return false;
|
|
5580
5588
|
}
|
|
5581
5589
|
};
|
|
5590
|
+
const workerRawFetch = (input, init = {}) => {
|
|
5591
|
+
const workerUrl = new URL("/api/conversion-proxy", conversionProxyBaseUrlForRequest);
|
|
5592
|
+
workerUrl.searchParams.set("url", input);
|
|
5593
|
+
workerUrl.searchParams.set("raw", "1");
|
|
5594
|
+
const method2 = (init?.method || "GET").toUpperCase();
|
|
5595
|
+
const nextHeaders = {};
|
|
5596
|
+
const h = init?.headers;
|
|
5597
|
+
if (h && typeof h.forEach === "function") {
|
|
5598
|
+
h.forEach((v, k) => {
|
|
5599
|
+
if (!v) return;
|
|
5600
|
+
nextHeaders[k] = String(v);
|
|
5601
|
+
});
|
|
5602
|
+
} else {
|
|
5603
|
+
Object.entries(h || {}).forEach(([k, v]) => {
|
|
5604
|
+
if (!v) return;
|
|
5605
|
+
nextHeaders[k] = Array.isArray(v) ? v.join(",") : String(v);
|
|
5606
|
+
});
|
|
5607
|
+
}
|
|
5608
|
+
return fetch(workerUrl.toString(), {
|
|
5609
|
+
...init,
|
|
5610
|
+
method: method2,
|
|
5611
|
+
headers: nextHeaders
|
|
5612
|
+
});
|
|
5613
|
+
};
|
|
5582
5614
|
const upstreamFetch = async (input, init = {}) => {
|
|
5615
|
+
if (conversionProxyBaseUrlForRequest) {
|
|
5616
|
+
return workerRawFetch(input, init);
|
|
5617
|
+
}
|
|
5583
5618
|
const primary = await scraperFetch(input, init);
|
|
5584
5619
|
if (!await shouldFallbackFromScraper(primary)) {
|
|
5585
5620
|
return primary;
|
|
@@ -5610,7 +5645,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
5610
5645
|
)}`,
|
|
5611
5646
|
redirect: "manual"
|
|
5612
5647
|
});
|
|
5613
|
-
const setCookies = passResp.headers.getSetCookie?.() || [];
|
|
5648
|
+
const setCookies = passResp.headers.getSetCookie?.() || (passResp.headers.get("set-cookie") ? [String(passResp.headers.get("set-cookie"))] : []);
|
|
5614
5649
|
cookieHeader = setCookies.map((c) => c.split(";")[0]).join("; ");
|
|
5615
5650
|
}
|
|
5616
5651
|
const fetchHeaders = { ...headers };
|
|
@@ -5708,7 +5743,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
5708
5743
|
html = stripTrackingScriptsFromScrapedHtml(html, trackingMarkersForRequest);
|
|
5709
5744
|
html = html.replace(/(href|src|action)="\/(?!\/)/g, `$1="${origin}/`);
|
|
5710
5745
|
const escapedOrigin = origin.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5711
|
-
const proxyBase =
|
|
5746
|
+
const proxyBase = `${proxyRootForRequest}?password=${encodeURIComponent(password)}&url=`;
|
|
5712
5747
|
html = html.replace(
|
|
5713
5748
|
new RegExp(`(href|action)="${escapedOrigin}(/[^"]*)"`, "g"),
|
|
5714
5749
|
(match, attr, urlPath) => {
|
|
@@ -5721,7 +5756,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
5721
5756
|
);
|
|
5722
5757
|
html = html.replace(
|
|
5723
5758
|
/data-link="\/(?!\/)([^"]*)"/g,
|
|
5724
|
-
(_match, pathPart) => `data-link="
|
|
5759
|
+
(_match, pathPart) => `data-link="${proxyRootForRequest}?password=${encodeURIComponent(password)}&url=${encodeURIComponent(
|
|
5725
5760
|
`${origin}/${pathPart}`
|
|
5726
5761
|
)}"`
|
|
5727
5762
|
);
|
|
@@ -5745,6 +5780,7 @@ ${iframeAlwaysShowCssGuardScript}
|
|
|
5745
5780
|
var TARGET_ORIGIN=${JSON.stringify(origin)};
|
|
5746
5781
|
var TARGET_PAGE_URL=${JSON.stringify(targetUrl)};
|
|
5747
5782
|
var PROXY_PASSWORD=${JSON.stringify(password)};
|
|
5783
|
+
var PROXY_BASE_URL="";
|
|
5748
5784
|
var STRICT_OBSERVER_FREEZE=${JSON.stringify(strictObserverFreezeForRequest)};
|
|
5749
5785
|
var PARENT_URL_CHANNEL="vvveb-proxy-url";
|
|
5750
5786
|
window.__CONVERSION_EDITOR_ACTIVE__=true;
|
|
@@ -5795,7 +5831,7 @@ function shouldBlockEditorTracking(rawUrl){
|
|
|
5795
5831
|
var looksLikeHeartbeatPayload=hasViewportPing&&hasSessionIds;
|
|
5796
5832
|
var isCrossOriginCollector=host!==TARGET_HOSTNAME&&hasMarker(host,TRACKING_HOST_MARKERS)&&hasMarker(path,TRACKING_PATH_MARKERS);
|
|
5797
5833
|
var isSnowplowStylePath=path==="/i"||path.indexOf("/com.snowplowanalytics.snowplow/")!==-1||path.indexOf("/tp2")!==-1;
|
|
5798
|
-
var isTaboolaUnip=host==="trc-events.taboola.com"
|
|
5834
|
+
var isTaboolaUnip=host==="trc-events.taboola.com"&&/\\/log\\/\\d+\\/unip(?:\\/|$)/.test(path);
|
|
5799
5835
|
var isCollectApiPath=path==="/api/collect"||path.indexOf("/api/collect/")===0;
|
|
5800
5836
|
var isNbCollectorPath=path==="/nb-collector"||path.indexOf("/nb-collector/")===0;
|
|
5801
5837
|
return isCrossOriginCollector||(looksLikeHeartbeatPayload&&isSnowplowStylePath)||isCollectApiPath||isTaboolaUnip||isNbCollectorPath;
|
|
@@ -5865,7 +5901,7 @@ try{window.addEventListener("popstate",notifyEditorUrlChanged,true);}catch(_){}
|
|
|
5865
5901
|
try{window.addEventListener("hashchange",notifyEditorUrlChanged,true);}catch(_){}
|
|
5866
5902
|
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
5867
5903
|
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;}}
|
|
5868
|
-
function toProxy(raw){if(isSkippable(raw))return null;var abs=toAbsolute(raw);if(!abs||typeof abs!=="string")return null;try{var parsed=new URL(abs);if(parsed.origin!==TARGET_ORIGIN)return null;
|
|
5904
|
+
function toProxy(raw){if(isSkippable(raw))return null;var abs=toAbsolute(raw);if(!abs||typeof abs!=="string")return null;try{var parsed=new URL(abs);if(parsed.origin!==TARGET_ORIGIN)return null;var root="/api/conversion-proxy";return root+"?password="+encodeURIComponent(PROXY_PASSWORD||"")+"&url="+encodeURIComponent(parsed.toString());}catch(_){return null;}}
|
|
5869
5905
|
var nativeAssign=window.location.assign?window.location.assign.bind(window.location):null;
|
|
5870
5906
|
var nativeReplace=window.location.replace?window.location.replace.bind(window.location):null;
|
|
5871
5907
|
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;}}
|
package/dist/vite.js
CHANGED
|
@@ -1132,6 +1132,8 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
1132
1132
|
</div>
|
|
1133
1133
|
|
|
1134
1134
|
<!-- CDN scripts -->
|
|
1135
|
+
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
|
1136
|
+
<script src="https://cdn.jsdelivr.net/npm/jquery-ui-dist@1.13.3/jquery-ui.min.js"></script>
|
|
1135
1137
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
1136
1138
|
<script>
|
|
1137
1139
|
window.__veLoadFallback = function(el, candidates){
|
|
@@ -1158,15 +1160,7 @@ window.__veLoadFallback = function(el, candidates){
|
|
|
1158
1160
|
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/inputs.js"
|
|
1159
1161
|
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/inputs.js||https://unpkg.com/vvvebjs@latest/libs/builder/inputs.js')"
|
|
1160
1162
|
></script>
|
|
1161
|
-
<!-- components.js
|
|
1162
|
-
<script
|
|
1163
|
-
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components.js"
|
|
1164
|
-
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components.js||https://unpkg.com/vvvebjs@latest/libs/builder/components.js')"
|
|
1165
|
-
></script>
|
|
1166
|
-
// <script
|
|
1167
|
-
// src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-widgets.js"
|
|
1168
|
-
// onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-widgets.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-widgets.js')"
|
|
1169
|
-
// ></script>
|
|
1163
|
+
<!-- components.js removed (frequently missing on npm CDN); safety stubs below prevent bootstrap/widgets loader errors -->
|
|
1170
1164
|
<script>
|
|
1171
1165
|
/* Safety stub: if components.js didn't define these, create empty arrays so
|
|
1172
1166
|
components-bootstrap5.js doesn't throw ReferenceError on load. */
|
|
@@ -1195,7 +1189,7 @@ if (window.Vvveb && window.Vvveb.Components) {
|
|
|
1195
1189
|
</script>
|
|
1196
1190
|
<script
|
|
1197
1191
|
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap4.js"
|
|
1198
|
-
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap4.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-bootstrap4.js')"
|
|
1192
|
+
onerror="window.__veLoadFallback(this,'https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap5.js||https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-bootstrap4.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-bootstrap5.js||https://unpkg.com/vvvebjs@latest/libs/builder/components-bootstrap4.js')"
|
|
1199
1193
|
></script>
|
|
1200
1194
|
<script
|
|
1201
1195
|
src="https://cdn.jsdelivr.net/npm/vvvebjs@latest/libs/builder/components-widgets.js"
|
|
@@ -2428,12 +2422,24 @@ function handleLoadExperiment(data) {
|
|
|
2428
2422
|
var extraTrackingMarkers = Array.isArray(data && data.trackingMarkers)
|
|
2429
2423
|
? data.trackingMarkers.filter(function(m){return typeof m === 'string' && m.trim().length > 0;})
|
|
2430
2424
|
: [];
|
|
2425
|
+
var conversionProxyBaseUrl = (typeof (data && data.conversionProxyBaseUrl) === 'string'
|
|
2426
|
+
? data.conversionProxyBaseUrl
|
|
2427
|
+
: '').trim().replace(/\\/+$/, '');
|
|
2428
|
+
var proxyPath = '/api/conversion-proxy';
|
|
2429
|
+
// Keep iframe navigation same-origin for DOM access (selection/editing).
|
|
2430
|
+
// If conversionProxyBaseUrl is provided, middleware delegates upstream fetches
|
|
2431
|
+
// server-side while browser URLs stay local.
|
|
2432
|
+
var proxyRoot = proxyPath;
|
|
2431
2433
|
var trackingMarkersParam = extraTrackingMarkers.length
|
|
2432
2434
|
? '&trackingMarkers=' + encodeURIComponent(JSON.stringify(extraTrackingMarkers))
|
|
2433
2435
|
: '';
|
|
2434
|
-
var
|
|
2436
|
+
var conversionProxyBaseUrlParam = conversionProxyBaseUrl
|
|
2437
|
+
? '&conversionProxyBaseUrl=' + encodeURIComponent(conversionProxyBaseUrl)
|
|
2438
|
+
: '';
|
|
2439
|
+
var proxyUrl = proxyRoot + '?password=' + encodeURIComponent(data.editorPassword || '') +
|
|
2435
2440
|
'&url=' + encodeURIComponent(pageUrl) +
|
|
2436
2441
|
'&strictObserverFreeze=' + encodeURIComponent(data && data.strictObserverFreeze ? '1' : '0') +
|
|
2442
|
+
conversionProxyBaseUrlParam +
|
|
2437
2443
|
trackingMarkersParam;
|
|
2438
2444
|
|
|
2439
2445
|
// Parent often re-posts load-experiment when React re-renders (new object identity) or
|
|
@@ -5519,6 +5525,8 @@ function createVisualEditorMiddleware(options) {
|
|
|
5519
5525
|
const url = new URL(req.url || "", "http://localhost");
|
|
5520
5526
|
const targetUrl = url.searchParams.get("url");
|
|
5521
5527
|
const password = url.searchParams.get("password") || "";
|
|
5528
|
+
const conversionProxyBaseUrlForRequest = (url.searchParams.get("conversionProxyBaseUrl") || "").trim().replace(/\/+$/, "");
|
|
5529
|
+
const proxyRootForRequest = "/api/conversion-proxy";
|
|
5522
5530
|
const extraTrackingMarkersForRequest = parseTrackingMarkersParam(
|
|
5523
5531
|
url.searchParams.get("trackingMarkers")
|
|
5524
5532
|
);
|
|
@@ -5571,7 +5579,34 @@ function createVisualEditorMiddleware(options) {
|
|
|
5571
5579
|
return false;
|
|
5572
5580
|
}
|
|
5573
5581
|
};
|
|
5582
|
+
const workerRawFetch = (input, init = {}) => {
|
|
5583
|
+
const workerUrl = new URL("/api/conversion-proxy", conversionProxyBaseUrlForRequest);
|
|
5584
|
+
workerUrl.searchParams.set("url", input);
|
|
5585
|
+
workerUrl.searchParams.set("raw", "1");
|
|
5586
|
+
const method2 = (init?.method || "GET").toUpperCase();
|
|
5587
|
+
const nextHeaders = {};
|
|
5588
|
+
const h = init?.headers;
|
|
5589
|
+
if (h && typeof h.forEach === "function") {
|
|
5590
|
+
h.forEach((v, k) => {
|
|
5591
|
+
if (!v) return;
|
|
5592
|
+
nextHeaders[k] = String(v);
|
|
5593
|
+
});
|
|
5594
|
+
} else {
|
|
5595
|
+
Object.entries(h || {}).forEach(([k, v]) => {
|
|
5596
|
+
if (!v) return;
|
|
5597
|
+
nextHeaders[k] = Array.isArray(v) ? v.join(",") : String(v);
|
|
5598
|
+
});
|
|
5599
|
+
}
|
|
5600
|
+
return fetch(workerUrl.toString(), {
|
|
5601
|
+
...init,
|
|
5602
|
+
method: method2,
|
|
5603
|
+
headers: nextHeaders
|
|
5604
|
+
});
|
|
5605
|
+
};
|
|
5574
5606
|
const upstreamFetch = async (input, init = {}) => {
|
|
5607
|
+
if (conversionProxyBaseUrlForRequest) {
|
|
5608
|
+
return workerRawFetch(input, init);
|
|
5609
|
+
}
|
|
5575
5610
|
const primary = await scraperFetch(input, init);
|
|
5576
5611
|
if (!await shouldFallbackFromScraper(primary)) {
|
|
5577
5612
|
return primary;
|
|
@@ -5602,7 +5637,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
5602
5637
|
)}`,
|
|
5603
5638
|
redirect: "manual"
|
|
5604
5639
|
});
|
|
5605
|
-
const setCookies = passResp.headers.getSetCookie?.() || [];
|
|
5640
|
+
const setCookies = passResp.headers.getSetCookie?.() || (passResp.headers.get("set-cookie") ? [String(passResp.headers.get("set-cookie"))] : []);
|
|
5606
5641
|
cookieHeader = setCookies.map((c) => c.split(";")[0]).join("; ");
|
|
5607
5642
|
}
|
|
5608
5643
|
const fetchHeaders = { ...headers };
|
|
@@ -5700,7 +5735,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
5700
5735
|
html = stripTrackingScriptsFromScrapedHtml(html, trackingMarkersForRequest);
|
|
5701
5736
|
html = html.replace(/(href|src|action)="\/(?!\/)/g, `$1="${origin}/`);
|
|
5702
5737
|
const escapedOrigin = origin.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5703
|
-
const proxyBase =
|
|
5738
|
+
const proxyBase = `${proxyRootForRequest}?password=${encodeURIComponent(password)}&url=`;
|
|
5704
5739
|
html = html.replace(
|
|
5705
5740
|
new RegExp(`(href|action)="${escapedOrigin}(/[^"]*)"`, "g"),
|
|
5706
5741
|
(match, attr, urlPath) => {
|
|
@@ -5713,7 +5748,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
5713
5748
|
);
|
|
5714
5749
|
html = html.replace(
|
|
5715
5750
|
/data-link="\/(?!\/)([^"]*)"/g,
|
|
5716
|
-
(_match, pathPart) => `data-link="
|
|
5751
|
+
(_match, pathPart) => `data-link="${proxyRootForRequest}?password=${encodeURIComponent(password)}&url=${encodeURIComponent(
|
|
5717
5752
|
`${origin}/${pathPart}`
|
|
5718
5753
|
)}"`
|
|
5719
5754
|
);
|
|
@@ -5737,6 +5772,7 @@ ${iframeAlwaysShowCssGuardScript}
|
|
|
5737
5772
|
var TARGET_ORIGIN=${JSON.stringify(origin)};
|
|
5738
5773
|
var TARGET_PAGE_URL=${JSON.stringify(targetUrl)};
|
|
5739
5774
|
var PROXY_PASSWORD=${JSON.stringify(password)};
|
|
5775
|
+
var PROXY_BASE_URL="";
|
|
5740
5776
|
var STRICT_OBSERVER_FREEZE=${JSON.stringify(strictObserverFreezeForRequest)};
|
|
5741
5777
|
var PARENT_URL_CHANNEL="vvveb-proxy-url";
|
|
5742
5778
|
window.__CONVERSION_EDITOR_ACTIVE__=true;
|
|
@@ -5787,7 +5823,7 @@ function shouldBlockEditorTracking(rawUrl){
|
|
|
5787
5823
|
var looksLikeHeartbeatPayload=hasViewportPing&&hasSessionIds;
|
|
5788
5824
|
var isCrossOriginCollector=host!==TARGET_HOSTNAME&&hasMarker(host,TRACKING_HOST_MARKERS)&&hasMarker(path,TRACKING_PATH_MARKERS);
|
|
5789
5825
|
var isSnowplowStylePath=path==="/i"||path.indexOf("/com.snowplowanalytics.snowplow/")!==-1||path.indexOf("/tp2")!==-1;
|
|
5790
|
-
var isTaboolaUnip=host==="trc-events.taboola.com"
|
|
5826
|
+
var isTaboolaUnip=host==="trc-events.taboola.com"&&/\\/log\\/\\d+\\/unip(?:\\/|$)/.test(path);
|
|
5791
5827
|
var isCollectApiPath=path==="/api/collect"||path.indexOf("/api/collect/")===0;
|
|
5792
5828
|
var isNbCollectorPath=path==="/nb-collector"||path.indexOf("/nb-collector/")===0;
|
|
5793
5829
|
return isCrossOriginCollector||(looksLikeHeartbeatPayload&&isSnowplowStylePath)||isCollectApiPath||isTaboolaUnip||isNbCollectorPath;
|
|
@@ -5857,7 +5893,7 @@ try{window.addEventListener("popstate",notifyEditorUrlChanged,true);}catch(_){}
|
|
|
5857
5893
|
try{window.addEventListener("hashchange",notifyEditorUrlChanged,true);}catch(_){}
|
|
5858
5894
|
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
5859
5895
|
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;}}
|
|
5860
|
-
function toProxy(raw){if(isSkippable(raw))return null;var abs=toAbsolute(raw);if(!abs||typeof abs!=="string")return null;try{var parsed=new URL(abs);if(parsed.origin!==TARGET_ORIGIN)return null;
|
|
5896
|
+
function toProxy(raw){if(isSkippable(raw))return null;var abs=toAbsolute(raw);if(!abs||typeof abs!=="string")return null;try{var parsed=new URL(abs);if(parsed.origin!==TARGET_ORIGIN)return null;var root="/api/conversion-proxy";return root+"?password="+encodeURIComponent(PROXY_PASSWORD||"")+"&url="+encodeURIComponent(parsed.toString());}catch(_){return null;}}
|
|
5861
5897
|
var nativeAssign=window.location.assign?window.location.assign.bind(window.location):null;
|
|
5862
5898
|
var nativeReplace=window.location.replace?window.location.replace.bind(window.location):null;
|
|
5863
5899
|
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;}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@accelerated-agency/visual-editor",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Conversion visual editor as a reusable React package",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"clean": "rm -rf dist",
|
|
27
27
|
"build": "tsup",
|
|
28
28
|
"local:build": "tsup && yarn --cwd ../codebase-server clean && yarn --cwd ../codebase-server dev",
|
|
29
|
-
"watch": "tsup --watch"
|
|
29
|
+
"watch": "tsup --watch",
|
|
30
|
+
"deploy:worker": "wrangler deploy"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
33
|
"react": ">=18",
|