<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="google" content="notranslate"> <meta http-equiv="Content-Language" content="en"> <title>contentscript.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> <script src="scripts/semantic.min.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc.css"> <link type="text/css" rel="stylesheet" href="styles/semantic.min.css"> <link type="text/css" rel="stylesheet" href="styles/override.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><div class="ui vertical accordion"><div class="title"><div class="ui list"><div class="item"><i class="dropdown icon"></i><a href="ComposableObservableStore.html">ComposableObservableStore</a></div></div></div><div class="content"><ul class='methods'><li data-type='method'><a href="ComposableObservableStore.html#getFlatState">getFlatState</a></li><li data-type='method'><a href="ComposableObservableStore.html#updateStructure">updateStructure</a></li></ul></div></li></div><div class="ui vertical accordion"><div class="title"><div class="ui list"><div class="item"><i class="dropdown icon"></i><a href="EdgeEncryptor.html">EdgeEncryptor</a></div></div></div><div class="content"><ul class='methods'><li data-type='method'><a href="EdgeEncryptor.html#decrypt">decrypt</a></li><li data-type='method'><a href="EdgeEncryptor.html#encrypt">encrypt</a></li></ul></div></li></div><div class="ui vertical accordion"><div class="title"><div class="ui list"><div class="item"><i class="dropdown icon"></i><a href="TokenRatesController.html">TokenRatesController</a></div></div></div><div class="content"><ul class='methods'><li data-type='method'><a href="TokenRatesController.html#fetchExchangeRate">fetchExchangeRate</a></li><li data-type='method'><a href="TokenRatesController.html#updateExchangeRates">updateExchangeRates</a></li></ul></div></li></div><div class="ui vertical accordion"><div class="title"><div class="ui list"><div class="item"><i class="inverted dropdown icon"></i><a href="module.exports_module.exports.html">exports</a></div></div></div></li></div></ul><h3>Global</h3><ul><li><a href="global.html#blacklistedDomainCheck">blacklistedDomainCheck</a></li><li><a href="global.html#cleanContextForImports">cleanContextForImports</a></li><li><a href="global.html#config">config</a></li><li><a href="global.html#connectToAccountManager">connectToAccountManager</a></li><li><a href="global.html#doctypeCheck">doctypeCheck</a></li><li><a href="global.html#documentElementCheck">documentElementCheck</a></li><li><a href="global.html#initializePopup">initializePopup</a></li><li><a href="global.html#initialState">initialState</a></li><li><a href="global.html#logStreamDisconnectWarning">logStreamDisconnectWarning</a></li><li><a href="global.html#redirectToPhishingWarning">redirectToPhishingWarning</a></li><li><a href="global.html#restoreContextAfterImports">restoreContextAfterImports</a></li><li><a href="global.html#setupControllerConnection">setupControllerConnection</a></li><li><a href="global.html#setupInjection">setupInjection</a></li><li><a href="global.html#setupStreams">setupStreams</a></li><li><a href="global.html#setupWeb3Connection">setupWeb3Connection</a></li><li><a href="global.html#shouldInjectWeb3">shouldInjectWeb3</a></li><li><a href="global.html#suffixCheck">suffixCheck</a></li></ul> </nav> <div id="main"> <h1 class="page-title">contentscript.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>const fs = require('fs') const path = require('path') const pump = require('pump') const LocalMessageDuplexStream = require('post-message-stream') const PongStream = require('ping-pong-stream/pong') const ObjectMultiplex = require('obj-multiplex') const extension = require('extensionizer') const PortStream = require('./lib/port-stream.js') const inpageContent = fs.readFileSync(path.join(__dirname, '..', '..', 'dist', 'chrome', 'inpage.js')).toString() const inpageSuffix = '//# sourceURL=' + extension.extension.getURL('inpage.js') + '\n' const inpageBundle = inpageContent + inpageSuffix // Eventually this streaming injection could be replaced with: // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.exportFunction // // But for now that is only Firefox // If we create a FireFox-only code path using that API, // MetaMask will be much faster loading and performant on Firefox. if (shouldInjectWeb3()) { setupInjection() setupStreams() } /** * Creates a script tag that injects inpage.js */ function setupInjection () { try { // inject in-page script var scriptTag = document.createElement('script') scriptTag.textContent = inpageBundle scriptTag.onload = function () { this.parentNode.removeChild(this) } var container = document.head || document.documentElement // append as first child container.insertBefore(scriptTag, container.children[0]) } catch (e) { console.error('Metamask injection failed.', e) } } /** * Sets up two-way communication streams between the * browser extension and local per-page browser context */ function setupStreams () { // setup communication to page and plugin const pageStream = new LocalMessageDuplexStream({ name: 'contentscript', target: 'inpage', }) const pluginPort = extension.runtime.connect({ name: 'contentscript' }) const pluginStream = new PortStream(pluginPort) // forward communication plugin->inpage pump( pageStream, pluginStream, pageStream, (err) => logStreamDisconnectWarning('MetaMask Contentscript Forwarding', err) ) // setup local multistream channels const mux = new ObjectMultiplex() mux.setMaxListeners(25) pump( mux, pageStream, mux, (err) => logStreamDisconnectWarning('MetaMask Inpage', err) ) pump( mux, pluginStream, mux, (err) => logStreamDisconnectWarning('MetaMask Background', err) ) // connect ping stream const pongStream = new PongStream({ objectMode: true }) pump( mux, pongStream, mux, (err) => logStreamDisconnectWarning('MetaMask PingPongStream', err) ) // connect phishing warning stream const phishingStream = mux.createStream('phishing') phishingStream.once('data', redirectToPhishingWarning) // ignore unused channels (handled by background, inpage) mux.ignoreStream('provider') mux.ignoreStream('publicConfig') } /** * Error handler for page to plugin stream disconnections * * @param {string} remoteLabel Remote stream name * @param {Error} err Stream connection error */ function logStreamDisconnectWarning (remoteLabel, err) { let warningMsg = `MetamaskContentscript - lost connection to ${remoteLabel}` if (err) warningMsg += '\n' + err.stack console.warn(warningMsg) } /** * Determines if Web3 should be injected * * @returns {boolean} True of Web3 should be injected */ function shouldInjectWeb3 () { return doctypeCheck() && suffixCheck() && documentElementCheck() && !blacklistedDomainCheck() } /** * Checks the doctype of the current document if it exists * * @returns {boolean} True if the doctype is html or if none exists */ function doctypeCheck () { const doctype = window.document.doctype if (doctype) { return doctype.name === 'html' } else { return true } } /** * Checks the current document extension * * @returns {boolean} True if the current extension is not prohibited */ function suffixCheck () { var prohibitedTypes = ['xml', 'pdf'] var currentUrl = window.location.href var currentRegex for (let i = 0; i < prohibitedTypes.length; i++) { currentRegex = new RegExp(`\\.${prohibitedTypes[i]}$`) if (currentRegex.test(currentUrl)) { return false } } return true } /** * Checks the documentElement of the current document * * @returns {boolean} True if the documentElement is an html node or if none exists */ function documentElementCheck () { var documentElement = document.documentElement.nodeName if (documentElement) { return documentElement.toLowerCase() === 'html' } return true } /** * Checks if the current domain is blacklisted * * @returns {boolean} True if the current domain is blacklisted */ function blacklistedDomainCheck () { var blacklistedDomains = [ 'uscourts.gov', 'dropbox.com', 'webbyawards.com', ] var currentUrl = window.location.href var currentRegex for (let i = 0; i < blacklistedDomains.length; i++) { const blacklistedDomain = blacklistedDomains[i].replace('.', '\\.') currentRegex = new RegExp(`(?:https?:\\/\\/)(?:(?!${blacklistedDomain}).)*$`) if (!currentRegex.test(currentUrl)) { return true } } return false } /** * Redirects the current page to a phishing information page */ function redirectToPhishingWarning () { console.log('MetaMask - redirecting to phishing warning') window.location.href = 'https://metamask.io/phishing.html' } </code></pre> </article> </section> </div> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Wed Apr 18 2018 17:21:38 GMT-0400 (EDT) using the radgrad jsdoc theme. Derived from docdash. </footer> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> <script>$('.ui.accordion').accordion();</script> </body> </html>