metamask源码学习-contentscript.js
When a new site is visited, the WebExtension creates a new ContentScript
in that page's context, which can be seen at app/scripts/contentscript.js
. This script represents a per-page setup process, which creates the per-page web3
api, connects it to the background script via the Port API (wrapped in a stream abstraction), and injected into the DOM before anything loads.
当访问一个新站点时,WebExtension会在该页面的上下文中创建一个新的ContentScript,可以在app/scripts/ ContentScript .js中看到其的代码。这个脚本表示每个页面的设置过程,它创建每个页面的web3api,通过端口API(封装在流抽象中)将其连接到后台脚本,并在加载之前注入DOM。
它其实就是在页面与metamask之间进行交互前先通过contentscript来对页面的内容进行查看并判断是否提供web3给页面
metamask-extension/app/scripts/contentscript.js
它的作用就是将inpage.js这个脚本写到浏览器<script>上,使得浏览器能够调用这个脚本处理json rpc
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()) {//判断传过来的访问页面如果判断满足能够InjectWeb3就将web3 inject并且建立从contentscript到inpage的双向流
setupInjection() //然后这样传给inpage后,其web3才能使用,然后再传给页面使用
setupStreams()
} /**
* Creates a script tag that injects inpage.js
*/
function setupInjection () {//将inpage.js脚本嵌入页面<script>中
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[])
} 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 () { //建立contentscript到inpage的双向流,inpage.js是创建inpage到contentscript的双向流
// 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() 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} {@code true} if Web3 should be injected
*/
function shouldInjectWeb3 () {决定是否应该插入web3
return doctypeCheck() && suffixCheck() &&
documentElementCheck() && !blacklistedDomainCheck() //
} /**
* Checks the doctype of the current document if it exists
*
* @returns {boolean} {@code true} if the doctype is html or if none exists
*/
function doctypeCheck () {//查看页面的类型
const doctype = window.document.doctype //指定文档类型节点是否为html或不存在
if (doctype) {
return doctype.name === 'html'
} else {
return true
}
} /**
* Checks the current document extension
*
* @returns {boolean} {@code true} if the current extension is not prohibited
*/
function suffixCheck () {//检查当前文档扩展名(不为'xml', 'pdf')
var prohibitedTypes = ['xml', 'pdf']
var currentUrl = window.location.href
var currentRegex
for (let i = ; 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} {@code true} if the documentElement is an html node or if none exists
*/
function documentElementCheck () {
var documentElement = document.documentElement.nodeName //返回文档的根节点是否为html或不存在
if (documentElement) {
return documentElement.toLowerCase() === 'html'
}
return true
} /**
* Checks if the current domain is blacklisted
*
* @returns {boolean} {@code true} if the current domain is blacklisted
*/
function blacklistedDomainCheck () {//黑名单
var blacklistedDomains = [
'uscourts.gov',
'dropbox.com',
'webbyawards.com',
'cdn.shopify.com/s/javascripts/tricorder/xtld-read-only-frame.html',
'adyen.com',
'gravityforms.com',
'harbourair.com',
'ani.gamer.com.tw',
'blueskybooking.com',
]
var currentUrl = window.location.href
var currentRegex
for (let i = ; 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 - routing to Phishing Warning component')
const extensionURL = extension.runtime.getURL('phishing.html')
window.location.href = extensionURL
}
metamask源码学习-contentscript.js的更多相关文章
- metamask源码学习-inpage.js
The most confusing part about porting MetaMask to a new platform is the way we provide the Web3 API ...
- metamask源码学习-background.js
这个就是浏览器后台所进行操作的地方了,它就是页面也区块链进行交互的中间部分. metamask-background描述了为web扩展单例的文件app/scripts/background.js.该上 ...
- metamask源码学习-ui/index.js
The UI-即上图左下角metamask-ui部分,即其图形化界面 The MetaMask UI is essentially just a website that can be configu ...
- metamask源码学习导论
()MetaMask Browser Extension https://github.com/MetaMask/metamask-extension 这就是整个metamask的源码所在之处,好好看 ...
- metamask源码学习-controller-transaction
()metamask-extension/app/scripts/controllers/transactions Transaction Controller is an aggregate of ...
- metamask源码学习-metamask-controller.js
The MetaMask Controller——The central metamask controller. Aggregates other controllers and exports a ...
- metamask源码学习-controllers-network
https://github.com/MetaMask/metamask-extension/tree/master/app/scripts/controllers/network metamask- ...
- 【 js 基础 】【 源码学习 】源码设计 (持续更新)
学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:undersc ...
- Underscore.js 源码学习笔记(下)
上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...
随机推荐
- SQL Server 数据类型映射(转载)
SQL Server 数据类型映射 SQL Server 和 .NET Framework 基于不同的类型系统. 例如,.NET Framework Decimal 结构的最大小数位数为 28,而 S ...
- try、catch、finally详解,你不知道的异常处理
介绍 不管是新手还是工作几年的老油条,对try{}catch{}来说是不陌生的.他可以来帮助我们获取异常信息,在try中的代码出现错误,火灾catch代码块中被捕获到.官方也给了详细的解释:. 抛出异 ...
- Java集合框架——容器的快速报错机制 fail-fast 是什么?
前言:最近看 java 集合方面的源码,了解到集合使用了 fail-fast 的机制,这里就记录一下这个机制是什么,有什么用,如何实现的. 一.fail-fast 简介 fail-fast 机制,即快 ...
- HDU6205
card card card Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- Thymeleaf学习记录(1)--启动模板及建立Demo
Thymeleaf是什么? Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎.相比于JSP,Thymeleaf更简洁,渲染性能更好,维护性更好,它可以XML/XHTML/HTM ...
- UED与UCD
UED User Experience Design(用户体验设计),简称UED.UED是以用户为中心的一种设计手段,以用户需求为目标而进行的设计.设计过程注重以用户为中心,用户体验的概念从开发的最早 ...
- 【读书笔记】iOS-成为一名开发者
iOS开发者计划是按年付费的,在过期前60天可以开始续费.如果你不续费的话,你将无法发布应用.另外苹果会吊销你的开发者证书和发布证书.最后,苹果将你在iTunes App Store上的所有应用下架. ...
- 【图解】Web前端实现类似Excel的电子表格
本文将通过图解的方式,使用纯前端表格控件 SpreadJS 来一步一步实现在线的电子表格产品(例如可构建Office 365 Excel产品.Google的在线SpreadSheet). 工具简介: ...
- Java网络编程--套接字Socket
一.套接字Socket IP地址标志Internet上的计算机,端口号标志正在计算机上运行的进程(程序). 端口号被规定为一个16位的0--65535之间的整数,其中,0--1023被预先定义的服务通 ...
- Vue CLI3 开启gzip压缩
gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度.html.js.css文件甚至json数据都可以用它压缩,可以减小60%以上的体积. webpack在打包时可以借助 compr ...