diff options
author | Valérian Galliat <val@codejam.info> | 2015-09-10 18:34:07 +0300 |
---|---|---|
committer | Valérian Galliat <val@codejam.info> | 2015-12-22 22:01:07 +0300 |
commit | 41dc75b8e7420297043d2fb294ce334a498498df (patch) | |
tree | 0a7723c1add60a8e1fbd4c6250e7279271dbf905 /lib | |
parent | 76127d2d869d6260faab448cedc484ede7f9770d (diff) |
Implement 'render-to' method
* Update 'handle' (previously 'append-to') to take a 'getElem' function
instead of directly a root element, allowing to custimize the element
injection method, and without directly manipulating the DOM.
* Reimplement 'append-to' using abstract 'handle' method.
* Implement a 'render-to' method to render a torrent inside an existing
element.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/append-to.js | 35 | ||||
-rw-r--r-- | lib/file.js | 12 | ||||
-rw-r--r-- | lib/render-to.js | 17 | ||||
-rw-r--r-- | lib/render.js | 60 |
4 files changed, 85 insertions, 39 deletions
diff --git a/lib/append-to.js b/lib/append-to.js new file mode 100644 index 0000000..672d711 --- /dev/null +++ b/lib/append-to.js @@ -0,0 +1,35 @@ +var render = require('./render') + +module.exports = function appendTo (file, rootElem, cb) { + if (rootElem && (rootElem.nodeName === 'VIDEO' || rootElem.nodeName === 'AUDIO')) { + throw new Error( + 'Invalid video/audio node argument. Argument must be root element that ' + + 'video/audio tag will be appended to.' + ) + } + + render(file, function (tagName) { + if (tagName === 'video' || tagName === 'audio') return createMedia(tagName) + else return createElem(tagName) + }, function (err, elem) { + if (err && elem) { + elem.remove() + } + + cb(err, elem) + }) + + function createMedia (tagName) { + var elem = createElem(tagName) + elem.controls = true + elem.autoplay = true // for chrome + elem.play() // for firefox + return elem + } + + function createElem (tagName) { + var elem = document.createElement(tagName) + rootElem.appendChild(elem) + return elem + } +} diff --git a/lib/file.js b/lib/file.js index 340ff37..09d3af8 100644 --- a/lib/file.js +++ b/lib/file.js @@ -1,6 +1,7 @@ module.exports = File var appendTo = require('./append-to') +var renderTo = require('./render-to') var eos = require('end-of-stream') var EventEmitter = require('events').EventEmitter var FileStream = require('./file-stream') @@ -130,3 +131,14 @@ File.prototype.appendTo = function (elem, cb) { if (typeof elem === 'string') elem = document.querySelector(elem) appendTo(this, elem, cb) } + +/** + * Render the file in an existing DOM element. + * @param {Element|string} elem + * @param {function} cb + */ +File.prototype.renderTo = function (elem, cb) { + if (typeof window === 'undefined') throw new Error('browser-only method') + if (typeof elem === 'string') elem = document.querySelector(elem) + renderTo(this, elem, cb) +} diff --git a/lib/render-to.js b/lib/render-to.js new file mode 100644 index 0000000..d2b47cc --- /dev/null +++ b/lib/render-to.js @@ -0,0 +1,17 @@ +var path = require('path') +var render = require('./render') + +module.exports = function renderTo (file, elem, cb) { + render(file, function (tagName) { + if (elem.nodeName !== tagName.toUpperCase()) { + var extname = path.extname(file.name).toLowerCase() + + throw new Error( + 'Cannot render "' + extname + '" inside a "' + + elem.nodeName.toLowerCase() + '" element, expected "' + tagName + '"' + ) + } + + return elem + }, cb) +} diff --git a/lib/render.js b/lib/render.js index c68e3f9..84c3a29 100644 --- a/lib/render.js +++ b/lib/render.js @@ -1,4 +1,4 @@ -var debug = require('debug')('webtorrent:append-to') +var debug = require('debug')('webtorrent:render') var MediaSourceStream = require('mediasource') var path = require('path') var videostream = require('videostream') @@ -15,26 +15,19 @@ var IFRAME_EXTS = [ '.css', '.html', '.js', '.md', '.pdf', '.txt' ] var MediaSource = typeof window !== 'undefined' && window.MediaSource -module.exports = function appendTo (file, rootElem, cb) { +module.exports = function render (file, getElem, cb) { if (!cb) cb = noop var elem var extname = path.extname(file.name).toLowerCase() var currentTime = 0 - if (rootElem && (rootElem.nodeName === 'VIDEO' || rootElem.nodeName === 'AUDIO')) { - throw new Error( - 'Invalid video/audio node argument. Argument must be root element that ' + - 'video/audio tag will be appended to.' - ) - } - - if (MEDIASOURCE_EXTS.indexOf(extname) >= 0) appendToMediaSource() - else if (AUDIO_EXTS.indexOf(extname) >= 0) appendToAudio() - else if (IMAGE_EXTS.indexOf(extname) >= 0) appendToImage() - else if (IFRAME_EXTS.indexOf(extname) >= 0) appendToIframe() + if (MEDIASOURCE_EXTS.indexOf(extname) >= 0) renderMediaSource() + else if (AUDIO_EXTS.indexOf(extname) >= 0) renderAudio() + else if (IMAGE_EXTS.indexOf(extname) >= 0) renderImage() + else if (IFRAME_EXTS.indexOf(extname) >= 0) renderIframe() else nextTick(cb, new Error('Unsupported file type "' + extname + '": Cannot append to DOM')) - function appendToMediaSource () { + function renderMediaSource () { if (!MediaSource) { return nextTick(cb, new Error( 'Video/audio streaming is not supported in your browser. You can still share ' + @@ -50,7 +43,7 @@ module.exports = function appendTo (file, rootElem, cb) { function useVideostream () { debug('Use `videostream` package for ' + file.name) - createElem() + prepareElem() elem.addEventListener('error', fallbackToMediaSource) elem.addEventListener('playing', onPlaying) videostream(file, elem) @@ -58,7 +51,7 @@ module.exports = function appendTo (file, rootElem, cb) { function useMediaSource () { debug('Use MediaSource API for ' + file.name) - createElem() + prepareElem() elem.addEventListener('error', fallbackToBlobURL) elem.addEventListener('playing', onPlaying) @@ -68,7 +61,7 @@ module.exports = function appendTo (file, rootElem, cb) { function useBlobURL () { debug('Use Blob URL for ' + file.name) - createElem() + prepareElem() elem.addEventListener('error', fatalError) elem.addEventListener('playing', onPlaying) file.getBlobURL(function (err, url) { @@ -94,18 +87,13 @@ module.exports = function appendTo (file, rootElem, cb) { useBlobURL() } - function createElem (time) { + function prepareElem () { if (!elem) { - elem = document.createElement(tagName) - elem.controls = true - elem.autoplay = true // for chrome - elem.play() // for firefox + elem = getElem(tagName) elem.addEventListener('progress', function () { currentTime = elem.currentTime }) - - rootElem.appendChild(elem) } } } @@ -115,45 +103,39 @@ module.exports = function appendTo (file, rootElem, cb) { cb(null, elem) } - function appendToAudio () { - elem = document.createElement('audio') - elem.controls = true - elem.autoplay = true - rootElem.appendChild(elem) + function renderAudio () { + elem = getElem('audio') file.getBlobURL(function (err, url) { if (err) return fatalError(err) elem.addEventListener('error', fatalError) elem.addEventListener('playing', onPlaying) elem.src = url - elem.play() }) } - function appendToImage () { + function renderImage () { + elem = getElem('img') file.getBlobURL(function (err, url) { if (err) return fatalError(err) - elem = document.createElement('img') elem.src = url elem.alt = file.name - rootElem.appendChild(elem) - cb(null, elem) + cb(null) }) } - function appendToIframe () { + function renderIframe () { + elem = getElem('iframe') + file.getBlobURL(function (err, url) { if (err) return fatalError(err) - elem = document.createElement('iframe') elem.src = url if (extname !== '.pdf') elem.sandbox = 'allow-forms allow-scripts' - rootElem.appendChild(elem) cb(null, elem) }) } function fatalError (err) { - if (elem) elem.remove() - err.message = 'Error appending file "' + file.name + '" to DOM: ' + err.message + err.message = 'Error rendering file "' + file.name + '": ' + err.message debug(err.message) if (cb) cb(err) } |