Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Commit

Permalink
webtorrent integration demo
Browse files Browse the repository at this point in the history
  • Loading branch information
dcposch authored and bbondy committed Nov 22, 2016
1 parent 8b6dada commit eb004bd
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 17 deletions.
8 changes: 7 additions & 1 deletion app/extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ let generateBraveManifest = () => {
'form-action': '\'none\'',
'referrer': 'no-referrer',
'style-src': '\'self\' \'unsafe-inline\'',
'img-src': '* data:',
'img-src': '* data: blob:',
'frame-src': '\'self\' https://buy.coinbase.com'
}

Expand All @@ -137,6 +137,12 @@ let generateBraveManifest = () => {
cspDirectives['style-src'] = '\'self\' \'unsafe-inline\' http://' + devServer
}

// TODO:
// * Move WebTorrent to its own renderer process, similar to the way it's done in
// WebTorrent Desktop
// * Remove this CSP exception:
cspDirectives['connect-src'] = '*'

var csp = ''
for (var directive in cspDirectives) {
csp += directive + ' ' + cspDirectives[directive] + '; '
Expand Down
9 changes: 9 additions & 0 deletions app/extensions/brave/ext/webtorrent.min.js

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions app/extensions/brave/js/webtorrent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(function () {
var queryString = window.location.search

let webtorrentEntryPage = 'gen/webtorrentPage.entry.js'

chrome.ipc.on('language', (e, detail) => {
document.l10n.requestLanguages([detail.langCode])
document.getElementsByName('availableLanguages')[0].content = detail.languageCodes.join(', ')
})

window.addEventListener('load', function () {
var po = document.createElement('script')
po.async = true
po.src = webtorrentEntryPage
var s = document.getElementsByTagName('script')[0]
s.parentNode.insertBefore(po, s)
chrome.ipc.send('request-language')
})
})()
20 changes: 20 additions & 0 deletions app/extensions/brave/webtorrent.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
<meta charset="utf-8">
<meta name="availableLanguages" content="">
<meta name="defaultLanguage" content="en-US">
<link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
<title data-l10n-id="webtorrentPage"></title>
<script src='ext/webtorrent.min.js'></script>
<script src='js/webtorrent.js'></script>
<script src="ext/l20n.min.js" async></script>
<link rel="localization" href="locales/{locale}/app.properties">
</head>
<body>
<div id="appContainer" />
</body>
</html>
8 changes: 6 additions & 2 deletions js/components/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const debounce = require('../lib/debounce')
const getSetting = require('../settings').getSetting
const config = require('../constants/config')
const settings = require('../constants/settings')
const {aboutUrls, isSourceAboutUrl, isTargetAboutUrl, getTargetAboutUrl, getBaseUrl, isIntermediateAboutPage} = require('../lib/appUrlUtil')
const {aboutUrls, isSourceMagnetUrl, getTargetMagnetUrl, isSourceAboutUrl, isTargetAboutUrl, getTargetAboutUrl, getBaseUrl, isIntermediateAboutPage} = require('../lib/appUrlUtil')
const {isFrameError} = require('../../app/common/lib/httpUtil')
const locale = require('../l10n')
const appConfig = require('../constants/appConfig')
Expand Down Expand Up @@ -319,7 +319,11 @@ class Frame extends ImmutableComponent {
}

if (!guestInstanceId || newSrc !== 'about:blank') {
this.webview.setAttribute('src', isSourceAboutUrl(newSrc) ? getTargetAboutUrl(newSrc) : newSrc)
let webviewSrc
if (isSourceAboutUrl(newSrc)) webviewSrc = getTargetAboutUrl(newSrc)
else if (isSourceMagnetUrl(newSrc)) webviewSrc = getTargetMagnetUrl(newSrc)
else webviewSrc = newSrc
this.webview.setAttribute('src', webviewSrc)
}

if (webviewAdded) {
Expand Down
28 changes: 23 additions & 5 deletions js/lib/appUrlUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,32 @@ module.exports.isSourceAboutUrl = function (input) {
return !!module.exports.getTargetAboutUrl(getBaseUrl(input))
}

/**
* Determines if the passed in string is the target of a source about: URL
* Example: isTargetAboutUrl('http://localhost:8000/about-blank/index.html') -> true
*/
module.exports.isTargetAboutUrl = function (input) {
return !!module.exports.getSourceAboutUrl(getBaseUrl(input))
}

// TODO: document

module.exports.getTargetMagnetUrl = function (input) {
if (!input.startsWith('magnet:?')) return null
const url = module.exports.getAppUrl('webtorrent.html')
return url + '#' + input
}

module.exports.getSourceMagnetUrl = function (input) {
const url = module.exports.getAppUrl('webtorrent.html')
if (!input.startsWith(url)) return null
return input.substring(input.indexOf('#') + 1)
}

module.exports.isSourceMagnetUrl = function (input) {
return !!module.exports.getTargetMagnetUrl(input)
}

module.exports.isTargetMagnetUrl = function (input) {
return !!module.exports.getSourceMagnetUrl(input)
}

/**
* Determines whether a string is a valid URL. Based on node-urlutil.js.
* @param {string} input
Expand All @@ -148,7 +166,7 @@ function getHash (input) {
return (typeof input === 'string') ? input.split('#')[1] : ''
}

module.exports.navigatableTypes = ['http:', 'https:', 'about:', 'chrome:', 'chrome-extension:', 'file:', 'view-source:', 'ftp:']
module.exports.navigatableTypes = ['http:', 'https:', 'about:', 'chrome:', 'chrome-extension:', 'file:', 'view-source:', 'ftp:', 'magnet:']

/**
* Determine the URL to use when creating a new tab
Expand Down
2 changes: 1 addition & 1 deletion js/lib/urlutil.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const UrlUtil = {
// for cases, pure string
const case3Reg = /[\?\.\/\s:]/
// for cases, data:uri, view-source:uri and about
const case4Reg = /^data:|view-source:|mailto:|about:|chrome-extension:.*/
const case4Reg = /^data:|view-source:|mailto:|about:|chrome-extension:|magnet:.*/

let str = input.trim()
let scheme = this.getScheme(str)
Expand Down
10 changes: 6 additions & 4 deletions js/stores/windowStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const urlParse = require('url').parse
const currentWindow = require('../../app/renderer/currentWindow')
const {tabFromFrame} = require('../state/frameStateUtil')
const {l10nErrorText} = require('../../app/common/lib/httpUtil')
const {aboutUrls, getSourceAboutUrl, isIntermediateAboutPage, navigatableTypes, newFrameUrl} = require('../lib/appUrlUtil')
const {aboutUrls, getSourceAboutUrl, isIntermediateAboutPage, getSourceMagnetUrl, navigatableTypes, newFrameUrl} = require('../lib/appUrlUtil')
const Serializer = require('../dispatcher/serializer')

let windowState = Immutable.fromJS({
Expand Down Expand Up @@ -281,8 +281,8 @@ const doAction = (action) => {
})
updateNavBarInput(frame.get('location'), frameStatePath(action.key))
} else {
// If the user is changing back to the original src and they already navigated away then we need to
// explicitly set a new location via webview.loadURL.
// If the user is changing back to the original src and they already navigated away then we need to
// explicitly set a new location via webview.loadURL.
let activeShortcut
if (frame.get('location') !== action.location &&
frame.get('src') === action.location &&
Expand All @@ -308,7 +308,9 @@ const doAction = (action) => {
windowState = windowState.setIn(activeFrameStatePath().concat(['navbar', 'urlbar', 'suggestions', 'shouldRender']), false)
// For about: URLs, make sure we store the URL as about:something
// and not what we map to.
action.location = getSourceAboutUrl(action.location) || action.location
action.location = getSourceAboutUrl(action.location) ||
getSourceMagnetUrl(action.location) ||
action.location

if (UrlUtil.isURL(action.location)) {
action.location = UrlUtil.getUrlFromInput(action.location)
Expand Down
68 changes: 68 additions & 0 deletions js/webtorrent/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const ReactDOM = require('react-dom')
var WebTorrent = window.WebTorrent // require('webtorrent')

var state = {
torrentId: window.location.hash.substring(1),
progress: 0,
files: [],
errorMessage: ''
}

// Start downloading the torrent
var client = new WebTorrent()
window.client = client
state.torrent = client.add(state.torrentId)
client.on('error', onError)

// Show download progress
setInterval(update, 1000)

function update () {
var torrent = state.torrent

var status
if (!torrent.infoHash) {
status = 'Loading torrent information...'
} else if (torrent.progress < 1) {
status = 'Downloading ' + (torrent.name || '...')
} else {
status = 'Done!'
}

var elem = (
<div>
<h1>{status}</h1>
<h3>Progress: {(torrent.progress * 100).toFixed(1)}%</h3>
<h3>Files</h3>
<ul>
{torrent.files.map((file, i) => {
var isSelected = i === state.selectedFileIndex
return (
<li data-ix={i} class={isSelected && 'selected'} onClick={onClickFile}>
{file.name}
</li>
)
})}
</ul>
<div id='fileContainer' />
<div class='error'>{state.errorMessage}</div>
</div>
)
ReactDOM.render(elem, document.querySelector('#appContainer'))
}

function onClickFile (e) {
if (state.selectedFileIndex === e.target.dataset.ix) return
state.selectedFileIndex = e.target.dataset.ix

update()

var fileContainer = document.querySelector('#fileContainer')
fileContainer.innerHTML = ''
var file = state.torrent.files[state.selectedFileIndex]
file.appendTo(fileContainer)
}

function onError (err) {
state.errorMessage = err.message
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@
"tldjs": "1.6.2",
"tracking-protection": "1.1.x",
"underscore": "1.8.3",
"url-loader": "^0.5.7"
"url-loader": "^0.5.7",
"webtorrent": "^0.97.2"
},
"devDependencies": {
"asar": "^0.11.0",
Expand Down
20 changes: 17 additions & 3 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,31 @@ var aboutPages = {
}
}

var webtorrentPage = {
name: 'webtorrent',
target: 'web',
entry: ['./js/webtorrent/entry.js'],
output: {
path: path.resolve(__dirname, 'app', 'extensions', 'brave', 'gen'),
filename: 'webtorrentPage.entry.js',
publicPath: './gen/'
}
}

module.exports = {
development: [
merge(app, development()),
merge(aboutPages, development())
merge(aboutPages, development()),
merge(webtorrentPage, development())
],
production: [
merge(app, production()),
merge(aboutPages, production())
merge(aboutPages, production()),
merge(webtorrentPage, production())
],
test: [
merge(app, production()),
merge(aboutPages, production())
merge(aboutPages, production()),
merge(webtorrentPage, production())
]
}[env]

0 comments on commit eb004bd

Please sign in to comment.