Added splitter demo app.
This commit is contained in:
parent
06281e85c4
commit
d65379f6c4
57
dist/ethers-wallet.js
vendored
57
dist/ethers-wallet.js
vendored
@ -34,6 +34,8 @@ utils.defineProperty(exportUtils, 'getContractAddress', function(transaction) {
|
||||
module.exports = Wallet;
|
||||
|
||||
|
||||
utils.defineProperty(Wallet, 'etherSymbol', '\uD835\uDF63');
|
||||
|
||||
utils.defineProperty(Wallet, 'getAddress', SigningKey.getAddress);
|
||||
utils.defineProperty(Wallet, 'getIcapAddress', SigningKey.getIcapAddress);
|
||||
|
||||
@ -161,21 +163,32 @@ function numberOrBN(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function zpad(buffer, length) {
|
||||
var zero = new Buffer([0]);
|
||||
while (buffer.length < length) {
|
||||
buffer = Buffer.concat([zero, buffer]);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function coderNumber(size, signed) {
|
||||
return {
|
||||
encode: function(value) {
|
||||
value = numberOrBN(value)
|
||||
// if (signed) {
|
||||
return value.toTwos(32 * 8).toArrayLike(Buffer, 'be', 32);
|
||||
// } else {
|
||||
// return value.toArrayLike(Buffer, 'be', 32);
|
||||
// }
|
||||
if (signed) {
|
||||
value = value.toTwos(32 * 8);
|
||||
} else if (value < 0) {
|
||||
value = value.toTwos(size * 8);
|
||||
}
|
||||
return value.toArrayLike(Buffer, 'be', 32);
|
||||
},
|
||||
decode: function(data, offset) {
|
||||
var value = new utils.BN(data.slice(offset, offset + 32));
|
||||
// if (signed) {
|
||||
value = value.fromTwos(32 * 8);
|
||||
// }
|
||||
if (signed) {
|
||||
value = value.fromTwos(size * 8);
|
||||
} else {
|
||||
value = value.mod((new utils.BN(2)).pow(new utils.BN(size * 8)))
|
||||
}
|
||||
return {
|
||||
consumed: 32,
|
||||
value: value,
|
||||
@ -451,7 +464,7 @@ function Interface(abi) {
|
||||
return Interface.decodeParams(
|
||||
outputTypes,
|
||||
utils.hexOrBuffer(data)
|
||||
)
|
||||
);
|
||||
};
|
||||
} else {
|
||||
result.type = 'transaction';
|
||||
@ -701,8 +714,8 @@ function Contract(provider, wallet, contractAddress, contractInterface) {
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
Promise.all([
|
||||
provider.client.sendMessage('getTransactionCount', [wallet.address, 'pending']),
|
||||
provider.client.sendMessage('getGasPrice', []),
|
||||
provider.client.sendMessage('eth_getTransactionCount', [wallet.address, 'pending']),
|
||||
provider.client.sendMessage('eth_gasPrice', []),
|
||||
]).then(function(results) {
|
||||
if (transaction.nonce == null) {
|
||||
transaction.nonce = results[0];
|
||||
@ -716,7 +729,7 @@ function Contract(provider, wallet, contractAddress, contractInterface) {
|
||||
}
|
||||
|
||||
var signedTransaction = wallet.sign(transaction);
|
||||
provider.client.sendMessage('sendRawTransaction', [signedTransaction]).then(function(txid) {
|
||||
provider.client.sendMessage('eth_sendRawTransaction', [signedTransaction]).then(function(txid) {
|
||||
resolve(txid);
|
||||
}, function(error) {
|
||||
reject(error);
|
||||
@ -871,31 +884,31 @@ var utils = require('./utils.js');
|
||||
function Randomish() {
|
||||
if (!(this instanceof Randomish)) { throw new Error('missing new'); }
|
||||
|
||||
var bits = 0;
|
||||
var weak = (randomBytes._weakCrypto || false);
|
||||
|
||||
var entropyBits = (weak ? 0: ((32 + 16) * 8));
|
||||
Object.defineProperty(this, 'entropy', {
|
||||
enumerable: true,
|
||||
get: function() { return bits; }
|
||||
get: function() { return entropyBits; }
|
||||
});
|
||||
|
||||
var weak = !!(randomBytes._weakCrypto);
|
||||
|
||||
var entropy = new aes.ModeOfOperation.cbc(
|
||||
Randomish.randomishBytes(32),
|
||||
Randomish.randomishBytes(16)
|
||||
);
|
||||
|
||||
if (!weak) { bits += (32 + 16) * 8; }
|
||||
|
||||
utils.defineProperty(this, 'feedEntropy', function(data, expectedBits) {
|
||||
utils.defineProperty(this, 'feedEntropy', function(data, expectedEntropyBits) {
|
||||
if (!data) { data = ''; }
|
||||
if (!expectedBits) { expectedBits = 0; }
|
||||
if (!expectedEntropyBits) { expectedEntropyBits = 0; }
|
||||
|
||||
if (parseInt(expectedBits) != expectedBits) { throw new Error('invalid expectedBits'); }
|
||||
if (parseInt(expectedEntropyBits) != expectedEntropyBits) {
|
||||
throw new Error('invalid expectedEntropyBits');
|
||||
}
|
||||
|
||||
data = (new Date()).getTime() + '-' + JSON.stringify(data) + '-' + data.toString();
|
||||
var hashed = utils.sha3(new Buffer(data, 'utf8'));
|
||||
|
||||
bits += expectedBits + (weak ? 0: ((32) * 8));
|
||||
entropyBits += expectedEntropyBits + (weak ? 0: ((32) * 8));
|
||||
|
||||
// Feed the hashed data and random data to the mode of operation
|
||||
entropy.encrypt(hashed.slice(0, 16));
|
||||
|
2
dist/ethers-wallet.min.js
vendored
2
dist/ethers-wallet.min.js
vendored
File diff suppressed because one or more lines are too long
377
examples/splitter/index.html
Normal file
377
examples/splitter/index.html
Normal file
@ -0,0 +1,377 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Ethereum Classic Split Tool</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #eee;
|
||||
font-family: sans-serif;
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
}
|
||||
.centerer {
|
||||
margin-left: 50%;
|
||||
}
|
||||
.centered {
|
||||
background-color: #fff;
|
||||
border-left: 1px solid #888;
|
||||
border-right: 1px solid #888;
|
||||
box-shadow: 0 0 7px #999;
|
||||
margin-left: -370px;
|
||||
padding: 20px;
|
||||
width: 700px;
|
||||
}
|
||||
p {
|
||||
text-align: justify;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
padding: 0 15px 15px 0;
|
||||
}
|
||||
td {
|
||||
padding: 0 15px 15px 0;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
border: 1px solid #555;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
input[type=password] {
|
||||
border: 1px solid #555;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.submit {
|
||||
border: 1px solid #555;
|
||||
box-shadow: 0px 0px 5px #888;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
transition: opacity 0.1s linear;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.submit:hover {
|
||||
border: 1px solid #999;
|
||||
box-shadow: 0px 0px 5px #aaa;
|
||||
}
|
||||
|
||||
.submit:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.submit.disable {
|
||||
box-shadow: none;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.submit.disable:hover {
|
||||
border: 1px solid #555;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.submit.disable:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="centerer">
|
||||
<div class="centered">
|
||||
<h1>Split Ether Classic</h1>
|
||||
<hr />
|
||||
<h2>What does this tool do?</h2>
|
||||
<p>
|
||||
This tool will take a <i>geth</i> (or crowdsale) JSON wallet, decrypt it and
|
||||
send all its funds to <a href="http://etherscan.io/address/0x3474627d4f63a678266bc17171d87f8570936622#code">this contract</a>,
|
||||
which will:
|
||||
</p>
|
||||
<ul>
|
||||
<li>On the ETH branch — send the funds back to the original address</li>
|
||||
<li>On the ETC branch — send the funds to the provided target address (for example, a <a href="https://shapeshift.io">shapeshift</a> deposit address)</li>
|
||||
</ul>
|
||||
<br />
|
||||
<h3>Disclaimer:</h3>
|
||||
<p>
|
||||
I threw this together in couple of hours, mainly to split my own ether
|
||||
and test my <i>ethers-wallet</i> library (which is still missing features
|
||||
and is itself not ready for production use). Testing has been fairly minimal
|
||||
beyond trying it on a few wallets. <b>Use this at your own risk.</b>
|
||||
</p>
|
||||
<hr />
|
||||
<h2>Check Current ETC Balance</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>ETC Address:</th>
|
||||
<td><input type="text" id="checkAddress" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<div id="submitCheck" class="submit disable">Check Classic Ether Balance</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr />
|
||||
<h2>Split ETC/ETH</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>JSON Wallet:</th>
|
||||
<td><input type="file" id="json" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Password:</th>
|
||||
<td><input type="password" id="password" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Target ETC Address:</th>
|
||||
<td><input type="text" id="targetAddress" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<div id="submitSplit" class="submit disable">Split Classic Ether</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr />
|
||||
<h2>Donations?</h2>
|
||||
<p>
|
||||
*shrug*
|
||||
</p>
|
||||
<p>
|
||||
<code>0xb2682160c482eb985ec9f3e364eec0a904c44c23</code>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="../../dist/ethers-wallet.js"></script>
|
||||
<script type="text/javascript" src="./web3.min.js"></script>
|
||||
|
||||
<!-- This greatly improves the scrypt PBKDF performance -->
|
||||
<script type="text/javascript" src="./setImmediate.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var submitCheck = document.getElementById('submitCheck');
|
||||
var submitSplit = document.getElementById('submitSplit');
|
||||
|
||||
var inputJson = document.getElementById('json');
|
||||
var inputCheckAddress = document.getElementById('checkAddress')
|
||||
var inputTargetAddress = document.getElementById('targetAddress')
|
||||
var inputPassword = document.getElementById('password');
|
||||
|
||||
var web3Classic = new Web3(new Web3.providers.HttpProvider('http://homestead-virginia-2.ethers.ws:8545'));
|
||||
function getWeb3Promise(method) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return new Promise(function(resolve, reject) {
|
||||
args.push(function(error, result) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
web3Classic.eth[method].apply(web3Classic, args);
|
||||
});
|
||||
}
|
||||
|
||||
function bigNumberToBN(bigNumber) {
|
||||
var hexValue = bigNumber.toString(16);
|
||||
if (hexValue.length % 2) { hexValue = '0' + hexValue; }
|
||||
return new Wallet.utils.BN(new Wallet.utils.Buffer(hexValue, 'hex'), 16);
|
||||
}
|
||||
|
||||
var contractAddress = '0x3474627d4f63a678266bc17171d87f8570936622';
|
||||
var contractAbi = JSON.parse('[{"constant":false,"inputs":[{"name":"balance","type":"uint256"}],"name":"claimDonations","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"isClassic","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"classicAddress","type":"address"}],"name":"split","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"}]');
|
||||
|
||||
submitCheck.onclick = function() {
|
||||
if (submitCheck.classList.contains('disable')) { return; }
|
||||
|
||||
var address = document.getElementById('checkAddress').value;
|
||||
try {
|
||||
address = Wallet.getAddress(address);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
alert('invalid address');
|
||||
return;
|
||||
}
|
||||
getWeb3Promise('getBalance', address, 'latest').then(function(balance) {
|
||||
alert('Balance: ' + web3Classic.fromWei(balance).toString(10) + ' ' + Wallet.etherSymbol);
|
||||
}, function(error) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
alert('Faied to get balance');
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
console.log('check', address);
|
||||
}
|
||||
|
||||
submitSplit.onclick = function() {
|
||||
if (submitSplit.classList.contains('disable')) { return; }
|
||||
|
||||
function done() {
|
||||
submitSplit.textContent = 'Split Classic Ether';
|
||||
inputJson.readOnly = false;
|
||||
inputPassword.readOnly = false;
|
||||
inputTargetAddress.readOnly = false;
|
||||
checkSplit();
|
||||
}
|
||||
|
||||
inputJson.readOnly = true;
|
||||
inputPassword.readOnly = true;
|
||||
inputTargetAddress.readOnly = true;
|
||||
|
||||
submitSplit.classList.add('disable');
|
||||
|
||||
var files = inputJson.files;
|
||||
if (files.length !== 1) {
|
||||
alert('No wallet found');
|
||||
return done();
|
||||
}
|
||||
|
||||
var password = new Wallet.utils.Buffer(inputPassword.value, 'utf8');
|
||||
|
||||
var targetAddress = document.getElementById('targetAddress').value;
|
||||
try {
|
||||
targetAddress = Wallet.getAddress(targetAddress);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
alert('invalid target address');
|
||||
return done();
|
||||
}
|
||||
|
||||
function processWallet(wallet) {
|
||||
if (wallet.address === targetAddress) {
|
||||
alert('Wallet address and target address cannot be the same.');
|
||||
return done();
|
||||
}
|
||||
|
||||
submitSplit.textContent = 'Decrypted \u2014 Processing (please wait)';
|
||||
|
||||
var contract = wallet.getContract(contractAddress, contractAbi);
|
||||
var data = contract.interface.split(targetAddress).data;
|
||||
|
||||
var transaction = {
|
||||
to: contractAddress,
|
||||
data: data
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
getWeb3Promise('getBalance', wallet.address, 'latest'),
|
||||
getWeb3Promise('getTransactionCount', wallet.address, 'latest'),
|
||||
getWeb3Promise('getGasPrice'),
|
||||
getWeb3Promise('estimateGas', transaction)
|
||||
]).then(function(results) {
|
||||
var balance = results[0];
|
||||
var transactionCount = results[1];
|
||||
var gasPrice = results[2];
|
||||
var gasEstimate = results[3] + 21000;
|
||||
|
||||
transaction.gasPrice = '0x' + gasPrice.toString(16);
|
||||
transaction.nonce = transactionCount;
|
||||
transaction.gasLimit = bigNumberToBN(gasEstimate);
|
||||
|
||||
var toSend = bigNumberToBN(balance).sub(bigNumberToBN(gasPrice).mul(bigNumberToBN(gasEstimate)));
|
||||
transaction.value = toSend;
|
||||
|
||||
var accept = confirm('Balance: ' + web3Classic.fromWei(balance).toString(10) + ' ' + Wallet.etherSymbol + '. Are you sure you want to split Classic Ether to ' + targetAddress + '?');
|
||||
if (accept) {
|
||||
var signedTransaction = wallet.sign(transaction);
|
||||
function showError(error) {
|
||||
done();
|
||||
console.log(error);
|
||||
alert('Error sending transaction');
|
||||
}
|
||||
getWeb3Promise('sendRawTransaction', signedTransaction).then(function(txid) {
|
||||
if (txid.match(/^0x0+$/)) {
|
||||
showError(new Error('txid was zero'));
|
||||
return;
|
||||
}
|
||||
done();
|
||||
console.log('txid:' + txid);
|
||||
alert('Success \u2014 ' + txid);
|
||||
}, function(error) {
|
||||
showError(error);
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}, function(error) {
|
||||
done();
|
||||
console.log(error);
|
||||
alert('Error: Faied to fetch info');
|
||||
});
|
||||
}
|
||||
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onload = function(e) {
|
||||
var json = e.target.result;
|
||||
if (Wallet.isCrowdsaleWallet(json)) {
|
||||
var wallet = Wallet.decryptCrowdsale(json, password);
|
||||
processWallet(wallet);
|
||||
} else if (Wallet.isValidWallet(json)) {
|
||||
Wallet.decrypt(json, password, function(error, wallet, progress) {
|
||||
if (error) {
|
||||
done();
|
||||
console.log(error);
|
||||
if (error.message === 'invalid password') {
|
||||
alert('Wrong Password');
|
||||
} else {
|
||||
alert('Error Decrypting Wallet');
|
||||
}
|
||||
} else if (wallet) {
|
||||
processWallet(wallet);
|
||||
} else {
|
||||
submitSplit.textContent = 'Decrypting \u2014 ' + (parseInt(progress * 100) + '%');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('unknown walet format');
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
fileReader.readAsText(files[0]);
|
||||
}
|
||||
|
||||
inputCheckAddress.oninput = function() {
|
||||
try {
|
||||
Wallet.getAddress(inputCheckAddress.value);
|
||||
submitCheck.classList.remove('disable');
|
||||
} catch (error) {
|
||||
submitCheck.classList.add('disable');
|
||||
}
|
||||
}
|
||||
|
||||
function checkSplit() {
|
||||
console.log('foo');
|
||||
try {
|
||||
Wallet.getAddress(inputTargetAddress.value);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
submitSplit.classList.add('disable');
|
||||
return;
|
||||
}
|
||||
if (!inputJson.files || inputJson.files.length !== 1) {
|
||||
console.log(inputJson);
|
||||
submitSplit.classList.add('disable');
|
||||
return;
|
||||
}
|
||||
submitSplit.classList.remove('disable');
|
||||
}
|
||||
|
||||
inputTargetAddress.oninput = checkSplit;
|
||||
inputJson.onchange = checkSplit;
|
||||
|
||||
var check
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
175
examples/splitter/setImmediate.js
Normal file
175
examples/splitter/setImmediate.js
Normal file
@ -0,0 +1,175 @@
|
||||
(function (global, undefined) {
|
||||
"use strict";
|
||||
|
||||
if (global.setImmediate) {
|
||||
return;
|
||||
}
|
||||
|
||||
var nextHandle = 1; // Spec says greater than zero
|
||||
var tasksByHandle = {};
|
||||
var currentlyRunningATask = false;
|
||||
var doc = global.document;
|
||||
var setImmediate;
|
||||
|
||||
function addFromSetImmediateArguments(args) {
|
||||
tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args);
|
||||
return nextHandle++;
|
||||
}
|
||||
|
||||
// This function accepts the same arguments as setImmediate, but
|
||||
// returns a function that requires no arguments.
|
||||
function partiallyApplied(handler) {
|
||||
var args = [].slice.call(arguments, 1);
|
||||
return function() {
|
||||
if (typeof handler === "function") {
|
||||
handler.apply(undefined, args);
|
||||
} else {
|
||||
(new Function("" + handler))();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function runIfPresent(handle) {
|
||||
// From the spec: "Wait until any invocations of this algorithm started before this one have completed."
|
||||
// So if we're currently running a task, we'll need to delay this invocation.
|
||||
if (currentlyRunningATask) {
|
||||
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
|
||||
// "too much recursion" error.
|
||||
setTimeout(partiallyApplied(runIfPresent, handle), 0);
|
||||
} else {
|
||||
var task = tasksByHandle[handle];
|
||||
if (task) {
|
||||
currentlyRunningATask = true;
|
||||
try {
|
||||
task();
|
||||
} finally {
|
||||
clearImmediate(handle);
|
||||
currentlyRunningATask = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clearImmediate(handle) {
|
||||
delete tasksByHandle[handle];
|
||||
}
|
||||
|
||||
function installNextTickImplementation() {
|
||||
setImmediate = function() {
|
||||
var handle = addFromSetImmediateArguments(arguments);
|
||||
process.nextTick(partiallyApplied(runIfPresent, handle));
|
||||
return handle;
|
||||
};
|
||||
}
|
||||
|
||||
function canUsePostMessage() {
|
||||
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
|
||||
// where `global.postMessage` means something completely different and can't be used for this purpose.
|
||||
if (global.postMessage && !global.importScripts) {
|
||||
var postMessageIsAsynchronous = true;
|
||||
var oldOnMessage = global.onmessage;
|
||||
global.onmessage = function() {
|
||||
postMessageIsAsynchronous = false;
|
||||
};
|
||||
global.postMessage("", "*");
|
||||
global.onmessage = oldOnMessage;
|
||||
return postMessageIsAsynchronous;
|
||||
}
|
||||
}
|
||||
|
||||
function installPostMessageImplementation() {
|
||||
// Installs an event handler on `global` for the `message` event: see
|
||||
// * https://developer.mozilla.org/en/DOM/window.postMessage
|
||||
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
|
||||
|
||||
var messagePrefix = "setImmediate$" + Math.random() + "$";
|
||||
var onGlobalMessage = function(event) {
|
||||
if (event.source === global &&
|
||||
typeof event.data === "string" &&
|
||||
event.data.indexOf(messagePrefix) === 0) {
|
||||
runIfPresent(+event.data.slice(messagePrefix.length));
|
||||
}
|
||||
};
|
||||
|
||||
if (global.addEventListener) {
|
||||
global.addEventListener("message", onGlobalMessage, false);
|
||||
} else {
|
||||
global.attachEvent("onmessage", onGlobalMessage);
|
||||
}
|
||||
|
||||
setImmediate = function() {
|
||||
var handle = addFromSetImmediateArguments(arguments);
|
||||
global.postMessage(messagePrefix + handle, "*");
|
||||
return handle;
|
||||
};
|
||||
}
|
||||
|
||||
function installMessageChannelImplementation() {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = function(event) {
|
||||
var handle = event.data;
|
||||
runIfPresent(handle);
|
||||
};
|
||||
|
||||
setImmediate = function() {
|
||||
var handle = addFromSetImmediateArguments(arguments);
|
||||
channel.port2.postMessage(handle);
|
||||
return handle;
|
||||
};
|
||||
}
|
||||
|
||||
function installReadyStateChangeImplementation() {
|
||||
var html = doc.documentElement;
|
||||
setImmediate = function() {
|
||||
var handle = addFromSetImmediateArguments(arguments);
|
||||
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
|
||||
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
|
||||
var script = doc.createElement("script");
|
||||
script.onreadystatechange = function () {
|
||||
runIfPresent(handle);
|
||||
script.onreadystatechange = null;
|
||||
html.removeChild(script);
|
||||
script = null;
|
||||
};
|
||||
html.appendChild(script);
|
||||
return handle;
|
||||
};
|
||||
}
|
||||
|
||||
function installSetTimeoutImplementation() {
|
||||
setImmediate = function() {
|
||||
var handle = addFromSetImmediateArguments(arguments);
|
||||
setTimeout(partiallyApplied(runIfPresent, handle), 0);
|
||||
return handle;
|
||||
};
|
||||
}
|
||||
|
||||
// If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
|
||||
var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
|
||||
attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
|
||||
|
||||
// Don't get fooled by e.g. browserify environments.
|
||||
if ({}.toString.call(global.process) === "[object process]") {
|
||||
// For Node.js before 0.9
|
||||
installNextTickImplementation();
|
||||
|
||||
} else if (canUsePostMessage()) {
|
||||
// For non-IE10 modern browsers
|
||||
installPostMessageImplementation();
|
||||
|
||||
} else if (global.MessageChannel) {
|
||||
// For web workers, where supported
|
||||
installMessageChannelImplementation();
|
||||
|
||||
} else if (doc && "onreadystatechange" in doc.createElement("script")) {
|
||||
// For IE 6–8
|
||||
installReadyStateChangeImplementation();
|
||||
|
||||
} else {
|
||||
// For older browsers
|
||||
installSetTimeoutImplementation();
|
||||
}
|
||||
|
||||
attachTo.setImmediate = setImmediate;
|
||||
attachTo.clearImmediate = clearImmediate;
|
||||
}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
|
5
examples/splitter/web3.min.js
vendored
Normal file
5
examples/splitter/web3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user