diff --git a/package.json b/package.json index 0d706aa2ca..7f74301f7e 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "exokit-home": "0.0.70", "fake-indexeddb": "^2.0.4", "fault-zone": "0.0.20", + "favicon-get": "0.0.2", "he": "^1.1.1", "history": "^4.7.2", "hterm-repl": "0.0.10", diff --git a/src/core.js b/src/core.js index de98512f3b..0aec99edfc 100644 --- a/src/core.js +++ b/src/core.js @@ -12,6 +12,8 @@ const {URL} = url; const {performance} = require('perf_hooks'); const mkdirp = require('mkdirp'); +const parse5 = require('parse5'); +const selector = require('window-selector'); const {XMLHttpRequest: XMLHttpRequestBase, FormData} = require('window-xhr'); @@ -628,7 +630,7 @@ const _fromAST = (node, window, parentNode, ownerDocument, uppercase) => { tagName = tagName.toUpperCase(); } let {attrs, value, content, childNodes, sourceCodeLocation} = node; - const HTMLElementTemplate = window[symbols.htmlTagsSymbol][tagName]; + const HTMLElementTemplate = window && window[symbols.htmlTagsSymbol][tagName]; const location = sourceCodeLocation ? { line: sourceCodeLocation.startLine, col: sourceCodeLocation.startCol, @@ -1266,7 +1268,36 @@ const _makeWindow = (options = {}, parent = null, top = null) => { } return styleSpec.style; }; + const gwf = require('favicon-get'); + // const gwf = require('/home/a/favicon-get'); + const querySelectorAll = (document, s) => { + s = s + ''; + return selector.find({ + traverse: fn => { + for (let i = 0; i < document.childNodes.length; i++) { + document.childNodes[i].traverse(fn); + } + }, + }, s); + }; window.browser = { + favicon: u => gwf(u, async u => { + const res = await fetch(u); + if (res.ok) { + const text = await res.text(); + let document = parse5.parse(text) + const ownerDocument = { + defaultView: { + Element: window.Element, + }, + }; + document = GlobalContext._fromAST(document, null, null, ownerDocument, true); + document.baseURI = u; // XXX is this correct? + return document; + } else { + throw new Error(`invalid status code: ${res.status}`); + } + }, fetch, querySelectorAll), devTools: DevTools, http: (() => { const httpProxy = {};