From 7b9a1197c8efe0a33d107c38e94871485831ec89 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 21 Jun 2016 12:07:13 -0700 Subject: [PATCH 01/13] Began adding auto linting --- .eslint | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + gulpfile.js | 24 ++++++++- package.json | 1 + 4 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 .eslint diff --git a/.eslint b/.eslint new file mode 100644 index 000000000..ae59af478 --- /dev/null +++ b/.eslint @@ -0,0 +1,150 @@ +{ + "parserOptions": { + "ecmaVersion": 6, + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "impliedStrict": true, + }, + }, + + "env": { + "es6": true, + "node": true + }, + + "plugins": [ + "standard", + "promise" + ], + + "globals": { + "chrome": true, + "document": false, + "navigator": false, + "web3": true, + "window": false + }, + + "rules": { + "accessor-pairs": 2, + "arrow-spacing": [2, { "before": true, "after": true }], + "block-spacing": [2, "always"], + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "camelcase": [2, { "properties": "never" }], + "comma-dangle": [2, "never"], + "comma-spacing": [2, { "before": false, "after": true }], + "comma-style": [2, "last"], + "constructor-super": 2, + "curly": [2, "multi-line"], + "dot-location": [2, "property"], + "eol-last": 2, + "eqeqeq": [2, "allow-null"], + "generator-star-spacing": [2, { "before": true, "after": true }], + "handle-callback-err": [2, "^(err|error)$" ], + "indent": [2, 2, { "SwitchCase": 1 }], + "jsx-quotes": [2, "prefer-single"], + "key-spacing": [2, { "beforeColon": false, "afterColon": true }], + "keyword-spacing": [2, { "before": true, "after": true }], + "new-cap": [2, { "newIsCap": true, "capIsNew": false }], + "new-parens": 2, + "no-array-constructor": 2, + "no-caller": 2, + "no-class-assign": 2, + "no-cond-assign": 2, + "no-const-assign": 2, + "no-control-regex": 2, + "no-debugger": 2, + "no-delete-var": 2, + "no-dupe-args": 2, + "no-dupe-class-members": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-duplicate-imports": 2, + "no-empty-character-class": 2, + "no-empty-pattern": 2, + "no-eval": 2, + "no-ex-assign": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-extra-boolean-cast": 2, + "no-extra-parens": [2, "functions"], + "no-fallthrough": 2, + "no-floating-decimal": 2, + "no-func-assign": 2, + "no-implied-eval": 2, + "no-inner-declarations": [2, "functions"], + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-iterator": 2, + "no-label-var": 2, + "no-labels": [2, { "allowLoop": false, "allowSwitch": false }], + "no-lone-blocks": 2, + "no-mixed-spaces-and-tabs": 2, + "no-multi-spaces": 2, + "no-multi-str": 2, + "no-multiple-empty-lines": [2, { "max": 1 }], + "no-native-reassign": 2, + "no-negated-in-lhs": 2, + "no-new": 2, + "no-new-func": 2, + "no-new-object": 2, + "no-new-require": 2, + "no-new-symbol": 2, + "no-new-wrappers": 2, + "no-obj-calls": 2, + "no-octal": 2, + "no-octal-escape": 2, + "no-path-concat": 2, + "no-proto": 2, + "no-redeclare": 2, + "no-regex-spaces": 2, + "no-return-assign": [2, "except-parens"], + "no-self-assign": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-shadow-restricted-names": 2, + "no-spaced-func": 2, + "no-sparse-arrays": 2, + "no-this-before-super": 2, + "no-throw-literal": 2, + "no-trailing-spaces": 2, + "no-undef": 2, + "no-undef-init": 2, + "no-unexpected-multiline": 2, + "no-unmodified-loop-condition": 2, + "no-unneeded-ternary": [2, { "defaultAssignment": false }], + "no-unreachable": 2, + "no-unsafe-finally": 2, + "no-unused-vars": [2, { "vars": "all", "args": "none" }], + "no-useless-call": 2, + "no-useless-computed-key": 2, + "no-useless-constructor": 2, + "no-useless-escape": 2, + "no-whitespace-before-property": 2, + "no-with": 2, + "one-var": [2, { "initialized": "never" }], + "operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }], + "padded-blocks": [2, "never"], + "quotes": [2, "single", "avoid-escape"], + "semi": [2, "never"], + "semi-spacing": [2, { "before": false, "after": true }], + "space-before-blocks": [2, "always"], + "space-before-function-paren": [2, "always"], + "space-in-parens": [2, "never"], + "space-infix-ops": 2, + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], + "template-curly-spacing": [2, "never"], + "use-isnan": 2, + "valid-typeof": 2, + "wrap-iife": [2, "any"], + "yield-star-spacing": [2, "both"], + "yoda": [2, "never"], + + "standard/object-curly-even-spacing": [2, "either"], + "standard/array-bracket-even-spacing": [2, "either"], + "standard/computed-property-even-spacing": [2, "even"], + + "promise/param-names": 2 + } +} diff --git a/README.md b/README.md index bab22074d..384f18553 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ Then just run `npm test`. You can also test with a continuously watching process, via `npm run watch`. +You can run the linter by itself with `gulp lint`. + ### Deploying the UI You must be authorized already on the Metamask plugin. diff --git a/gulpfile.js b/gulpfile.js index 63eb22a2c..368446bff 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -9,6 +9,7 @@ var sourcemaps = require('gulp-sourcemaps') var assign = require('lodash.assign') var livereload = require('gulp-livereload') var del = require('del') +var eslint = require('gulp-eslint') // browser reload @@ -49,6 +50,25 @@ gulp.task('copy:watch', function(){ gulp.watch(['./app/{_locales,images}/*', './app/scripts/chromereload.js', './app/*.{html,json}'], gulp.series('copy')) }) +// lint js + +gulp.task('lint', function () { + // Ignoring node_modules, dist, and docs folders: + return gulp.src(['app/**/*.js', 'ui/**/*.js', '!node_modules/**', '!dist/**', '!docs/**']) + .pipe(eslint()) + // eslint.format() outputs the lint results to the console. + // Alternatively use eslint.formatEach() (see Docs). + .pipe(eslint.format()) + // To have the process exit with an error code (1) on + // lint error, return the stream and pipe to failAfterError last. + .pipe(eslint.failAfterError()) +}); + +/* +gulp.task('default', ['lint'], function () { + // This will only run if the lint task is successful... +}); +*/ // build js @@ -74,8 +94,8 @@ gulp.task('clean', function clean() { // high level tasks -gulp.task('dev', gulp.series('dev:js', 'copy', gulp.parallel('copy:watch', 'dev:reload'))) -gulp.task('build', gulp.series('clean', gulp.parallel('build:js', 'copy'))) +gulp.task('dev', gulp.series('dev:js', 'copy', gulp.parallel('copy:watch', 'dev:reload', 'lint'))) +gulp.task('build', gulp.series('clean', gulp.parallel('build:js', 'copy', 'lint'))) // task generators diff --git a/package.json b/package.json index a82738c67..6e8bf4c00 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "eth-store": "^1.1.0", "ethereumjs-tx": "^1.0.0", "ethereumjs-util": "^4.4.0", + "gulp-eslint": "^2.0.0", "hat": "0.0.3", "identicon.js": "^1.2.1", "inject-css": "^0.1.1", From 45506d6758e284aa6f5c128b12dea55f229f65e6 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 21 Jun 2016 12:40:09 -0700 Subject: [PATCH 02/13] Got eslint running correctly --- .eslint => .eslintrc | 20 +++++++++++--------- .nvmrc | 1 + gulpfile.js | 4 +++- package.json | 1 + 4 files changed, 16 insertions(+), 10 deletions(-) rename .eslint => .eslintrc (93%) create mode 100644 .nvmrc diff --git a/.eslint b/.eslintrc similarity index 93% rename from .eslint rename to .eslintrc index ae59af478..c7e01d8ce 100644 --- a/.eslint +++ b/.eslintrc @@ -1,20 +1,26 @@ { + "parser": "babel-eslint", "parserOptions": { "ecmaVersion": 6, "ecmaFeatures": { "experimentalObjectRestSpread": true, "impliedStrict": true, + "modules": true, + "blockBindings": true, + "arrowFunctions": true, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "templateStrings": true }, }, "env": { "es6": true, - "node": true + "node": true, + "browser": true }, "plugins": [ - "standard", - "promise" ], "globals": { @@ -134,17 +140,13 @@ "space-infix-ops": 2, "space-unary-ops": [2, { "words": true, "nonwords": false }], "spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], + "strict": 0, "template-curly-spacing": [2, "never"], "use-isnan": 2, "valid-typeof": 2, "wrap-iife": [2, "any"], "yield-star-spacing": [2, "both"], "yoda": [2, "never"], - - "standard/object-curly-even-spacing": [2, "either"], - "standard/array-bracket-even-spacing": [2, "either"], - "standard/computed-property-even-spacing": [2, "even"], - - "promise/param-names": 2 + "prefer-const": 1 } } diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..e0ea36fee --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +6.0 diff --git a/gulpfile.js b/gulpfile.js index 368446bff..4204d79b9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,6 +10,8 @@ var assign = require('lodash.assign') var livereload = require('gulp-livereload') var del = require('del') var eslint = require('gulp-eslint') +var fs = require('fs') +var path = require('path') // browser reload @@ -55,7 +57,7 @@ gulp.task('copy:watch', function(){ gulp.task('lint', function () { // Ignoring node_modules, dist, and docs folders: return gulp.src(['app/**/*.js', 'ui/**/*.js', '!node_modules/**', '!dist/**', '!docs/**']) - .pipe(eslint()) + .pipe(eslint(fs.readFileSync(path.join(__dirname, '.eslintrc')))) // eslint.format() outputs the lint results to the console. // Alternatively use eslint.formatEach() (see Docs). .pipe(eslint.format()) diff --git a/package.json b/package.json index 6e8bf4c00..65d813da9 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "xtend": "^4.0.1" }, "devDependencies": { + "babel-eslint": "^6.0.5", "babel-preset-es2015": "^6.6.0", "babel-register": "^6.7.2", "babelify": "^7.2.0", From 7b2f061fbbe48882733717dffd299c2737c33493 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 21 Jun 2016 12:51:04 -0700 Subject: [PATCH 03/13] Some manual fixes --- .eslintrc | 6 +++--- app/scripts/background.js | 3 --- package.json | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.eslintrc b/.eslintrc index c7e01d8ce..945a68b08 100644 --- a/.eslintrc +++ b/.eslintrc @@ -37,7 +37,7 @@ "block-spacing": [2, "always"], "brace-style": [2, "1tbs", { "allowSingleLine": true }], "camelcase": [2, { "properties": "never" }], - "comma-dangle": [2, "never"], + "comma-dangle": [2, "always-multiline"], "comma-spacing": [2, { "before": false, "after": true }], "comma-style": [2, "last"], "constructor-super": 2, @@ -134,8 +134,8 @@ "quotes": [2, "single", "avoid-escape"], "semi": [2, "never"], "semi-spacing": [2, { "before": false, "after": true }], - "space-before-blocks": [2, "always"], - "space-before-function-paren": [2, "always"], + "space-before-blocks": [0, "always"], + "space-before-function-paren": [0, "always"], "space-in-parens": [2, "never"], "space-infix-ops": 2, "space-unary-ops": [2, { "words": true, "nonwords": false }], diff --git a/app/scripts/background.js b/app/scripts/background.js index 3ad95d3e9..b07331046 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1,11 +1,9 @@ const urlUtil = require('url') const Dnode = require('dnode') const eos = require('end-of-stream') -const combineStreams = require('pumpify') const extend = require('xtend') const EthStore = require('eth-store') const MetaMaskProvider = require('web3-provider-engine/zero.js') -const ObjectMultiplex = require('./lib/obj-multiplex') const PortStream = require('./lib/port-stream.js') const IdentityStore = require('./lib/idStore') const createUnlockRequestNotification = require('./lib/notifications.js').createUnlockRequestNotification @@ -55,7 +53,6 @@ function setupTrustedCommunication(connectionStream, originDomain){ // state and network // -var providerConfig = configManager.getProvider() var idStore = new IdentityStore() var providerOpts = { diff --git a/package.json b/package.json index 65d813da9..8c1f119cb 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "private": true, "scripts": { "start": "gulp dev", - "test": "mocha --require test/helper.js --compilers js:babel-register --recursive", + "test": "mocha --require test/helper.js --compilers js:babel-register --recursive && gulp lint", "watch": "mocha watch --compilers js:babel-register --recursive" }, "browserify": { From f7f8f8b1c50be39db22a7b10c6c6db007fe590aa Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 21 Jun 2016 13:06:41 -0700 Subject: [PATCH 04/13] Turn spaces back on --- .eslintrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc b/.eslintrc index 945a68b08..f5d5ce6db 100644 --- a/.eslintrc +++ b/.eslintrc @@ -134,8 +134,8 @@ "quotes": [2, "single", "avoid-escape"], "semi": [2, "never"], "semi-spacing": [2, { "before": false, "after": true }], - "space-before-blocks": [0, "always"], - "space-before-function-paren": [0, "always"], + "space-before-blocks": [1, "always"], + "space-before-function-paren": [1, "always"], "space-in-parens": [2, "never"], "space-infix-ops": 2, "space-unary-ops": [2, { "words": true, "nonwords": false }], From 45d16d975b3e7b981821aabfe356efd2c7a06e6e Mon Sep 17 00:00:00 2001 From: kumavis Date: Tue, 21 Jun 2016 13:14:21 -0700 Subject: [PATCH 05/13] background - batch rpc fix for origin domain --- app/scripts/background.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/app/scripts/background.js b/app/scripts/background.js index 3ad95d3e9..66108c251 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -152,19 +152,22 @@ function setupPublicConfig(stream){ } function setupProviderConnection(stream, originDomain){ - - stream.on('data', function onRpcRequest(payload){ - // Append origin to rpc payload - payload.origin = originDomain - // Append origin to signature request - if (payload.method === 'eth_sendTransaction') { - payload.params[0].origin = originDomain - } else if (payload.method === 'eth_sign') { - payload.params.push({ origin: originDomain }) - } + // decorate all payloads with origin domain + stream.on('data', function onRpcRequest(request){ + var payloads = Array.isArray(request) ? request : [request] + payloads.forEach(function(payload){ + // Append origin to rpc payload + payload.origin = originDomain + // Append origin to signature request + if (payload.method === 'eth_sendTransaction') { + payload.params[0].origin = originDomain + } else if (payload.method === 'eth_sign') { + payload.params.push({ origin: originDomain }) + } + }) // handle rpc request - provider.sendAsync(payload, function onPayloadHandled(err, response){ - logger(null, payload, response) + provider.sendAsync(request, function onPayloadHandled(err, response){ + logger(null, request, response) try { stream.write(response) } catch (err) { From a08c3bc01b11fbd0e3a243359befbe9fc909edf4 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 21 Jun 2016 13:18:32 -0700 Subject: [PATCH 06/13] Auto linted --- .eslintrc | 1 - app/scripts/background.js | 108 +- app/scripts/chromereload.js | 2225 ++++++++--------- app/scripts/contentscript.js | 10 +- app/scripts/inpage.js | 11 +- app/scripts/lib/auto-faucet.js | 4 +- app/scripts/lib/auto-reload.js | 15 +- app/scripts/lib/config-manager.js | 115 +- app/scripts/lib/ensnare.js | 10 +- app/scripts/lib/id-management.js | 34 +- app/scripts/lib/idStore.js | 89 +- app/scripts/lib/inpage-provider.js | 29 +- app/scripts/lib/local-message-stream.js | 19 +- app/scripts/lib/message-manager.js | 20 +- app/scripts/lib/notifications.js | 41 +- app/scripts/lib/obj-multiplex.js | 13 +- app/scripts/lib/port-stream.js | 15 +- app/scripts/lib/remote-store.js | 34 +- app/scripts/lib/stream-utils.js | 17 +- app/scripts/migrations/002.js | 4 +- app/scripts/migrations/003.js | 4 +- app/scripts/migrations/004.js | 16 +- app/scripts/popup.js | 16 +- ui/app/account-detail.js | 26 +- ui/app/accounts/account-panel.js | 11 +- ui/app/accounts/index.js | 96 +- ui/app/actions.js | 113 +- ui/app/app.js | 54 +- ui/app/components/account-export.js | 21 +- ui/app/components/account-panel.js | 15 +- ui/app/components/drop-menu-item.js | 8 +- ui/app/components/editable-label.js | 19 +- ui/app/components/eth-balance.js | 4 +- ui/app/components/identicon.js | 6 +- ui/app/components/mascot.js | 14 +- ui/app/components/network.js | 58 +- ui/app/components/panel.js | 5 +- ui/app/components/pending-msg.js | 9 +- ui/app/components/pending-tx.js | 9 +- ui/app/components/template.js | 5 +- .../components/transaction-list-item-icon.js | 11 +- ui/app/components/transaction-list-item.js | 22 +- ui/app/components/transaction-list.js | 8 +- ui/app/conf-tx.js | 20 +- ui/app/config.js | 47 +- ui/app/first-time/create-vault-complete.js | 11 +- ui/app/first-time/create-vault.js | 17 +- ui/app/first-time/disclaimer.js | 13 +- ui/app/first-time/init-menu.js | 15 +- ui/app/first-time/restore-vault.js | 16 +- ui/app/info.js | 135 +- ui/app/loading.js | 8 +- ui/app/recover-seed/confirmation.js | 23 +- ui/app/reducers.js | 5 +- ui/app/reducers/app.js | 588 +++-- ui/app/reducers/identities.js | 4 +- ui/app/reducers/metamask.js | 161 +- ui/app/root.js | 9 +- ui/app/send.js | 21 +- ui/app/settings.js | 16 +- ui/app/store.js | 3 +- ui/app/template.js | 10 +- ui/app/unlock.js | 21 +- ui/app/util.js | 87 +- ui/css.js | 18 +- ui/example.js | 30 +- ui/index.js | 12 +- ui/lib/explorer-link.js | 2 +- ui/lib/icon-factory.js | 17 +- ui/lib/tx-helper.js | 2 +- 70 files changed, 2282 insertions(+), 2393 deletions(-) diff --git a/.eslintrc b/.eslintrc index f5d5ce6db..635c47a95 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,5 +1,4 @@ { - "parser": "babel-eslint", "parserOptions": { "ecmaVersion": 6, "ecmaFeatures": { diff --git a/app/scripts/background.js b/app/scripts/background.js index b07331046..09a8a18ac 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -20,7 +20,7 @@ const Web3 = require('web3') // chrome.runtime.onConnect.addListener(connectRemote) -function connectRemote(remotePort){ +function connectRemote (remotePort) { var isMetaMaskInternalProcess = (remotePort.name === 'popup') var portStream = new PortStream(remotePort) if (isMetaMaskInternalProcess) { @@ -33,7 +33,7 @@ function connectRemote(remotePort){ } } -function setupUntrustedCommunication(connectionStream, originDomain){ +function setupUntrustedCommunication (connectionStream, originDomain) { // setup multiplexing var mx = setupMultiplex(connectionStream) // connect features @@ -41,7 +41,7 @@ function setupUntrustedCommunication(connectionStream, originDomain){ setupPublicConfig(mx.createStream('publicConfig')) } -function setupTrustedCommunication(connectionStream, originDomain){ +function setupTrustedCommunication (connectionStream, originDomain) { // setup multiplexing var mx = setupMultiplex(connectionStream) // connect features @@ -58,7 +58,7 @@ var idStore = new IdentityStore() var providerOpts = { rpcUrl: configManager.getCurrentRpcAddress(), // account mgmt - getAccounts: function(cb){ + getAccounts: function (cb) { var selectedAddress = idStore.getSelectedAddress() var result = selectedAddress ? [selectedAddress] : [] cb(null, result) @@ -76,8 +76,8 @@ idStore.web3 = web3 idStore.getNetwork() // log new blocks -provider.on('block', function(block){ - console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex')) +provider.on('block', function (block) { + console.log('BLOCK CHANGED:', '#' + block.number.toString('hex'), '0x' + block.hash.toString('hex')) // Check network when restoring connectivity: if (idStore._currentState.network === 'loading') { @@ -90,7 +90,7 @@ provider.on('error', idStore.getNetwork.bind(idStore)) var ethStore = new EthStore(provider) idStore.setStore(ethStore) -function getState(){ +function getState () { var state = extend( ethStore.getState(), idStore.getState(), @@ -112,45 +112,43 @@ var initPublicState = extend( var publicConfigStore = new HostStore(initPublicState) // subscribe to changes -configManager.subscribe(function(state){ +configManager.subscribe(function (state) { storeSetFromObj(publicConfigStore, configToPublic(state)) }) -idStore.on('update', function(state){ +idStore.on('update', function (state) { storeSetFromObj(publicConfigStore, idStoreToPublic(state)) }) // idStore substate -function idStoreToPublic(state){ +function idStoreToPublic (state) { return { selectedAddress: state.selectedAddress, } } // config substate -function configToPublic(state){ +function configToPublic (state) { return { provider: state.provider, } } // dump obj into store -function storeSetFromObj(store, obj){ - Object.keys(obj).forEach(function(key){ +function storeSetFromObj (store, obj) { + Object.keys(obj).forEach(function (key) { store.set(key, obj[key]) }) } - // // remote features // -function setupPublicConfig(stream){ +function setupPublicConfig (stream) { var storeStream = publicConfigStore.createStream() stream.pipe(storeStream).pipe(stream) } -function setupProviderConnection(stream, originDomain){ - - stream.on('data', function onRpcRequest(payload){ +function setupProviderConnection (stream, originDomain) { + stream.on('data', function onRpcRequest (payload) { // Append origin to rpc payload payload.origin = originDomain // Append origin to signature request @@ -160,7 +158,10 @@ function setupProviderConnection(stream, originDomain){ payload.params.push({ origin: originDomain }) } // handle rpc request - provider.sendAsync(payload, function onPayloadHandled(err, response){ + provider.sendAsync(payload, function onPayloadHandled (err, response) { + if (err) { + return logger(err) + } logger(null, payload, response) try { stream.write(response) @@ -170,54 +171,52 @@ function setupProviderConnection(stream, originDomain){ }) }) - function logger(err, request, response){ + function logger (err, request, response) { if (err) return console.error(err.stack) if (!request.isMetamaskInternal) { console.log(`RPC (${originDomain}):`, request, '->', response) - if (response.error) console.error('Error in RPC response:\n'+response.error.message) + if (response.error) console.error('Error in RPC response:\n' + response.error.message) } } } -function setupControllerConnection(stream){ +function setupControllerConnection (stream) { var dnode = Dnode({ - getState: function(cb){ cb(null, getState()) }, - setRpcTarget: setRpcTarget, - setProviderType: setProviderType, + getState: function (cb) { cb(null, getState()) }, + setRpcTarget: setRpcTarget, + setProviderType: setProviderType, useEtherscanProvider: useEtherscanProvider, - agreeToDisclaimer: agreeToDisclaimer, + agreeToDisclaimer: agreeToDisclaimer, // forward directly to idStore - createNewVault: idStore.createNewVault.bind(idStore), - recoverFromSeed: idStore.recoverFromSeed.bind(idStore), - submitPassword: idStore.submitPassword.bind(idStore), + createNewVault: idStore.createNewVault.bind(idStore), + recoverFromSeed: idStore.recoverFromSeed.bind(idStore), + submitPassword: idStore.submitPassword.bind(idStore), setSelectedAddress: idStore.setSelectedAddress.bind(idStore), approveTransaction: idStore.approveTransaction.bind(idStore), - cancelTransaction: idStore.cancelTransaction.bind(idStore), - signMessage: idStore.signMessage.bind(idStore), - cancelMessage: idStore.cancelMessage.bind(idStore), - setLocked: idStore.setLocked.bind(idStore), + cancelTransaction: idStore.cancelTransaction.bind(idStore), + signMessage: idStore.signMessage.bind(idStore), + cancelMessage: idStore.cancelMessage.bind(idStore), + setLocked: idStore.setLocked.bind(idStore), clearSeedWordCache: idStore.clearSeedWordCache.bind(idStore), - exportAccount: idStore.exportAccount.bind(idStore), - revealAccount: idStore.revealAccount.bind(idStore), - saveAccountLabel: idStore.saveAccountLabel.bind(idStore), - tryPassword: idStore.tryPassword.bind(idStore), - recoverSeed: idStore.recoverSeed.bind(idStore), + exportAccount: idStore.exportAccount.bind(idStore), + revealAccount: idStore.revealAccount.bind(idStore), + saveAccountLabel: idStore.saveAccountLabel.bind(idStore), + tryPassword: idStore.tryPassword.bind(idStore), + recoverSeed: idStore.recoverSeed.bind(idStore), }) stream.pipe(dnode).pipe(stream) - dnode.on('remote', function(remote){ - + dnode.on('remote', function (remote) { // push updates to popup ethStore.on('update', sendUpdate) idStore.on('update', sendUpdate) // teardown on disconnect - eos(stream, function unsubscribe(){ + eos(stream, function unsubscribe () { ethStore.removeListener('update', sendUpdate) }) - function sendUpdate(){ + function sendUpdate () { var state = getState() remote.sendUpdate(state) } - }) } @@ -227,7 +226,7 @@ function setupControllerConnection(stream){ idStore.on('update', updateBadge) -function updateBadge(state){ +function updateBadge (state) { var label = '' var unconfTxs = configManager.unconfirmedTxs() var unconfTxLen = Object.keys(unconfTxs).length @@ -245,7 +244,7 @@ function updateBadge(state){ // Add unconfirmed Tx + Msg // -function newUnsignedTransaction(txParams, onTxDoneCb){ +function newUnsignedTransaction (txParams, onTxDoneCb) { var state = idStore.getState() if (!state.isUnlocked) { createUnlockRequestNotification({ @@ -257,20 +256,19 @@ function newUnsignedTransaction(txParams, onTxDoneCb){ } } -function newUnsignedMessage(msgParams, cb){ +function newUnsignedMessage (msgParams, cb) { var state = idStore.getState() if (!state.isUnlocked) { createUnlockRequestNotification({ title: 'Account Unlock Request', }) - var msgId = idStore.addUnconfirmedMessage(msgParams, cb) } else { addUnconfirmedMsg(msgParams, cb) } } -function addUnconfirmedTx(txParams, onTxDoneCb){ - idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, function(err, txData){ +function addUnconfirmedTx (txParams, onTxDoneCb) { + idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, function (err, txData) { if (err) return onTxDoneCb(err) createTxNotification({ title: 'New Unsigned Transaction', @@ -281,7 +279,7 @@ function addUnconfirmedTx(txParams, onTxDoneCb){ }) } -function addUnconfirmedMsg(msgParams, cb){ +function addUnconfirmedMsg (msgParams, cb) { var msgId = idStore.addUnconfirmedMessage(msgParams, cb) createMsgNotification({ title: 'New Unsigned Message', @@ -295,7 +293,7 @@ function addUnconfirmedMsg(msgParams, cb){ // config // -function agreeToDisclaimer(cb) { +function agreeToDisclaimer (cb) { try { configManager.setConfirmed(true) cb() @@ -305,23 +303,23 @@ function agreeToDisclaimer(cb) { } // called from popup -function setRpcTarget(rpcTarget){ +function setRpcTarget (rpcTarget) { configManager.setRpcTarget(rpcTarget) chrome.runtime.reload() idStore.getNetwork() } -function setProviderType(type) { +function setProviderType (type) { configManager.setProviderType(type) chrome.runtime.reload() idStore.getNetwork() } -function useEtherscanProvider() { +function useEtherscanProvider () { configManager.useEtherscanProvider() chrome.runtime.reload() } // util -function noop(){} +function noop () {} diff --git a/app/scripts/chromereload.js b/app/scripts/chromereload.js index 24adc7022..0dd6bd5aa 100644 --- a/app/scripts/chromereload.js +++ b/app/scripts/chromereload.js @@ -32,1187 +32,1160 @@ window.LiveReloadOptions = { host: 'localhost' }; +(function e (t, n, r) { function s (o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require === 'function' && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = 'MODULE_NOT_FOUND', f } var l = n[o] = {exports: {}}; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require === 'function' && require; for (var o = 0; o < r.length; o++)s(r[o]); return s })({1: [function (require, module, exports) { + (function () { + var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, _ref -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o tag"); - return; - } - } - this.reloader = new Reloader(this.window, this.console, Timer); - this.connector = new Connector(this.options, this.WebSocket, Timer, { - connecting: (function(_this) { - return function() {}; - })(this), - socketConnected: (function(_this) { - return function() {}; - })(this), - connected: (function(_this) { - return function(protocol) { - var _base; - if (typeof (_base = _this.listeners).connect === "function") { - _base.connect(); - } - _this.log("LiveReload is connected to " + _this.options.host + ":" + _this.options.port + " (protocol v" + protocol + ")."); - return _this.analyze(); - }; - })(this), - error: (function(_this) { - return function(e) { - if (e instanceof ProtocolError) { - if (typeof console !== "undefined" && console !== null) { - return console.log("" + e.message + "."); - } - } else { - if (typeof console !== "undefined" && console !== null) { - return console.log("LiveReload internal error: " + e.message); - } - } - }; - })(this), - disconnected: (function(_this) { - return function(reason, nextDelay) { - var _base; - if (typeof (_base = _this.listeners).disconnect === "function") { - _base.disconnect(); - } - switch (reason) { - case 'cannot-connect': - return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + ", will retry in " + nextDelay + " sec."); - case 'broken': - return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + ", reconnecting in " + nextDelay + " sec."); - case 'handshake-timeout': - return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake timeout), will retry in " + nextDelay + " sec."); - case 'handshake-failed': - return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake failed), will retry in " + nextDelay + " sec."); - case 'manual': - break; - case 'error': - break; - default: - return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + " (" + reason + "), reconnecting in " + nextDelay + " sec."); - } - }; - })(this), - message: (function(_this) { - return function(message) { - switch (message.command) { - case 'reload': - return _this.performReload(message); - case 'alert': - return _this.performAlert(message); - } - }; })(this) - }); - this.initialized = true; - } - - LiveReload.prototype.on = function(eventName, handler) { - return this.listeners[eventName] = handler; - }; - - LiveReload.prototype.log = function(message) { - return this.console.log("" + message); - }; - - LiveReload.prototype.performReload = function(message) { - var _ref, _ref1; - this.log("LiveReload received reload request: " + (JSON.stringify(message, null, 2))); - return this.reloader.reload(message.path, { - liveCSS: (_ref = message.liveCSS) != null ? _ref : true, - liveImg: (_ref1 = message.liveImg) != null ? _ref1 : true, - originalPath: message.originalPath || '', - overrideURL: message.overrideURL || '', - serverURL: "http://" + this.options.host + ":" + this.options.port - }); - }; - - LiveReload.prototype.performAlert = function(message) { - return alert(message.message); - }; - - LiveReload.prototype.shutDown = function() { - var _base; - if (!this.initialized) { - return; - } - this.connector.disconnect(); - this.log("LiveReload disconnected."); - return typeof (_base = this.listeners).shutdown === "function" ? _base.shutdown() : void 0; - }; - - LiveReload.prototype.hasPlugin = function(identifier) { - return !!this.pluginIdentifiers[identifier]; - }; - - LiveReload.prototype.addPlugin = function(pluginClass) { - var plugin; - if (!this.initialized) { - return; - } - if (this.hasPlugin(pluginClass.identifier)) { - return; - } - this.pluginIdentifiers[pluginClass.identifier] = true; - plugin = new pluginClass(this.window, { - _livereload: this, - _reloader: this.reloader, - _connector: this.connector, - console: this.console, - Timer: Timer, - generateCacheBustUrl: (function(_this) { - return function(url) { - return _this.reloader.generateCacheBustUrl(url); - }; + this.socket.onmessage = (function (_this) { + return function (e) { + return _this._onmessage(e) + } })(this) - }); - this.plugins.push(plugin); - this.reloader.addPlugin(plugin); - }; - - LiveReload.prototype.analyze = function() { - var plugin, pluginData, pluginsData, _i, _len, _ref; - if (!this.initialized) { - return; - } - if (!(this.connector.protocol >= 7)) { - return; - } - pluginsData = {}; - _ref = this.plugins; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - plugin = _ref[_i]; - pluginsData[plugin.constructor.identifier] = pluginData = (typeof plugin.analyze === "function" ? plugin.analyze() : void 0) || {}; - pluginData.version = plugin.constructor.version; - } - this.connector.sendCommand({ - command: 'info', - plugins: pluginsData, - url: this.window.location.href - }); - }; - - return LiveReload; - - })(); - -}).call(this); - -},{"./connector":1,"./options":5,"./reloader":7,"./timer":9}],5:[function(require,module,exports){ -(function() { - var Options; - - exports.Options = Options = (function() { - function Options() { - this.https = false; - this.host = null; - this.port = 35729; - this.snipver = null; - this.ext = null; - this.extver = null; - this.mindelay = 1000; - this.maxdelay = 60000; - this.handshake_timeout = 5000; - } - - Options.prototype.set = function(name, value) { - if (typeof value === 'undefined') { - return; - } - if (!isNaN(+value)) { - value = +value; - } - return this[name] = value; - }; - - return Options; - - })(); - - Options.extract = function(document) { - var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len1, _ref, _ref1; - _ref = document.getElementsByTagName('script'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - element = _ref[_i]; - if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) { - options = new Options(); - options.https = src.indexOf("https") === 0; - if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?$/)) { - options.host = mm[1]; - if (mm[2]) { - options.port = parseInt(mm[2], 10); + return this.socket.onerror = (function (_this) { + return function (e) { + return _this._onerror(e) } - } - if (m[2]) { - _ref1 = m[2].split('&'); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - pair = _ref1[_j]; - if ((keyAndValue = pair.split('=')).length > 1) { - options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('=')); - } - } - } - return options; + })(this) } - } - return null; - }; -}).call(this); + Connector.prototype.disconnect = function () { + this._connectionDesired = false + this._reconnectTimer.stop() + if (!this._isSocketConnected()) { + return + } + this._disconnectionReason = 'manual' + return this.socket.close() + } -},{}],6:[function(require,module,exports){ -(function() { - var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + Connector.prototype._scheduleReconnection = function () { + if (!this._connectionDesired) { + return + } + if (!this._reconnectTimer.running) { + this._reconnectTimer.start(this._nextDelay) + return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2) + } + } - exports.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6'; - - exports.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7'; - - exports.ProtocolError = ProtocolError = (function() { - function ProtocolError(reason, data) { - this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\"."; - } - - return ProtocolError; - - })(); - - exports.Parser = Parser = (function() { - function Parser(handlers) { - this.handlers = handlers; - this.reset(); - } - - Parser.prototype.reset = function() { - return this.protocol = null; - }; - - Parser.prototype.process = function(data) { - var command, e, message, options, _ref; - try { + Connector.prototype.sendCommand = function (command) { if (this.protocol == null) { - if (data.match(/^!!ver:([\d.]+)$/)) { - this.protocol = 6; - } else if (message = this._parseMessage(data, ['hello'])) { - if (!message.protocols.length) { - throw new ProtocolError("no protocols specified in handshake message"); - } else if (__indexOf.call(message.protocols, PROTOCOL_7) >= 0) { - this.protocol = 7; - } else if (__indexOf.call(message.protocols, PROTOCOL_6) >= 0) { - this.protocol = 6; - } else { - throw new ProtocolError("no supported protocols found"); + return + } + return this._sendCommand(command) + } + + Connector.prototype._sendCommand = function (command) { + return this.socket.send(JSON.stringify(command)) + } + + Connector.prototype._closeOnError = function () { + this._handshakeTimeout.stop() + this._disconnectionReason = 'error' + return this.socket.close() + } + + Connector.prototype._onopen = function (e) { + var hello + this.handlers.socketConnected() + this._disconnectionReason = 'handshake-failed' + hello = { + command: 'hello', + protocols: [PROTOCOL_6, PROTOCOL_7], + } + hello.ver = Version + if (this.options.ext) { + hello.ext = this.options.ext + } + if (this.options.extver) { + hello.extver = this.options.extver + } + if (this.options.snipver) { + hello.snipver = this.options.snipver + } + this._sendCommand(hello) + return this._handshakeTimeout.start(this.options.handshake_timeout) + } + + Connector.prototype._onclose = function (e) { + this.protocol = 0 + this.handlers.disconnected(this._disconnectionReason, this._nextDelay) + return this._scheduleReconnection() + } + + Connector.prototype._onerror = function (e) {} + + Connector.prototype._onmessage = function (e) { + return this.protocolParser.process(e.data) + } + + return Connector + })() + }).call(this) +}, {'./protocol': 6}], 2: [function (require, module, exports) { + (function () { + var CustomEvents + + CustomEvents = { + bind: function (element, eventName, handler) { + if (element.addEventListener) { + return element.addEventListener(eventName, handler, false) + } else if (element.attachEvent) { + element[eventName] = 1 + return element.attachEvent('onpropertychange', function (event) { + if (event.propertyName === eventName) { + return handler() + } + }) + } else { + throw new Error('Attempt to attach custom event ' + eventName + " to something which isn't a DOMElement") + } + }, + fire: function (element, eventName) { + var event + if (element.addEventListener) { + event = document.createEvent('HTMLEvents') + event.initEvent(eventName, true, true) + return document.dispatchEvent(event) + } else if (element.attachEvent) { + if (element[eventName]) { + return element[eventName]++ + } + } else { + throw new Error('Attempt to fire custom event ' + eventName + " on something which isn't a DOMElement") + } + }, + } + + exports.bind = CustomEvents.bind + + exports.fire = CustomEvents.fire + }).call(this) +}, {}], 3: [function (require, module, exports) { + (function () { + var LessPlugin + + module.exports = LessPlugin = (function () { + LessPlugin.identifier = 'less' + + LessPlugin.version = '1.0' + + function LessPlugin (window, host) { + this.window = window + this.host = host + } + + LessPlugin.prototype.reload = function (path, options) { + if (this.window.less && this.window.less.refresh) { + if (path.match(/\.less$/i)) { + return this.reloadLess(path) + } + if (options.originalPath.match(/\.less$/i)) { + return this.reloadLess(options.originalPath) + } + } + return false + } + + LessPlugin.prototype.reloadLess = function (path) { + var link, links, _i, _len + links = (function () { + var _i, _len, _ref, _results + _ref = document.getElementsByTagName('link') + _results = [] + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + link = _ref[_i] + if (link.href && link.rel.match(/^stylesheet\/less$/i) || (link.rel.match(/stylesheet/i) && link.type.match(/^text\/(x-)?less$/i))) { + _results.push(link) } } - return this.handlers.connected(this.protocol); - } else if (this.protocol === 6) { - message = JSON.parse(data); - if (!message.length) { - throw new ProtocolError("protocol 6 messages must be arrays"); + return _results + })() + if (links.length === 0) { + return false + } + for (_i = 0, _len = links.length; _i < _len; _i++) { + link = links[_i] + link.href = this.host.generateCacheBustUrl(link.href) + } + this.host.console.log('LiveReload is asking LESS to recompile all stylesheets') + this.window.less.refresh(true) + return true + } + + LessPlugin.prototype.analyze = function () { + return { + disable: !!(this.window.less && this.window.less.refresh), + } + } + + return LessPlugin + })() + }).call(this) +}, {}], 4: [function (require, module, exports) { + (function () { + var Connector, LiveReload, Options, Reloader, Timer, + __hasProp = {}.hasOwnProperty + + Connector = require('./connector').Connector + + Timer = require('./timer').Timer + + Options = require('./options').Options + + Reloader = require('./reloader').Reloader + + exports.LiveReload = LiveReload = (function () { + function LiveReload (window) { + var k, v, _ref + this.window = window + this.listeners = {} + this.plugins = [] + this.pluginIdentifiers = {} + this.console = this.window.console && this.window.console.log && this.window.console.error ? this.window.location.href.match(/LR-verbose/) ? this.window.console : { + log: function () {}, + error: this.window.console.error.bind(this.window.console), + } : { + log: function () {}, + error: function () {}, + } + if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) { + this.console.error('LiveReload disabled because the browser does not seem to support web sockets') + return + } + if ('LiveReloadOptions' in window) { + this.options = new Options() + _ref = window['LiveReloadOptions'] + for (k in _ref) { + if (!__hasProp.call(_ref, k)) continue + v = _ref[k] + this.options.set(k, v) } - command = message[0], options = message[1]; - if (command !== 'refresh') { - throw new ProtocolError("unknown protocol 6 command"); - } - return this.handlers.message({ - command: 'reload', - path: options.path, - liveCSS: (_ref = options.apply_css_live) != null ? _ref : true - }); } else { - message = this._parseMessage(data, ['reload', 'alert']); - return this.handlers.message(message); - } - } catch (_error) { - e = _error; - if (e instanceof ProtocolError) { - return this.handlers.error(e); - } else { - throw e; - } - } - }; - - Parser.prototype._parseMessage = function(data, validCommands) { - var e, message, _ref; - try { - message = JSON.parse(data); - } catch (_error) { - e = _error; - throw new ProtocolError('unparsable JSON', data); - } - if (!message.command) { - throw new ProtocolError('missing "command" key', data); - } - if (_ref = message.command, __indexOf.call(validCommands, _ref) < 0) { - throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data); - } - return message; - }; - - return Parser; - - })(); - -}).call(this); - -},{}],7:[function(require,module,exports){ -(function() { - var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl; - - splitUrl = function(url) { - var hash, index, params; - if ((index = url.indexOf('#')) >= 0) { - hash = url.slice(index); - url = url.slice(0, index); - } else { - hash = ''; - } - if ((index = url.indexOf('?')) >= 0) { - params = url.slice(index); - url = url.slice(0, index); - } else { - params = ''; - } - return { - url: url, - params: params, - hash: hash - }; - }; - - pathFromUrl = function(url) { - var path; - url = splitUrl(url).url; - if (url.indexOf('file://') === 0) { - path = url.replace(/^file:\/\/(localhost)?/, ''); - } else { - path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/'); - } - return decodeURIComponent(path); - }; - - pickBestMatch = function(path, objects, pathFunc) { - var bestMatch, object, score, _i, _len; - bestMatch = { - score: 0 - }; - for (_i = 0, _len = objects.length; _i < _len; _i++) { - object = objects[_i]; - score = numberOfMatchingSegments(path, pathFunc(object)); - if (score > bestMatch.score) { - bestMatch = { - object: object, - score: score - }; - } - } - if (bestMatch.score > 0) { - return bestMatch; - } else { - return null; - } - }; - - numberOfMatchingSegments = function(path1, path2) { - var comps1, comps2, eqCount, len; - path1 = path1.replace(/^\/+/, '').toLowerCase(); - path2 = path2.replace(/^\/+/, '').toLowerCase(); - if (path1 === path2) { - return 10000; - } - comps1 = path1.split('/').reverse(); - comps2 = path2.split('/').reverse(); - len = Math.min(comps1.length, comps2.length); - eqCount = 0; - while (eqCount < len && comps1[eqCount] === comps2[eqCount]) { - ++eqCount; - } - return eqCount; - }; - - pathsMatch = function(path1, path2) { - return numberOfMatchingSegments(path1, path2) > 0; - }; - - IMAGE_STYLES = [ - { - selector: 'background', - styleNames: ['backgroundImage'] - }, { - selector: 'border', - styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage'] - } - ]; - - exports.Reloader = Reloader = (function() { - function Reloader(window, console, Timer) { - this.window = window; - this.console = console; - this.Timer = Timer; - this.document = this.window.document; - this.importCacheWaitPeriod = 200; - this.plugins = []; - } - - Reloader.prototype.addPlugin = function(plugin) { - return this.plugins.push(plugin); - }; - - Reloader.prototype.analyze = function(callback) { - return results; - }; - - Reloader.prototype.reload = function(path, options) { - var plugin, _base, _i, _len, _ref; - this.options = options; - if ((_base = this.options).stylesheetReloadTimeout == null) { - _base.stylesheetReloadTimeout = 15000; - } - _ref = this.plugins; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - plugin = _ref[_i]; - if (plugin.reload && plugin.reload(path, options)) { - return; - } - } - if (options.liveCSS) { - if (path.match(/\.css$/i)) { - if (this.reloadStylesheet(path)) { - return; + this.options = Options.extract(this.window.document) + if (!this.options) { + this.console.error('LiveReload disabled because it could not find its own