Better support for loading HTML pages plus some of their referenced content.
This commit is contained in:
parent
d66c456cf1
commit
c033769279
|
@ -39,3 +39,9 @@ browser.
|
||||||
### Production
|
### Production
|
||||||
|
|
||||||
TODO
|
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.
|
||||||
|
|
61
src/index.js
61
src/index.js
|
@ -2,25 +2,74 @@
|
||||||
|
|
||||||
const IPFS = require('ipfs')
|
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 <div style="background-image: url(./styles/img/main/alpha-sunrise.png);"> 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() {
|
function App() {
|
||||||
let node
|
let node
|
||||||
|
|
||||||
create()
|
create()
|
||||||
|
|
||||||
function 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', () => {
|
node.on('ready', () => {
|
||||||
console.log('IPFS node is ready')
|
console.log('IPFS node is ready')
|
||||||
console.log('loading IPFS content for ' + window.location.pathname)
|
console.log('loading IPFS content for ' + window.location.pathname)
|
||||||
|
|
||||||
// Load the page contents for the IPFS hash.
|
// Load the page contents for the IPFS hash.
|
||||||
node.files.cat(window.location.pathname, (err, file) => {
|
node.files.cat(window.location.pathname)
|
||||||
if (err) { throw err }
|
.then(function (contents_buffer) {
|
||||||
var iframe = document.createElement('iframe')
|
let iframe = document.createElement('iframe')
|
||||||
iframe.style = 'width: 100%; height: 100%; border: 0; overflow: hidden'
|
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)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue