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 web3api, 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 ...
随机推荐
- LeetCode链表相加-Python<二>
上一篇:LeetCode两数之和-Python<一> 题目:https://leetcode-cn.com/problems/add-two-numbers/description/ 给定 ...
- 三层+EasyUI+Ajax 提交Form表单
源代码下载:http://download.csdn.net/download/qq_25237531/10267746
- 【Dubbo&&Zookeeper】3、Failed to read schema document 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd'问题解决方法
转自:http://blog.csdn.net/gaoshanliushui2009/article/details/50469595 我们公司使了阿里的dubbo,但是阿里的开源网站http://c ...
- html页面背景设定相关
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- js发送请求
1.Chrome控制台中 net::ERR_CONNECTION_REFUSED js频繁发送请求,有可能连接被拒绝,可用setTimeout,过几秒发送,给个缓冲时间 var overlayAnal ...
- SD从零开始64-特异的业务交易(Special Business Transactions)
紧迫订单Rush Orders 紧迫订单和现金销售是用在从工厂销售流程可能用于当客户需要求即刻从货场获得他们的货物时的销售凭据种类: 在即刻交货的销售凭据种类中,即刻交货符号和交货种类DF是设置的:当 ...
- CloudSim源代码学习——虚拟机(VM)
package org.cloudbus.cloudsim; import java.util.ArrayList;//This class provides methods to manipulat ...
- Flutter 布局(七)- Row、Column详解
本文主要介绍Flutter布局中的Row.Column控件,详细介绍了其布局行为以及使用场景,并对源码进行了分析. 1. Row A widget that displays its children ...
- [20170927]hugepages与内核参数nr_overcommit_hugepages.txt
[20170927]hugepages与内核参数nr_overcommit_hugepages.txt /proc/sys/vm/nr_overcommit_hugepages specifies h ...
- Emacs中使用shell(调出terminal)
在Emacs中使用shell(调出terminal) 方法: M-x eshell 注意:不能使用 M-x shell,这样调用的是 cmd命令,一些命令无法使用