diff --git a/.travis.yml b/.travis.yml index 2576695c75..7ee87612d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: node_js node_js: - stable script: - - npm run lint && npm run csslint && npm run test && npm run downloadsolc && npm run make-mock-compiler && npm run build + - npm run lint && npm run test && npm run downloadsolc && npm run make-mock-compiler && npm run build - ./ci/browser_tests.sh deploy: provider: script diff --git a/assets/css/browser-solidity.css b/assets/css/browser-solidity.css index b09eb240b6..7086c4f0fe 100644 --- a/assets/css/browser-solidity.css +++ b/assets/css/browser-solidity.css @@ -136,11 +136,6 @@ body { box-sizing: border-box; } -#output { - display: block; - padding: 1em; -} - #header { font-size: 13px; height: 100%; @@ -166,6 +161,8 @@ body { list-style: none; margin: 0; padding: 0; + display: flex; + justify-content: space-between; } #header #options li.active { @@ -185,7 +182,6 @@ body { #header #optionViews > div { display: none; - padding: .5em .5em .5em; } #header #optionViews.txView #txView { @@ -198,7 +194,6 @@ body { #header #optionViews.publishView #publishView { display: block; - padding: 3em; } #header #optionViews.envView #envView { @@ -207,7 +202,6 @@ body { #header #optionViews.debugView #debugView { display: block; - padding: 3em; } #header #optionViews.verificationView #verificationView { @@ -216,8 +210,6 @@ body { #header #optionViews.staticanalysisView #staticanalysisView { display: block; - padding: 3em; - line-height: 1.5em; } #header #optionViews.txView input, @@ -264,12 +256,12 @@ body { #publishView button { background-color: #C6CFF7; font-size: 12px; - padding: 0.25em; margin-bottom: .5em; color: black; border:0 none; border-radius: 3px; width: 8em; + height: 20px; margin-right: 1em; cursor: pointer; } @@ -303,24 +295,13 @@ body { display: block; } -#header .origin, -#header #executionContext { +#header .origin { display: block; word-wrap: break-word; padding: 1.5em; font-weight: bold; } -#selectExEnv { - text-decoration: none; - background-color: #C6CFF7; - cursor: pointer; - font-size: 12px; - color: black; - border-radius: 3px; - border: 0 none; -} - #header #versionSelector { text-decoration: none; background-color: #C6CFF7; @@ -331,15 +312,6 @@ body { border: 0 none; } -.col1 { - width: 30%; - float: left; -} -.col2 { - width: 70%; - float: left; -} - #formalVerificationInput { height: 4.5em; width: 100%; @@ -354,18 +326,6 @@ body { display: none; } -.udapp .contract > .title { - cursor:pointer; -} - -.udapp .contract > .title:before { - content: "\25BC"; - opacity: 0.5; - margin-right: 0.4em; - font-size: 10px; - margin-top: 0.2em; -} - .contract.hidesub > .title:before { content: "\25B6"; } @@ -380,11 +340,13 @@ body { overflow: auto; display: block; clear: both; - margin: 1.5em; + margin: .5em .5em 0 .5em; + padding: .5em; font-weight: bold; } .crow #txorigin { + margin-left: 0.5em; text-decoration: none; background-color: #C6CFF7; cursor: pointer; @@ -412,9 +374,10 @@ body { word-wrap: break-word; cursor: pointer; position: relative; - margin: 0.5em; - border-radius: 0.6em; - padding: 1em 1.5em; + margin: 0.5em 0 1em 0; + border-radius: 5px; + line-height: 20px; + padding: 8px 15px; } .sol.error pre, @@ -438,11 +401,13 @@ body { } .sol.error { - background-color: rgba(255, 0, 0, 0.4); + background-color: hsla(0, 100%, 75%, 0.1); + border: .2em dotted #FF8080; } .sol.warning { - background-color: rgba(210, 202, 36, 0.4); + background-color: hsla(59, 56%, 78%, 0.5); + border: .2em dotted #ffbd01; } #ghostbar { @@ -465,7 +430,7 @@ body { bottom: 0; cursor: col-resize; z-index: 999; - border-right: 2px solid #C6CFF7; + border-right: 2px solid hsla(215, 81%, 79%, .3); } #editor .ace-tm .ace_gutter, @@ -475,11 +440,10 @@ body { } input[readonly] { - padding: .4em; - border: 1px solid #ccc; - box-sizing: border-box; display: block; width: 100%; + height: 7px; + padding: .8em; } input[type="file"] { diff --git a/assets/css/universal-dapp.css b/assets/css/universal-dapp.css index a63532bd76..b7571ce29d 100644 --- a/assets/css/universal-dapp.css +++ b/assets/css/universal-dapp.css @@ -1,6 +1,4 @@ .udapp { - padding: .5em; - border: 1px dotted #4D5686; position: relative; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); box-sizing: border-box; @@ -16,7 +14,6 @@ color: #7A7AE2; } -.udapp input, .udapp button, .udapp-setup textarea, .udapp-setup button { @@ -47,30 +44,7 @@ .udapp .create { overflow: auto; - margin-bottom: 1em; -} - -.udapp .title { - margin-bottom: 0.4em; - padding: 1em; - background-color: #C6CFF7; - font-weight: bold; - display: flex; - justify-content: space-between; - word-wrap: break-word; - position: relative; - border-radius: 3px; -} - -.udapp .definitionTitle { - background-color: #C6CFD9; -} - -.udapp .title:hover { - opacity: 0.8; -} -.udapp .title .size { - font-weight: normal; + margin: 1em; } .udapp .output { @@ -205,12 +179,8 @@ border-radius: 3px; } -.udapp input { - border-left: 0 none; -} - .udapp button { - background-color: #666; + padding: .36em; color: #4C4B4B; cursor: pointer; overflow: hidden; @@ -310,15 +280,24 @@ } .udapp .legend { - font-size: 12px; - float: left; - color: #666; + background-color: white; + line-height: 20px; + border: .2em dotted lightGrey; + padding: 8px 15px; + border-radius: 5px; + margin-bottom: 1em; + display: flex; + justify-content: initial; + flex-wrap: wrap; } .udapp .legend div { display: inline-block; margin-right: 0.5em; - margin-bottom: 1em; + display: flex; + align-items: center; + line-height: 0px; + padding: 5px; } .udapp .legend div:before { @@ -329,6 +308,7 @@ height: 1em; margin-right: 0.5em; width: 1em; + border-radius: 50%; } .udapp .legend .publish:before { diff --git a/ci/browser_tests.sh b/ci/browser_tests.sh index 1a8e1928f0..c49d154cef 100755 --- a/ci/browser_tests.sh +++ b/ci/browser_tests.sh @@ -19,8 +19,11 @@ while [ ! -f "$SAUCECONNECT_READYFILE" ]; do sleep .5 done -# npm run browser-test-remote-parallel || TEST_EXITCODE=1 -npm run nightwatch_remote_parallel || TEST_EXITCODE=1 +npm run nightwatch_remote_chrome || TEST_EXITCODE=1 +npm run nightwatch_remote_firefox || TEST_EXITCODE=1 +npm run nightwatch_remote_safari || TEST_EXITCODE=1 +# npm run nightwatch_remote_ie || TEST_EXITCODE=1 +# npm run nightwatch_remote_parallel || TEST_EXITCODE=1 node ci/sauceDisconnect.js "$SAUCECONNECT_USERNAME" "$SAUCECONNECT_ACCESSKEY" "$SAUCECONNECT_JOBIDENTIFIER" diff --git a/index.html b/index.html index e882ab0847..85d142e603 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,6 @@ Remix @@ -57,6 +55,7 @@
+ diff --git a/nightwatch.js b/nightwatch.js index 6a513c6f6d..c5da94b94e 100644 --- a/nightwatch.js +++ b/nightwatch.js @@ -50,8 +50,8 @@ module.exports = { 'desiredCapabilities': { 'browserName': 'safari', 'javascriptEnabled': true, - 'platform': 'OS X 10.10', - 'version': '8.0', + 'platform': 'OS X 10.11', + 'version': '10.0', 'acceptSslCerts': true, 'build': 'build-' + TRAVIS_JOB_NUMBER, 'tunnel-identifier': 'browsersolidity_tests_' + TRAVIS_JOB_NUMBER @@ -62,8 +62,9 @@ module.exports = { 'desiredCapabilities': { 'browserName': 'internet explorer', 'javascriptEnabled': true, + 'platform': 'Windows 10', 'acceptSslCerts': true, - 'version': '11', + 'version': '11.103', 'build': 'build-' + TRAVIS_JOB_NUMBER, 'tunnel-identifier': 'browsersolidity_tests_' + TRAVIS_JOB_NUMBER } diff --git a/package.json b/package.json index 04d3b4b10d..83cc675a59 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "babelify": "^7.3.0", "brace": "^0.8.0", "browserify-reload": "^1.0.3", + "clipboard-copy": "^1.2.0", "csjs-inject": "^1.0.1", "csslint": "^1.0.2", "ethereum-remix": "https://github.com/ethereum/remix", @@ -92,24 +93,39 @@ }, "browserify": { "transform": [ - ["babelify", { - "sourceMapsAbsolute": false, - "sourceMaps": true, - "plugins": [ - ["fast-async", { - "runtimePattern": null, - "compiler": { - "es7": true, - "noRuntime": true, - "promises": true, - "wrapAwait": true - } - }], - ["yo-yoify"], ["transform-object-assign"] - ], - "presets": ["es2015"] - }], - ["uglifyify"] + [ + "babelify", + { + "sourceMapsAbsolute": false, + "sourceMaps": true, + "plugins": [ + [ + "fast-async", + { + "runtimePattern": null, + "compiler": { + "es7": true, + "noRuntime": true, + "promises": true, + "wrapAwait": true + } + } + ], + [ + "yo-yoify" + ], + [ + "transform-object-assign" + ] + ], + "presets": [ + "es2015" + ] + } + ], + [ + "uglifyify" + ] ] }, "scripts": { diff --git a/src/app.js b/src/app.js index 8ec8f06f92..c8c1931f98 100644 --- a/src/app.js +++ b/src/app.js @@ -29,6 +29,29 @@ var FilePanel = require('./app/file-panel') var examples = require('./app/example-contracts') +var contractTab = require('./app/contract-tab.js') +var settingsTab = require('./app/settings-tab.js') +var analysisTab = require('./app/analysis-tab.js') +var debuggerTab = require('./app/debugger-tab.js') +var filesTab = require('./app/files-tab.js') +/* ---------------------------------------------- + TABS - Righthand pannel +---------------------------------------------- */ +var contractView = contractTab() +document.querySelector('#optionViews').appendChild(contractView) + +var settingsView = settingsTab() +document.querySelector('#optionViews').appendChild(settingsView) + +var analysisView = analysisTab() +document.querySelector('#optionViews').appendChild(analysisView) + +var debuggerView = debuggerTab() +document.querySelector('#optionViews').appendChild(debuggerView) + +var filesView = filesTab() +document.querySelector('#optionViews').appendChild(filesView) + // The event listener needs to be registered as early as possible, because the // parent will send the message upon the "load" event. var filesToLoad = null @@ -406,12 +429,6 @@ var run = function () { return $filesEl.position().left } - function activeFilePos () { - var el = $filesEl.find('.active') - var l = el.position().left - return l - } - function reAdjust () { if (widthOfList() + getLeftPosi() > widthOfVisible()) { $scrollerRight.fadeIn('fast') @@ -785,7 +802,8 @@ var run = function () { } } var staticanalysis = new StaticAnalysis(staticAnalysisAPI, compiler.event) - $('#staticanalysisView').append(staticanalysis.render()) + var node = document.getElementById('staticanalysisView') + node.insertBefore(staticanalysis.render(), node.childNodes[0]) // ----------------- autoCompile ----------------- var autoCompile = document.querySelector('#autoCompile').checked @@ -876,7 +894,7 @@ var run = function () { }) compiler.event.register('loadingCompiler', this, function (url, usingWorker) { - setVersionText(usingWorker ? '(loading using worker)' : '( Loading... Please, wait a moment. )') + setVersionText(usingWorker ? '(loading using worker)' : ' Loading... please, wait a moment! ') }) compiler.event.register('compilerLoaded', this, function (version) { @@ -956,7 +974,7 @@ var run = function () { loadVersion($('#versionSelector').val()) }) - var header = new Option('Click to select new compiler version') + var header = new Option('Select new compiler version') header.disabled = true header.selected = true $('#versionSelector').append(header) diff --git a/src/app/analysis-tab.js b/src/app/analysis-tab.js new file mode 100644 index 0000000000..810638c1d1 --- /dev/null +++ b/src/app/analysis-tab.js @@ -0,0 +1,41 @@ +var yo = require('yo-yo') + +// -------------- styling ---------------------- +var csjs = require('csjs-inject') +var styleGuide = require('./style-guide') +var styles = styleGuide() + +var css = csjs` + .analysisTabView { + padding: 2%; + margin-top: 1em; + } + .infoBox extends ${styles.infoTextBox} { + margin-bottom: 1em; + } + .textBox extends ${styles.textBoxL} { + margin-bottom: 1em; + } +` + +module.exports = analysisTab + +function analysisTab () { + return yo` +
+
+ This tab provides support for formal verification of Solidity contracts.
+ This feature is still in development and thus also not yet well documented, + but you can find some information + here. + The compiler generates input to be verified + (or report errors). Please paste the text below into + http://why3.lri.fr/try/ + to actually perform the verification. + We plan to support direct integration in the future. +
+ +
+
+ ` +} diff --git a/src/app/contract-tab.js b/src/app/contract-tab.js new file mode 100644 index 0000000000..86835fbf38 --- /dev/null +++ b/src/app/contract-tab.js @@ -0,0 +1,93 @@ +var yo = require('yo-yo') + +// -------------- styling ---------------------- +var csjs = require('csjs-inject') +var styleGuide = require('./style-guide') +var styles = styleGuide() + +var css = csjs` + .contractTabView { + padding: 2%; + } + .crow { + margin-top: 1em; + display: flex; + } + .col1 extends ${styles.titleL} { + width: 30%; + float: left; + align-self: center; + } + .col1_1 extends ${styles.titleM} { + width: 30%; + float: left; + align-self: center; + } + .col2 extends ${styles.textBoxL}{ + width: 70%; + height: 7px; + float: left; + padding: .8em; + } + .select extends ${styles.dropdown} { + width: 70%; + float: left; + text-align: center; + } + .contract { + display: block; + margin: 4em 0 2em 0; + } +` + +module.exports = contractTab + +function contractTab () { + return yo` +
+
+
+ Execution environment +
+ +
+
+
Transaction origin
+ +
+
+
Transaction gas limit
+ +
+
+
Gas Price
+ +
+
+
Value
+ +
+
+
+ ` +} diff --git a/src/app/debugger-tab.js b/src/app/debugger-tab.js new file mode 100644 index 0000000000..0aaeb87a44 --- /dev/null +++ b/src/app/debugger-tab.js @@ -0,0 +1,16 @@ +var yo = require('yo-yo') + +// -------------- styling ---------------------- +var csjs = require('csjs-inject') + +var css = csjs` + .debuggerTabView { + padding: 2%; + } +` + +module.exports = debuggerTab + +function debuggerTab () { + return yo`
` +} diff --git a/src/app/editor.js b/src/app/editor.js index 19475be4d7..6c770a9bc8 100644 --- a/src/app/editor.js +++ b/src/app/editor.js @@ -19,8 +19,7 @@ var css = csjs` } .ace-editor { top : 4px; - border-top : 3px solid transparent; - font-size : 15px; + font-size : 2vmin; width : 100%; } ` diff --git a/src/app/execution-context.js b/src/app/execution-context.js index 46e36aea6e..07899c406f 100644 --- a/src/app/execution-context.js +++ b/src/app/execution-context.js @@ -136,7 +136,7 @@ function ExecutionContext () { DROPDOWN --------------------------------------------------------------------------- */ - var selectExEnv = document.querySelector('#selectExEnv') + var selectExEnv = document.querySelector('#selectExEnvOptions') selectExEnv.addEventListener('change', function (event) { if (!executionContextChange(selectExEnv.options[selectExEnv.selectedIndex].value)) { selectExEnv.value = executionContext diff --git a/src/app/file-panel.js b/src/app/file-panel.js index a296e25804..1e7f9da311 100644 --- a/src/app/file-panel.js +++ b/src/app/file-panel.js @@ -55,10 +55,10 @@ var css = csjs` } .dragbar { position : relative; - top : 6px; + top : 4px; cursor : col-resize; z-index : 999; - border-right : 2px solid #C6CFF7; + border-right : 2px solid hsla(215, 81%, 79%, .3); } .ghostbar { width : 3px; diff --git a/src/app/files-tab.js b/src/app/files-tab.js new file mode 100644 index 0000000000..c26c687945 --- /dev/null +++ b/src/app/files-tab.js @@ -0,0 +1,45 @@ +var yo = require('yo-yo') + +// -------------- styling ---------------------- +var csjs = require('csjs-inject') +var styleGuide = require('./style-guide') +var styles = styleGuide() + +var css = csjs` + .filesTabView { + padding: 2%; + } + .crow { + margin-top: 1em; + display: flex; + } + .infoBox extends ${styles.infoTextBox} { + margin-top: 2em; + } +` + +module.exports = filesTab + +function filesTab () { + return yo` +
+
+ + Publish all open files to an anonymous github gist.
+
+
+ + Copy all files to another instance of Browser-solidity. +
+
You can also load a gist by adding the following + #gist=GIST_ID + to your url, where GIST_ID is the id of the gist to load. +
+
+ ` +} diff --git a/src/app/renderer.js b/src/app/renderer.js index 07db365e81..785a564b74 100644 --- a/src/app/renderer.js +++ b/src/app/renderer.js @@ -4,6 +4,40 @@ var $ = require('jquery') var utils = require('./utils') +// -------------- styling ---------------------- +var csjs = require('csjs-inject') +var styleGuide = require('./style-guide') +var styles = styleGuide() + +var css = csjs` + .col2 { + width: 70%; + float: left; + } + .col1 extends ${styles.titleL} { + width: 30%; + float: left; + } + .toggleText { + text-decoration: underline; + margin-left: 2px; + font-size: .9em; + } + .toggle { + font-size: 1.1em; + color: ${styles.colors.blue}; + margin: 1em; + cursor: pointer; + font-weight: 400; + display: flex; + align-items: center; + } + .toggle:hover { + opacity: .8; + } +` +// ---------------------------------------------- + function Renderer (appAPI, formalVerificationEvent, compilerEvent) { this.appAPI = appAPI var self = this @@ -96,16 +130,17 @@ Renderer.prototype.contracts = function (data, source) { } var tableRowItems = function (first, second, cls) { + second.get(0).classList.add(styles.textBoxL) // replace
 styling with textBoxL
     return $('
') .addClass(cls) - .append($('
').append(first)) - .append($('
').append(second)) + .append($(`
`).append(first)) + .append($(`
`).append(second)) } var tableRow = function (description, data) { return tableRowItems( $('').text(description), - $('').val(data)) + $(``).val(data)) } var preRow = function (description, data) { @@ -219,9 +254,25 @@ Renderer.prototype.contracts = function (data, source) { var detailsOpen = {} var getDetails = function (contract, source, contractName) { - var button = $('') + var button = $(`
Contract details (bytecode, interface etc.)
`) var details = $('
') + if (contract.bytecode) { + details.append(preRow('Bytecode', contract.bytecode)) + } + + details.append(preRow('Interface', contract['interface'])) + + if (contract.bytecode) { + details.append(preRow('Web3 deploy', gethDeploy(contractName.toLowerCase(), contract['interface'], contract.bytecode), 'deploy')) + + // check if there's a metadata hash appended + var metadataHash = retrieveMetadataHash(contract.bytecode) + if (metadataHash) { + details.append(preRow('Metadata location', 'bzzr://' + metadataHash)) + } + } + if (contract.metadata) { details.append(preRow('Metadata', contract.metadata)) } @@ -264,22 +315,6 @@ Renderer.prototype.contracts = function (data, source) { var self = this var renderOutputModifier = function (contractName, $contractOutput) { var contract = data.contracts[contractName] - if (contract.bytecode) { - $contractOutput.append(tableRow('Bytecode', contract.bytecode)) - } - - $contractOutput.append(tableRow('Interface', contract['interface'])) - - if (contract.bytecode) { - $contractOutput.append(preRow('Web3 deploy', gethDeploy(contractName.toLowerCase(), contract['interface'], contract.bytecode), 'deploy')) - - // check if there's a metadata hash appended - var metadataHash = retrieveMetadataHash(contract.bytecode) - if (metadataHash) { - $contractOutput.append(tableRow('Metadata location', 'bzzr://' + metadataHash)) - } - } - var ctrSource = self.appAPI.currentCompiledSourceCode() if (ctrSource) { $contractOutput.append(getDetails(contract, ctrSource, contractName)) @@ -306,9 +341,8 @@ Renderer.prototype.contracts = function (data, source) { } }) - $contractOutput.find('.title').click(function (ev) { $(this).closest('.contract').toggleClass('hidesub') }) $('#output').append($contractOutput) - $('.col2 input,textarea').click(function () { this.select() }) + $('.' + css.col2 + ' input,textarea').click(function () { this.select() }) } module.exports = Renderer diff --git a/src/app/settings-tab.js b/src/app/settings-tab.js new file mode 100644 index 0000000000..1a5f076c27 --- /dev/null +++ b/src/app/settings-tab.js @@ -0,0 +1,69 @@ +var yo = require('yo-yo') + +// -------------- styling ---------------------- +var csjs = require('csjs-inject') +var styleGuide = require('./style-guide') +var styles = styleGuide() + +var css = csjs` + .settingsTabView { + padding: 2%; + display: flex; + } + .info extends ${styles.infoTextBox} { + margin-bottom: 2em; + } + .crow { + margin-top: 1em; + display: flex; + } + .select extends ${styles.dropdown} { + float: left; + max-width: 90%; + } + .button extends ${styles.button} { + background-color: #C6CFF7; + width: 100%; + align-self: center; + text-align: -webkit-center; + } + .col1 extends ${styles.titleL} { + float: left; + align-self: center; + } + .checkboxText { + margin-left: 3px; + } +} +` +module.exports = settingsTab + +function settingsTab () { + return yo` +
+
+
Your current Solidity version is
+
+
+
+ +
+
+
+ Text Wrap +
+
+
+ Enable Optimization +
+
+
+ Auto Compile +
+
+
+
Compile
+
+
+ ` +} diff --git a/src/app/staticanalysis/modules/gasCosts.js b/src/app/staticanalysis/modules/gasCosts.js index 974d0da6d3..3f542bfc80 100644 --- a/src/app/staticanalysis/modules/gasCosts.js +++ b/src/app/staticanalysis/modules/gasCosts.js @@ -1,5 +1,5 @@ -var name = 'gas costs' -var desc = 'Warn if the gas requiremets of functions are too high.' +var name = 'gas costs: ' +var desc = 'warn if the gas requiremets of functions are too high' var categories = require('./categories') function gasCosts () { diff --git a/src/app/staticanalysis/modules/thisLocal.js b/src/app/staticanalysis/modules/thisLocal.js index 663dc0a1c5..a0fbb316fe 100644 --- a/src/app/staticanalysis/modules/thisLocal.js +++ b/src/app/staticanalysis/modules/thisLocal.js @@ -1,5 +1,5 @@ -var name = 'this on local' -var desc = 'Invocation of local functions via this' +var name = 'this on local: ' +var desc = 'invocation of local functions via this' var categories = require('./categories') var common = require('./staticAnalysisCommon') diff --git a/src/app/staticanalysis/modules/txOrigin.js b/src/app/staticanalysis/modules/txOrigin.js index bd82d01abc..36d8913237 100644 --- a/src/app/staticanalysis/modules/txOrigin.js +++ b/src/app/staticanalysis/modules/txOrigin.js @@ -1,4 +1,4 @@ -var name = 'tx origin' +var name = 'tx origin: ' var desc = 'warn if tx.origin is used' var categories = require('./categories') diff --git a/src/app/staticanalysis/staticAnalysisView.js b/src/app/staticanalysis/staticAnalysisView.js index ff163d40e7..aa32f80b37 100644 --- a/src/app/staticanalysis/staticAnalysisView.js +++ b/src/app/staticanalysis/staticAnalysisView.js @@ -7,9 +7,11 @@ var csjs = require('csjs-inject') var css = csjs` .analysis { - margin-top: 2em; font-height: 1.5em; } + .result { + margin-top: 1em; + } ` function staticAnalysisView (appAPI, compilerEvent) { @@ -33,17 +35,19 @@ function staticAnalysisView (appAPI, compilerEvent) { staticAnalysisView.prototype.render = function () { var self = this - var view = yo`
- Static Analysis - -
- ${this.modulesView} -
-
- + var view = yo` +
+ Static Analysis
+ +
+ ${this.modulesView} +
+
+ +
+
-
-
` + ` if (!this.view) { this.view = view } diff --git a/src/app/style-guide.js b/src/app/style-guide.js new file mode 100644 index 0000000000..8c00e2e08c --- /dev/null +++ b/src/app/style-guide.js @@ -0,0 +1,153 @@ +var csjs = require('csjs-inject') + +module.exports = styleGuide + +function styleGuide () { + /* -------------------------------------------------------------------------- + COLORS + -------------------------------------------------------------------------- */ + var colors = { + blue: '#9393bf', + lightBlue: '#F4F6FF', + greyBlue: '#102026', + grey: '#666', + lightGrey: '#dddddd', + red: '#FF8080', + lightRed: '#FFB9B9', + green: '#B1EAC5', + violet: '#C6CFF7', + pink: '#EC96EC', + yellow: '#ffbd01' + } + + /* -------------------------------------------------------------------------- + FONTS + -------------------------------------------------------------------------- */ + var texts = csjs ` + .title-XL { + font-size : 2em; + font-weight : 700; + letter-spacing : .05em; + } + + .title-L { + font-size : 1em; + font-weight : 600; + } + + .title-M { + font-size : 1em; + font-weight : 400; + } + + .title-S { + font-size : .8em; + font-weight : 300; + } + + .text { + font-size : .8em; + } + ` + /* -------------------------------------------------------------------------- + TEXT-BOXES + -------------------------------------------------------------------------- */ + var textBoxes = csjs` + .display-box-L { + font-size : 1em; + padding : 8px 15px; + line-height : 20px; + background : #f8f8f8; + border-radius : 3px; + border : 1px solid #e5e5e5; + overflow-x : auto; + width : 100%; + } + + .info-text-box { + background-color : white; + line-height : 20px; + border : .2em dotted lightGrey; + padding : 8px 15px; + border-radius : 5px; + margin-bottom : 1em; + } + + .warning-text-box { + background-color : #E6E5A7; // yellow + line-height : 20px; + padding : 1em 1em .5em 1em; + border-radius : 3px; + box-shadow : rgba(0,0,0,.2) 0 1px 4px; + margin-bottom : 1em; + } + + .error-text-box { + background-color : #FFB9B9; // light-red + line-height : 20px; + padding : 1em 1em .5em 1em; + border-radius : 3px; + box-shadow : rgba(0,0,0,.2) 0 1px 4px; + margin-bottom : 1em; + } + + .title-box { + margin-bottom : 0.4em; + padding : 1em; + background-color : transparent; + font-weight : bold; + display : flex; + justify-content : space-between; + word-wrap : break-word; + position : relative; + border-radius : 3px; + } + ` + /* -------------------------------------------------------------------------- + BUTTONS + -------------------------------------------------------------------------- */ + var buttons = csjs` + .button { + border-color : transparent; + border-radius : 3px; + cursor : pointer; + padding : .3em; + } + + .button:hover { + opacity : 0.8; + } + + .dropdown-menu { + font-size : 1em; + text-decoration : none; + background-color : #C6CFF7; + cursor : pointer; + font-size : 12px; + border : none; + height : 20px; + } + + ` + + /* -------------------------------------------------------------------------- + INPUT FIELDS + -------------------------------------------------------------------------- */ + /* + .input-field { + border : 1px solid #f0f0f0; // light-grey + padding : .3em; + margin : .3em; + } + */ + return { + textBoxL: textBoxes['display-box-L'], + infoTextBox: textBoxes['info-text-box'], + titleL: texts['title-L'], + titleM: texts['title-M'], + dropdown: buttons['dropdown-menu'], + button: buttons['button'], + colors: colors, + titleBox: textBoxes['title-box'] + } +} diff --git a/src/universal-dapp.js b/src/universal-dapp.js index 922ad8ab4d..9ab65ba1b3 100644 --- a/src/universal-dapp.js +++ b/src/universal-dapp.js @@ -9,7 +9,15 @@ var EventManager = require('./lib/eventManager') var crypto = require('crypto') var async = require('async') var TxRunner = require('./app/txRunner') +var yo = require('yo-yo') + +// copy to copyToClipboard +const copy = require('clipboard-copy') + +// -------------- styling ---------------------- var csjs = require('csjs-inject') +var styleGuide = require('./app/style-guide') +var styles = styleGuide() var css = csjs` .options { @@ -21,7 +29,75 @@ var css = csjs` margin-right: 0.5em; font-size: 1em; } + .title extends ${styles.titleBox} { + cursor: pointer; + background-color: ${styles.colors.violet}; + } + .title:hover { + opacity: .8; + } + .contract .title:before { + content: "\\25BE"; + } + .contract.hidesub .title:before { + content: "\\25B8" + } + .contract.hidesub { + padding-bottom: 0; + margin: 0; + } + .contract.hidesub > *:not(.title) { + display: none; + } ` + +var cssInstance = csjs` + .title { + display: flex; + justify-content: center; + margin-bottom: 1em; + padding: 1em; + font-size: .95em; + cursor: pointer; + background-color: ${styles.colors.violet}; + border: 2px dotted ${styles.colors.blue}; + border-radius: 5px; + } + .titleText { + margin-right: 1em; + word-break: break-all; + } + .titleText:hover { + opacity: .8; + } + .instance .title:before { + content: "\\25BE"; + margin-right: .5em; + } + .instance.hidesub .title:before { + content: "\\25B8" + margin-right: .5em; + } + .instance.hidesub { + padding-bottom: 0; + margin: 0; + } + .instance.hidesub > *:not(.title) { + display: none; + } + .copy extends ${styles.button} { + border: 1px dotted ${styles.colors.grey}; + border-radius: 5px; + text-align: center; + padding: 1em .3em; + min-width: 30%; + } + .copy:hover{ + background-color: ${styles.colors.lightGrey}; + opacity: .8; + } +` + ;[...document.querySelectorAll('#header #options li')].forEach(addCss) function addCss (el) { el.classList.add(css.options) } @@ -164,20 +240,20 @@ UniversalDApp.prototype.render = function () { .append($('
').text('Publish')) .append($('
').text('Attach')) .append($('
').text('Transact')) - .append($('
').text('Transact (Payable)')) + .append($('
').text('Transact(Payable)')) .append($('
').text('Call')) self.$el.append($legend) for (var c in self.contracts) { - var $contractEl = $('
') + var $contractEl = $(`
`) if (self.contracts[c].address) { self.getInstanceInterface(self.contracts[c], self.contracts[c].address, $contractEl) } else { - var $title = $('').text(self.contracts[c].name) + var $title = $(``).text(self.contracts[c].name) + $title.click(function (ev) { $(this).closest(`.${css.contract}`).toggleClass(`${css.hidesub}`) }) if (self.contracts[c].bytecode) { - $title.addClass('definitionTitle') $title.append($('
').text((self.contracts[c].bytecode.length / 2) + ' bytes')) } $contractEl.append($title).append(self.getCreateInterface($contractEl, self.contracts[c])) @@ -207,7 +283,7 @@ UniversalDApp.prototype.getCreateInterface = function ($container, contract) { $createInterface.append($close) } - var $publishButton = $('