85 lines
2.9 KiB
JavaScript
85 lines
2.9 KiB
JavaScript
'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.
|
|
for (let attribute_name of ['content', 'href', 'src', 'style']) {
|
|
let attribute_value = element.getAttribute(attribute_name)
|
|
|
|
if (attribute_value && attribute_value.includes('./')) {
|
|
let base_hash = window.location.pathname.match(/(^\/ipfs\/\w+)/)[1]
|
|
let anchor = document.createElement('a')
|
|
let relative_url = attribute_value.match(/(.\/[^)]+)/)[1]
|
|
anchor.href = base_hash + relative_url.slice(1)
|
|
console.log('loading IPFS sub-content for ' + anchor.pathname)
|
|
|
|
return node.files.cat(anchor.pathname).then(function (contents_buffer) {
|
|
let materialized_value = attribute_value.replace(
|
|
relative_url,
|
|
URL.createObjectURL(new Blob([contents_buffer]))
|
|
)
|
|
element.setAttribute(attribute_name, materialized_value)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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,div')
|
|
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()
|