From 913a9e85bd24a286c3399ab6e9a0c47fdfbeae0d Mon Sep 17 00:00:00 2001
From: Dan Finlay <dan@danfinlay.com>
Date: Mon, 25 Jul 2016 16:34:29 -0700
Subject: Inject inpage script synchronously

Huge thanks to the Firefox team, for their help on the issue of our long-standing inpage script race condition.

http://stackoverflow.com/questions/38577656/how-can-i-make-a-firefox-add-on-contentscript-inject-and-run-a-script-before-oth

The problem is that we were injecting a `script` tag and assigning its `src` attribute, which triggers an asynchronous fetch request, and does not guarantee execution order! (That was news to me!)

Instead, I'm now assigning the `script` tag a `textContent` value of the script to inject, and it seems to fix the problem!

There is also a Firefox-only API that could solve this whole problem in an even more elegant way, so we might want to expose a code path for that solution later on:

https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.exportFunction

Allows you to expose an object from one scope to another. There was even talk of creating a polyfill for it that does virtually what we do, message passing between contexts.
---
 app/scripts/contentscript.js | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'app/scripts/contentscript.js')

diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index d85675e61..103ea5348 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -3,6 +3,17 @@ const PortStream = require('./lib/port-stream.js')
 const ObjectMultiplex = require('./lib/obj-multiplex')
 const extension = require('./lib/extension')
 
+const fs = require('fs')
+const path = require('path')
+const inpageText = fs.readFileSync(__dirname + '/inpage.js').toString()
+
+// 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()
@@ -14,6 +25,7 @@ function setupInjection(){
     // inject in-page script
     var scriptTag = document.createElement('script')
     scriptTag.src = extension.extension.getURL('scripts/inpage.js')
+    scriptTag.textContent = inpageText
     scriptTag.onload = function () { this.parentNode.removeChild(this) }
     var container = document.head || document.documentElement
     // append as first child
@@ -50,7 +62,6 @@ function setupStreams(){
   pluginStream.on('close', function () {
     reloadStream.write({ method: 'reset' })
   })
-
 }
 
 function shouldInjectWeb3(){
-- 
cgit