'use strict' 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({ 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) .then(function (contents_buffer) { let iframe = document.createElement('iframe') iframe.style = 'width: 100%; height: 100%; border: 0; overflow: hidden' // 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) }) }) }) } } module.exports = App App()