diff --git a/README.md b/README.md index f3902b8..89b1a5d 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,9 @@ browser. ### Production TODO + + +### Compatibility + +So far, this is only tested in Firefox 57 on Linux. If you have success or +issues on other browsers, please let me know. diff --git a/src/index.js b/src/index.js index f103117..1212d23 100644 --- a/src/index.js +++ b/src/index.js @@ -2,25 +2,74 @@ const IPFS = require('ipfs') + +function materialize_references_to_ipfs_content(node, element) { + // Given an IPFS node and a DOM element with a relevant attribute referring to content on IPFS, + // load that content and set it into the attribute as a blob. + // + // Return a promise for doing all of that. + // TODO: Support
rewriting. + for (let attribute_name of ['content', 'href', 'src']) { + let attribute_value = element.getAttribute(attribute_name) + if (attribute_value && attribute_value.startsWith('./')) { + let base_hash = window.location.pathname.match(/(^\/ipfs\/\w+)/)[1] + let uri = base_hash + attribute_value.slice(1) + let anchor = document.createElement('a') + anchor.href = uri + console.log('loading IPFS sub-content for ' + anchor.pathname) + + return node.files.cat(anchor.pathname).then(function (contents_buffer) { + element.setAttribute(attribute_name, URL.createObjectURL(new Blob([contents_buffer]))) + }) + } + } +} + + function App() { let node create() function create() { - node = new IPFS() + node = new IPFS({ + config: { + Addresses: { + Swarm: [ +// '/dns4/wrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star' + ] + } + } + }) node.on('ready', () => { console.log('IPFS node is ready') console.log('loading IPFS content for ' + window.location.pathname) // Load the page contents for the IPFS hash. - node.files.cat(window.location.pathname, (err, file) => { - if (err) { throw err } - var iframe = document.createElement('iframe') + node.files.cat(window.location.pathname) + .then(function (contents_buffer) { + let iframe = document.createElement('iframe') iframe.style = 'width: 100%; height: 100%; border: 0; overflow: hidden' - iframe.src = URL.createObjectURL(new Blob([file])) - document.body.appendChild(iframe) + + // TODO: Should only do this if it's actually an HTML document. Need to gracefully skip this for other content types. + let contents_document = new DOMParser().parseFromString(contents_buffer.toString(), 'text/html') + let elements = contents_document.querySelectorAll('link,meta,script') + let promises = [] + + for (let element of elements) { + promises.push(materialize_references_to_ipfs_content(node, element)) + } + + Promise.all(promises).then(function () { + iframe.src = URL.createObjectURL( + new Blob([ + new XMLSerializer().serializeToString(contents_document) + ]) + ) + + document.body.appendChild(iframe) + }) }) }) }