gwchq-textjam 0.2.30 → 0.2.31
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 +56 -115
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -369284,7 +369284,6 @@ const node_html_parser_1 = __webpack_require__(36192);
|
|
|
369284
369284
|
const classnames_1 = __importDefault(__webpack_require__(46942));
|
|
369285
369285
|
const react_router_dom_1 = __webpack_require__(92648);
|
|
369286
369286
|
const EditorSlice_1 = __webpack_require__(68512);
|
|
369287
|
-
const externalLinkHelper_1 = __webpack_require__(31615);
|
|
369288
369287
|
const open_in_new_tab_svg_1 = __importDefault(__webpack_require__(86936));
|
|
369289
369288
|
const stores_1 = __webpack_require__(32132);
|
|
369290
369289
|
const ProjectTypes_1 = __webpack_require__(27130);
|
|
@@ -369370,29 +369369,22 @@ function HtmlRunner() {
|
|
|
369370
369369
|
};
|
|
369371
369370
|
}
|
|
369372
369371
|
}, [isPreviewMode]);
|
|
369373
|
-
|
|
369374
|
-
|
|
369375
|
-
|
|
369376
|
-
|
|
369377
|
-
|
|
369378
|
-
|
|
369379
|
-
|
|
369380
|
-
|
|
369381
|
-
|
|
369382
|
-
|
|
369383
|
-
|
|
369384
|
-
|
|
369385
|
-
|
|
369386
|
-
}
|
|
369387
|
-
else {
|
|
369388
|
-
handleRegularExternalLink(event.data.payload.linkTo);
|
|
369389
|
-
}
|
|
369390
|
-
}
|
|
369391
|
-
});
|
|
369392
|
-
};
|
|
369372
|
+
(0, react_1.useEffect)(() => {
|
|
369373
|
+
const handleReloadMessage = (event) => {
|
|
369374
|
+
if (event.data?.msg !== "RELOAD")
|
|
369375
|
+
return;
|
|
369376
|
+
const nextPage = event.data?.payload?.linkTo;
|
|
369377
|
+
if (typeof nextPage !== "string")
|
|
369378
|
+
return;
|
|
369379
|
+
dispatch((0, EditorSlice_1.setPage)(nextPage));
|
|
369380
|
+
dispatch((0, EditorSlice_1.triggerCodeRun)());
|
|
369381
|
+
};
|
|
369382
|
+
window.addEventListener("message", handleReloadMessage);
|
|
369383
|
+
return () => window.removeEventListener("message", handleReloadMessage);
|
|
369384
|
+
}, [dispatch]);
|
|
369393
369385
|
const iframeReload = () => {
|
|
369394
369386
|
const iframe = output.current?.contentDocument;
|
|
369395
|
-
const filePath = (0, helpers_1.getFilenameFromIFrame)(iframe)
|
|
369387
|
+
const filePath = (0, helpers_1.getFilenameFromIFrame)(iframe);
|
|
369396
369388
|
if (runningFilePath !== filePath) {
|
|
369397
369389
|
setRunningFilePath(filePath);
|
|
369398
369390
|
}
|
|
@@ -369402,9 +369394,11 @@ function HtmlRunner() {
|
|
|
369402
369394
|
linkElement.addEventListener("click", (e) => {
|
|
369403
369395
|
const href = linkElement.getAttribute("href");
|
|
369404
369396
|
const target = linkElement.getAttribute("target");
|
|
369405
|
-
|
|
369397
|
+
if (!href || target !== "_blank" || (0, helpers_1.isExternalUrl)(href))
|
|
369398
|
+
return;
|
|
369399
|
+
// block in-iframe navigation for internal html links with target="_blank"
|
|
369406
369400
|
// and open them in a preview tab
|
|
369407
|
-
if (
|
|
369401
|
+
if (href?.includes(".html")) {
|
|
369408
369402
|
e.preventDefault();
|
|
369409
369403
|
e.stopImmediatePropagation();
|
|
369410
369404
|
openPreview(`/${href}`);
|
|
@@ -369412,10 +369406,8 @@ function HtmlRunner() {
|
|
|
369412
369406
|
}, true);
|
|
369413
369407
|
});
|
|
369414
369408
|
}
|
|
369415
|
-
setExternalLink(null);
|
|
369416
369409
|
};
|
|
369417
369410
|
(0, react_1.useEffect)(() => {
|
|
369418
|
-
eventListener();
|
|
369419
369411
|
dispatch((0, EditorSlice_1.loadingRunner)(EditorTypes_1.RunnerType.HTML));
|
|
369420
369412
|
dispatch((0, EditorSlice_1.setLoadedRunner)(EditorTypes_1.RunnerType.HTML));
|
|
369421
369413
|
}, []);
|
|
@@ -369440,39 +369432,31 @@ function HtmlRunner() {
|
|
|
369440
369432
|
const fileToRun = page ?? defaultPreviewFilePath;
|
|
369441
369433
|
setRunningFilePath(fileToRun);
|
|
369442
369434
|
dispatch((0, EditorSlice_1.setError)(null));
|
|
369443
|
-
|
|
369444
|
-
|
|
369445
|
-
|
|
369446
|
-
|
|
369447
|
-
|
|
369448
|
-
|
|
369449
|
-
|
|
369450
|
-
|
|
369451
|
-
|
|
369452
|
-
|
|
369453
|
-
:
|
|
369454
|
-
|
|
369455
|
-
|
|
369456
|
-
|
|
369457
|
-
return;
|
|
369458
|
-
}
|
|
369459
|
-
const indexPage = (0, node_html_parser_1.parse)(entryPoint.content);
|
|
369460
|
-
const body = indexPage.querySelector("body") || indexPage;
|
|
369461
|
-
const htmlRoot = indexPage.querySelector("html") ?? indexPage;
|
|
369462
|
-
body.insertAdjacentHTML("afterbegin", scripts_1.disableLocalStorageScript);
|
|
369463
|
-
htmlRoot.insertAdjacentHTML("afterbegin", scripts_1.consoleOverrideScript);
|
|
369464
|
-
const { content } = await (0, fileParsers_1.resolveAndRewriteHtmlImports)(indexPage.toString(), projectComponents, entryPoint.path, page ?? entryPoint.path);
|
|
369465
|
-
if (output.current) {
|
|
369466
|
-
output.current.srcdoc = content;
|
|
369467
|
-
}
|
|
369468
|
-
if (codeRunTriggered) {
|
|
369469
|
-
dispatch((0, EditorSlice_1.codeRunHandled)());
|
|
369470
|
-
}
|
|
369435
|
+
const entryPoint = (0, helpers_1.getEntryPoint)(projectComponents, fileToRun);
|
|
369436
|
+
if (!entryPoint) {
|
|
369437
|
+
dispatch((0, EditorSlice_1.setError)(fileToRun === helpers_1.DEFAULT_ENTRY_FILE_PATH && !isPreviewMode
|
|
369438
|
+
? {
|
|
369439
|
+
type: Errors_1.ErrorType.ENTRY_FILE_NOT_FOUND,
|
|
369440
|
+
details: {
|
|
369441
|
+
fileName: helpers_1.DEFAULT_ENTRY_FILE_NAME,
|
|
369442
|
+
},
|
|
369443
|
+
}
|
|
369444
|
+
: {
|
|
369445
|
+
type: Errors_1.ErrorType.PAGE_NOT_FOUND,
|
|
369446
|
+
}));
|
|
369447
|
+
dispatch((0, EditorSlice_1.codeRunHandled)());
|
|
369448
|
+
return;
|
|
369471
369449
|
}
|
|
369472
|
-
|
|
369473
|
-
|
|
369474
|
-
|
|
369475
|
-
|
|
369450
|
+
const indexPage = (0, node_html_parser_1.parse)(entryPoint.content);
|
|
369451
|
+
const body = indexPage.querySelector("body") || indexPage;
|
|
369452
|
+
const htmlRoot = indexPage.querySelector("html") ?? indexPage;
|
|
369453
|
+
body.insertAdjacentHTML("afterbegin", scripts_1.disableLocalStorageScript);
|
|
369454
|
+
htmlRoot.insertAdjacentHTML("afterbegin", scripts_1.consoleOverrideScript);
|
|
369455
|
+
const { content } = await (0, fileParsers_1.resolveAndRewriteHtmlImports)(indexPage.toString(), projectComponents, entryPoint.path, page ?? entryPoint.path);
|
|
369456
|
+
if (output.current) {
|
|
369457
|
+
output.current.srcdoc = content;
|
|
369458
|
+
}
|
|
369459
|
+
if (codeRunTriggered) {
|
|
369476
369460
|
dispatch((0, EditorSlice_1.codeRunHandled)());
|
|
369477
369461
|
}
|
|
369478
369462
|
};
|
|
@@ -369512,7 +369496,7 @@ function HtmlRunner() {
|
|
|
369512
369496
|
const iframeClasses = (0, classnames_1.default)(styles_module_scss_1.default.iframe, {
|
|
369513
369497
|
[styles_module_scss_1.default.codeHasBeenRun]: codeHasBeenRun,
|
|
369514
369498
|
});
|
|
369515
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.htmlrunnerContainer, children: [(0, jsx_runtime_1.jsx)(OutputTabPanel_1.OutputTabPanel, { title: "Preview", icon: preview_svg_1.default, readOnly: readOnly, extraTabContent: codeHasBeenRun && openInNewTabLink, tabPanelClassName: styles_module_scss_1.default.previewHtml, children: error ? ((0, jsx_runtime_1.jsx)("div", { className: iframeClasses, children: (0, jsx_runtime_1.jsx)(NotFoundPage_1.NotFoundPage, {}) })) : ((0, jsx_runtime_1.jsx)("iframe", { className: iframeClasses, sandbox: "allow-scripts allow-same-origin allow-modals allow-popups", referrerPolicy: "strict-origin-when-cross-origin", allow: "\n accelerometer 'none';\n camera 'none';\n encrypted-media;\n fullscreen;\n picture-in-picture;\n geolocation 'none';\n gyroscope 'none';\n magnetometer 'none';\n microphone 'none';\n midi 'none';\n payment 'none';\n usb 'none';\n ", id: "output-frame", title: "HTML Output Preview", ref: output, onLoad: iframeReload })) }), !isPreviewMode && ((0, jsx_runtime_1.jsx)(ResizableWithHandle_1.default, { "data-testid": "proj-console-container", handleDirection: "top", defaultHeight: "50%", className: styles_module_scss_1.default.resizeContainer, handleClassName: styles_module_scss_1.default.resizeHandleContainer, children: (0, jsx_runtime_1.jsx)(OutputTabPanel_1.OutputTabPanel, { title: "Console", icon: console_svg_1.default, readOnly: readOnly, children: (0, jsx_runtime_1.jsx)(HtmlConsole_1.default, { consoleLogs: consoleLogs }) }) }))] }));
|
|
369499
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.htmlrunnerContainer, children: [(0, jsx_runtime_1.jsx)(OutputTabPanel_1.OutputTabPanel, { title: "Preview", icon: preview_svg_1.default, readOnly: readOnly, extraTabContent: codeHasBeenRun && openInNewTabLink, tabPanelClassName: styles_module_scss_1.default.previewHtml, children: error ? ((0, jsx_runtime_1.jsx)("div", { className: iframeClasses, children: (0, jsx_runtime_1.jsx)(NotFoundPage_1.NotFoundPage, {}) })) : ((0, jsx_runtime_1.jsx)("iframe", { className: iframeClasses, sandbox: "allow-scripts allow-same-origin allow-modals allow-popups allow-popups-to-escape-sandbox", referrerPolicy: "strict-origin-when-cross-origin", allow: "\n accelerometer 'none';\n camera 'none';\n encrypted-media;\n fullscreen;\n picture-in-picture;\n geolocation 'none';\n gyroscope 'none';\n magnetometer 'none';\n microphone 'none';\n midi 'none';\n payment 'none';\n usb 'none';\n ", id: "output-frame", title: "HTML Output Preview", ref: output, onLoad: iframeReload })) }), !isPreviewMode && ((0, jsx_runtime_1.jsx)(ResizableWithHandle_1.default, { "data-testid": "proj-console-container", handleDirection: "top", defaultHeight: "50%", className: styles_module_scss_1.default.resizeContainer, handleClassName: styles_module_scss_1.default.resizeHandleContainer, children: (0, jsx_runtime_1.jsx)(OutputTabPanel_1.OutputTabPanel, { title: "Console", icon: console_svg_1.default, readOnly: readOnly, children: (0, jsx_runtime_1.jsx)(HtmlConsole_1.default, { consoleLogs: consoleLogs }) }) }))] }));
|
|
369516
369500
|
}
|
|
369517
369501
|
exports["default"] = HtmlRunner;
|
|
369518
369502
|
|
|
@@ -369591,6 +369575,7 @@ const node_html_parser_1 = __webpack_require__(36192);
|
|
|
369591
369575
|
const ProjectTypes_1 = __webpack_require__(27130);
|
|
369592
369576
|
const binaryStore_1 = __webpack_require__(5060);
|
|
369593
369577
|
const projectHelpers_1 = __webpack_require__(2610);
|
|
369578
|
+
const helpers_1 = __webpack_require__(1108);
|
|
369594
369579
|
/** Normalizes CSS paths
|
|
369595
369580
|
* Treats paths without leading / or ./ or ../ as relative to current file
|
|
369596
369581
|
* E.g. 'image.png' will be treated as './image.png'
|
|
@@ -369644,9 +369629,7 @@ const getMimeType = (filePath, fallback = "application/octet-stream") => {
|
|
|
369644
369629
|
};
|
|
369645
369630
|
/** Check if a URL is external, blob, or data */
|
|
369646
369631
|
const isExternalOrDataUrl = (url) => {
|
|
369647
|
-
return (url.startsWith("blob:") ||
|
|
369648
|
-
/^(https?:)?\/\//.test(url) ||
|
|
369649
|
-
url.startsWith("data:"));
|
|
369632
|
+
return (url.startsWith("blob:") || (0, helpers_1.isExternalUrl)(url) || url.startsWith("data:"));
|
|
369650
369633
|
};
|
|
369651
369634
|
async function replaceAsync(input, regex, replacer) {
|
|
369652
369635
|
let result = "";
|
|
@@ -369823,7 +369806,12 @@ async function rewriteSources(indexPage, components, baseFilePath, propName, blo
|
|
|
369823
369806
|
const nodes = indexPage.querySelectorAll(`[${propName}]`);
|
|
369824
369807
|
for (const node of nodes) {
|
|
369825
369808
|
const raw = node.getAttribute(propName);
|
|
369826
|
-
if (!raw
|
|
369809
|
+
if (!raw)
|
|
369810
|
+
continue;
|
|
369811
|
+
// For external links with target="_blank", add noopener and noreferrer for security
|
|
369812
|
+
if ((0, helpers_1.isExternalUrl)(raw) && node.getAttribute("target") === "_blank")
|
|
369813
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
369814
|
+
if (isExternalOrDataUrl(raw))
|
|
369827
369815
|
continue;
|
|
369828
369816
|
if ((0, projectHelpers_1.parseFileName)(raw).extension === ProjectTypes_1.ProjectFileExtension.HTML &&
|
|
369829
369817
|
propName === "href") {
|
|
@@ -369876,7 +369864,7 @@ async function resolveAndRewriteHtmlImports(html, projectComponents, baseFilePat
|
|
|
369876
369864
|
|
|
369877
369865
|
|
|
369878
369866
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
369879
|
-
exports.getFilenameFromIFrame = exports.getEntryPoint = exports.DEFAULT_ENTRY_FILE_PATH = exports.DEFAULT_ENTRY_FILE_NAME = void 0;
|
|
369867
|
+
exports.isExternalUrl = exports.getFilenameFromIFrame = exports.getEntryPoint = exports.DEFAULT_ENTRY_FILE_PATH = exports.DEFAULT_ENTRY_FILE_NAME = void 0;
|
|
369880
369868
|
const ProjectTypes_1 = __webpack_require__(27130);
|
|
369881
369869
|
exports.DEFAULT_ENTRY_FILE_NAME = "index.html";
|
|
369882
369870
|
exports.DEFAULT_ENTRY_FILE_PATH = `/${exports.DEFAULT_ENTRY_FILE_NAME}`;
|
|
@@ -369887,6 +369875,10 @@ const getEntryPoint = (components, filePath) => {
|
|
|
369887
369875
|
exports.getEntryPoint = getEntryPoint;
|
|
369888
369876
|
const getFilenameFromIFrame = (iframe) => iframe?.querySelector("meta[filename]")?.getAttribute("filename") ?? null;
|
|
369889
369877
|
exports.getFilenameFromIFrame = getFilenameFromIFrame;
|
|
369878
|
+
const isExternalUrl = (url) => {
|
|
369879
|
+
return /^(https?:)?\/\//.test(url);
|
|
369880
|
+
};
|
|
369881
|
+
exports.isExternalUrl = isExternalUrl;
|
|
369890
369882
|
|
|
369891
369883
|
|
|
369892
369884
|
/***/ }),
|
|
@@ -376667,57 +376659,6 @@ const downloadProjectFile = async (file, fileName) => {
|
|
|
376667
376659
|
exports.downloadProjectFile = downloadProjectFile;
|
|
376668
376660
|
|
|
376669
376661
|
|
|
376670
|
-
/***/ }),
|
|
376671
|
-
|
|
376672
|
-
/***/ 31615:
|
|
376673
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
376674
|
-
|
|
376675
|
-
|
|
376676
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
376677
|
-
exports.matchingRegexes = exports.allowedInternalLinks = exports.allowedExternalLinks = exports.useExternalLinkState = void 0;
|
|
376678
|
-
const react_1 = __webpack_require__(51649);
|
|
376679
|
-
const react_redux_1 = __webpack_require__(14062);
|
|
376680
|
-
const EditorSlice_1 = __webpack_require__(68512);
|
|
376681
|
-
const Errors_1 = __webpack_require__(20339);
|
|
376682
|
-
const domain = "https://rpf.io/";
|
|
376683
|
-
const host = window?.location?.origin || "http://localhost:3011";
|
|
376684
|
-
const rpfDomain = new RegExp(`^${domain}`);
|
|
376685
|
-
const hostDomain = new RegExp(`^${host}`);
|
|
376686
|
-
const allowedInternalLinks = [new RegExp(`^#[a-zA-Z0-9]+`)];
|
|
376687
|
-
exports.allowedInternalLinks = allowedInternalLinks;
|
|
376688
|
-
const allowedExternalLinks = [rpfDomain, hostDomain];
|
|
376689
|
-
exports.allowedExternalLinks = allowedExternalLinks;
|
|
376690
|
-
const useExternalLinkState = (showModal) => {
|
|
376691
|
-
const dispatch = (0, react_redux_1.useDispatch)();
|
|
376692
|
-
const [externalLink, setExternalLink] = (0, react_1.useState)(null);
|
|
376693
|
-
const handleAllowedExternalLink = (linkTo) => {
|
|
376694
|
-
setExternalLink(linkTo);
|
|
376695
|
-
dispatch((0, EditorSlice_1.triggerCodeRun)());
|
|
376696
|
-
};
|
|
376697
|
-
const handleRegularExternalLink = (linkTo) => {
|
|
376698
|
-
setExternalLink(null);
|
|
376699
|
-
dispatch((0, EditorSlice_1.setPage)(linkTo));
|
|
376700
|
-
dispatch((0, EditorSlice_1.triggerCodeRun)());
|
|
376701
|
-
};
|
|
376702
|
-
const handleExternalLinkError = () => {
|
|
376703
|
-
dispatch((0, EditorSlice_1.setError)({ type: Errors_1.ErrorType.EXTERNAL_LINK }));
|
|
376704
|
-
showModal();
|
|
376705
|
-
};
|
|
376706
|
-
return {
|
|
376707
|
-
externalLink,
|
|
376708
|
-
setExternalLink,
|
|
376709
|
-
handleAllowedExternalLink,
|
|
376710
|
-
handleRegularExternalLink,
|
|
376711
|
-
handleExternalLinkError,
|
|
376712
|
-
};
|
|
376713
|
-
};
|
|
376714
|
-
exports.useExternalLinkState = useExternalLinkState;
|
|
376715
|
-
const matchingRegexes = (regexArray, testString) => {
|
|
376716
|
-
return regexArray.some((reg) => reg.test(testString));
|
|
376717
|
-
};
|
|
376718
|
-
exports.matchingRegexes = matchingRegexes;
|
|
376719
|
-
|
|
376720
|
-
|
|
376721
376662
|
/***/ }),
|
|
376722
376663
|
|
|
376723
376664
|
/***/ 65404:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gwchq-textjam",
|
|
3
3
|
"description": "Embeddable React editor used in Raspberry Pi text-based projects.",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.31",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/GirlsFirst/gwchq-textjam",
|
|
7
7
|
"author": "Girls Who Code HQ",
|