feat(browser): add Google iframe browser app
This commit is contained in:
1 parent
27292095a3
commit
93d0487617
13 files changed
+141
-23
No files matched your search
+21
-2
@@ -40,6 +40,7 @@ for (const [, inlineScript] of source.matchAll(/<script>([\s\S]*?)<\/script>/g))
|
||||
assert.doesNotMatch(source, /localizeDynamicText|createTreeWalker|NodeFilter\.SHOW_TEXT|const ZH=/);
|
||||
assert.match(source, /id==='system'\)window\.systemApp\(c\)/);
|
||||
assert.match(source, /id==='today'\)window\.today\(c\)/);
|
||||
assert.match(source, /id==='browser'\)window\.browserApp\(c\)/);
|
||||
assert.match(assets.i18nJs, /window\.setLanguage = setLanguage/);
|
||||
assert.match(assets.i18nRenderersJs, /window\.renderAll\(\)/);
|
||||
assert.match(assets.indexHtml, /setTimeout\(\(\)=>window\.applyLanguage\?\.\(\),0\)/, "missing locale UI code cannot abort desktop initialization");
|
||||
@@ -47,11 +48,29 @@ assert.doesNotMatch(assets.indexHtml, /setTimeout\(applyLanguage\s*,/);
|
||||
assert.doesNotMatch(assets.addonsJs, /(?<![\w.])applyLanguage\s*\(/, "add-on actions must not call a missing global locale function");
|
||||
assert.match(assets.indexHtml, /window\.renderIcons=renderIcons;window\.renderAll=renderAll/, "shared renderers are explicitly exposed to locale scripts");
|
||||
const shippedScripts = [...assets.indexHtml.matchAll(/<script>([\s\S]*?)<\/script>/g)].map(match => match[1]);
|
||||
assert.equal(shippedScripts.length, 12, "the complete desktop script chain is present in the served HTML");
|
||||
assert.equal(shippedScripts.length, 13, "the complete desktop script chain is present in the served HTML");
|
||||
assert.doesNotMatch(assets.indexHtml, /<script\s+src=/, "the desktop cannot silently fall back when an app script fails to load");
|
||||
assert.ok(assets.indexHtml.indexOf('window.systemApp =') < assets.indexHtml.lastIndexOf("window.init()"), "locale renderers run before desktop initialization");
|
||||
for (const script of shippedScripts) new vm.Script(script);
|
||||
for (const script of [assets.i18nJs, assets.tasksJs, assets.calendarJs, assets.i18nRenderersJs, assets.desktopPersonalizationJs, assets.desktopWidgetsJs, assets.addonsJs]) new vm.Script(script);
|
||||
for (const script of [assets.i18nJs, assets.tasksJs, assets.calendarJs, assets.i18nRenderersJs, assets.desktopPersonalizationJs, assets.desktopWidgetsJs, assets.browserAppJs, assets.addonsJs]) new vm.Script(script);
|
||||
const browserNodes = Object.fromEntries(['.browser-toolbar', '.browser-address', 'iframe', '[data-action="back"]', '[data-action="forward"]', '.browser-external', '.browser-hint-link'].map(key => [key, { value: '', href: '', disabled: false, listeners: {}, addEventListener(type, handler) { this.listeners[type] = handler; }, getAttribute(name) { return this[name] ?? null; } }]));
|
||||
const browserContainer = { dataset: {}, innerHTML: '', querySelector(selector) { return selector === '.browser-shell' ? (this.innerHTML ? {} : null) : browserNodes[selector]; } };
|
||||
const browserMessages = [];
|
||||
const browserContext = vm.createContext({ document: { activeElement: null, querySelector: () => browserContainer, createElement: () => ({}), head: { append() {} } }, LifeI18n: { t: key => key }, lang: () => 'en', toast: message => browserMessages.push(message), URL });
|
||||
browserContext.window = browserContext;
|
||||
vm.runInContext(assets.browserAppJs, browserContext);
|
||||
browserContext.browserApp(browserContainer);
|
||||
assert.equal(browserNodes.iframe.src, 'https://www.google.com/webhp?igu=1', 'the default embedded page is Google');
|
||||
browserNodes['.browser-address'].value = 'example.org/path';
|
||||
browserNodes['.browser-toolbar'].listeners.submit({ preventDefault() {} });
|
||||
assert.equal(browserNodes.iframe.src, 'https://example.org/path');
|
||||
assert.equal(browserNodes['.browser-hint-link'].href, 'https://example.org/path');
|
||||
browserNodes['.browser-address'].value = 'javascript:alert(1)';
|
||||
browserNodes['.browser-toolbar'].listeners.submit({ preventDefault() {} });
|
||||
assert.equal(browserNodes.iframe.src, 'https://example.org/path', 'unsafe schemes do not navigate');
|
||||
assert.equal(browserMessages.at(-1), 'browser.invalid');
|
||||
browserNodes['.browser-toolbar'].listeners.click({ target: { closest: () => ({ dataset: { action: 'back' } }) } });
|
||||
assert.equal(browserNodes.iframe.src, 'https://www.google.com/webhp?igu=1');
|
||||
assert.doesNotMatch(source, /Version 0\.1|Schema v1/);
|
||||
const makeStorage = initial => {
|
||||
const values = new Map(Object.entries(initial || {}));
|
||||
|
||||
Reference in new issue
Block a user