Merge pull request #793 from ethereum/modal_prompt_confirm

Modal prompt confirm
pull/1/head
yann300 7 years ago committed by GitHub
commit 70c7710b56
  1. 14
      src/app/contract/publishOnSwarm.js
  2. 19
      src/app/files/chromeCloudStorageSync.js
  3. 61
      src/app/files/file-explorer.js
  4. 48
      src/app/panels/file-panel.js
  5. 10
      src/app/tabs/compile-tab.js
  6. 6
      src/app/tabs/run-tab.js
  7. 29
      src/app/ui/modal-dialog-custom.js
  8. 9
      src/app/ui/modaldialog.js
  9. 39
      src/execution-context.js
  10. 22
      src/lib/gist-handler.js
  11. 10
      test/gist-handler-test.js

@ -43,11 +43,15 @@ module.exports = (contract, appAPI, cb) => {
}
cb()
})
}, function () {
// publish the list of sources in order, fail if any failed
async.eachSeries(sources, function (item, cb) {
swarmVerifiedPublish(item.content, item.hash, cb)
}, cb)
}, function (error) {
if (error) {
cb(error)
} else {
// publish the list of sources in order, fail if any failed
async.eachSeries(sources, function (item, cb) {
swarmVerifiedPublish(item.content, item.hash, cb)
}, cb)
}
})
}

@ -1,5 +1,6 @@
/* global confirm, chrome */
/* global chrome */
'use strict'
var modalDialogCustom = require('../ui/modal-dialog-custom')
module.exports = function (filesProviders) {
if (typeof chrome === 'undefined' || !chrome || !chrome.storage || !chrome.storage.sync) {
@ -13,9 +14,18 @@ module.exports = function (filesProviders) {
function check (key) {
chrome.storage.sync.get(key, function (resp) {
console.log('comparing to cloud', key, resp)
if (typeof resp[key] !== 'undefined' && obj[key] !== resp[key] && confirm('Overwrite "' + key + '"? Click Ok to overwrite local file with file from cloud. Cancel will push your local file to the cloud.')) {
console.log('Overwriting', key)
filesProviders['browser'].set(key, resp[key])
function confirmDialog (callback) {
modalDialogCustom.confirm('', 'Overwrite "' + key + '"? Click Ok to overwrite local file with file from cloud. Cancel will push your local file to the cloud.', () => { callback(true) }, () => { callback(false) })
}
if (typeof resp[key] !== 'undefined' && obj[key] !== resp[key]) {
confirmDialog((result) => {
if (result) {
console.log('Overwriting', key)
filesProviders['browser'].set(key, resp[key])
}
})
} else {
console.log('add to obj', obj, key)
filesProviders['browser'].get(key, (error, content) => {
@ -26,6 +36,7 @@ module.exports = function (filesProviders) {
}
})
}
done++
if (done >= count) {
chrome.storage.sync.set(obj, function () {

@ -1,4 +1,4 @@
/* global FileReader, confirm */
/* global FileReader */
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var Treeview = require('ethereum-remix').ui.TreeView
@ -133,8 +133,7 @@ function fileExplorer (appAPI, files) {
this.events = events
var api = {}
api.addFile = function addFile (file) {
var name = files.type + '/' + file.name
if (!files.exists(name) || confirm('The file ' + name + ' already exists! Would you like to overwrite it?')) {
function loadFile () {
var fileReader = new FileReader()
fileReader.onload = function (event) {
var success = files.set(name, event.target.result)
@ -143,6 +142,13 @@ function fileExplorer (appAPI, files) {
}
fileReader.readAsText(file)
}
var name = files.type + '/' + file.name
if (!files.exists(name)) {
loadFile()
} else {
modalDialogCustom.confirm(null, `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() })
}
}
this.api = api
@ -193,10 +199,10 @@ function fileExplorer (appAPI, files) {
var path = label.dataset.path
var isFolder = !!~label.className.indexOf('folder')
if (isFolder) path += '/'
if (confirm(`Do you really want to delete "${path}" ?`)) {
modalDialogCustom.confirm(null, `Do you really want to delete "${path}" ?`, () => {
li.parentElement.removeChild(li)
removeSubtree(files, path, isFolder)
}
})
}
function editModeOn (event) {
@ -213,29 +219,36 @@ function fileExplorer (appAPI, files) {
function editModeOff (event) {
var label = this
function rename () {
var newPath = label.dataset.path
newPath = newPath.split('/')
newPath[newPath.length - 1] = label.innerText
newPath = newPath.join('/')
if (label.innerText === '') {
modalDialogCustom.alert('File name cannot be empty')
label.innerText = textUnderEdit
} else if (label.innerText.match(/(\/|:|\*|\?|"|<|>|\\|\||')/) !== null) {
modalDialogCustom.alert('Special characters are not allowed')
label.innerText = textUnderEdit
} else if (!files.exists(newPath)) {
files.rename(label.dataset.path, newPath, isFolder)
} else {
modalDialogCustom.alert('File already exists.')
label.innerText = textUnderEdit
}
}
function cancelRename () {
label.innerText = textUnderEdit
}
if (event.which === 13) event.preventDefault()
if ((event.type === 'blur' || event.which === 27 || event.which === 13) && label.getAttribute('contenteditable')) {
var isFolder = label.className.indexOf('folder') !== -1
var save = textUnderEdit !== label.innerText
if (save && event.which !== 13) save = confirm('Do you want to rename?')
if (save) {
var newPath = label.dataset.path
newPath = newPath.split('/')
newPath[newPath.length - 1] = label.innerText
newPath = newPath.join('/')
if (label.innerText === '') {
modalDialogCustom.alert('File name cannot be empty')
label.innerText = textUnderEdit
} else if (label.innerText.match(/(\/|:|\*|\?|"|<|>|\\|\||')/) !== null) {
modalDialogCustom.alert('Special characters are not allowed')
label.innerText = textUnderEdit
} else if (!files.exists(newPath)) {
files.rename(label.dataset.path, newPath, isFolder)
} else {
modalDialogCustom.alert('File already exists.')
label.innerText = textUnderEdit
}
} else label.innerText = textUnderEdit
if (save && event.which !== 13) {
modalDialogCustom.confirm(null, `Do you want to rename?`, () => { rename() }, () => { cancelRename() })
}
label.removeAttribute('contenteditable')
label.classList.remove(css.rename)
}

@ -1,4 +1,3 @@
/* global confirm, prompt */
var async = require('async')
var $ = require('jquery')
var csjs = require('csjs-inject')
@ -314,13 +313,15 @@ function filepanel (appAPI, filesProvider) {
modalDialogCustom.alert('Failed to create gist: ' + (data || 'Unknown transport error'))
} else {
data = JSON.parse(data)
if (data.html_url && confirm('Created a gist at ' + data.html_url + ' Would you like to open it in a new window?')) {
window.open(data.html_url, '_blank')
if (data.html_url) {
modalDialogCustom.confirm(null, `Created a gist at ${data.html_url}. Would you like to open it in a new window?`, () => {
window.open(data.html_url, '_blank')
})
}
}
}
if (confirm('Are you sure you want to publish all your files anonymously as a public gist on github.com?')) {
// package only files from the browser storage.
function toGist () {
packageFiles(filesProvider['browser'], (error, packaged) => {
if (error) {
console.log(error)
@ -339,30 +340,31 @@ function filepanel (appAPI, filesProvider) {
}
})
}
modalDialogCustom.confirm(null, `Are you very sure you want to publish all your files anonymously as a public gist on github.com?`, () => {
toGist()
})
}
// ------------------ copy files --------------
function copyFiles () {
var target = prompt(
'To which other browser-solidity instance do you want to copy over all files?',
'https://ethereum.github.io/browser-solidity/'
)
if (target === null) {
return
}
// package only files from the browser storage.
packageFiles(filesProvider['browser'], (error, packaged) => {
if (error) {
console.log(error)
} else {
$('<iframe/>', {
src: target,
style: 'display:none;',
load: function () { this.contentWindow.postMessage(['loadFiles', packaged], '*') }
}).appendTo('body')
}
modalDialogCustom.prompt(null, 'To which other browser-solidity instance do you want to copy over all files?', 'https://ethereum.github.io/browser-solidity/', (target) => {
doCopy(target)
})
function doCopy (target) {
// package only files from the browser storage.
packageFiles(filesProvider['browser'], (error, packaged) => {
if (error) {
console.log(error)
} else {
$('<iframe/>', {
src: target,
style: 'display:none;',
load: function () { this.contentWindow.postMessage(['loadFiles', packaged], '*') }
}).appendTo('body')
}
})
}
}
}

@ -1,4 +1,4 @@
/* global alert */
/* global */
var $ = require('jquery')
var yo = require('yo-yo')
@ -434,9 +434,13 @@ function compileTab (container, appAPI, appEvents, opts) {
} else {
publishOnSwarm(contract, appAPI, function (err) {
if (err) {
alert('Failed to publish metadata: ' + err)
try {
err = JSON.stringify(err)
} catch (e) {}
modalDialogCustom.alert(yo`<span>Failed to publish metadata file to swarm, please check the Swarm gateways is available ( swarm-gateways.net ).<br />
${err}</span>`)
} else {
alert('Metadata published successfully. You\'l find the Swarm address in the Contract details.')
modalDialogCustom.alert(yo`<span>Metadata published successfully.<br />The Swarm address of the metadata file is available in the contract details.</span>`)
}
})
}

@ -199,9 +199,11 @@ function runTab (container, appAPI, appEvents, opts) {
// DROPDOWN
var selectExEnv = el.querySelector('#selectExEnvOptions')
selectExEnv.addEventListener('change', function (event) {
if (!executionContext.executionContextChange(selectExEnv.options[selectExEnv.selectedIndex].value)) {
executionContext.executionContextChange(selectExEnv.options[selectExEnv.selectedIndex].value, null, () => {
// set the final context. Cause it is possible that this is not the one we've originaly selected
selectExEnv.value = executionContext.getProvider()
}
})
fillAccountsList(appAPI, el)
instanceContainer.innerHTML = '' // clear the instances list
noInstancesText.style.display = 'block'

@ -1,7 +1,36 @@
var modal = require('./modaldialog.js')
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
.prompt_text {
width: 300px;
}
`
module.exports = {
alert: function (text) {
modal('', yo`<div>${text}</div>`, null, { label: null })
},
prompt: function (title, text, inputValue, ok, cancel) {
if (!inputValue) inputValue = ''
modal(title,
yo`<div>${text}<div><input type='text' name='prompt_text' id='prompt_text' class="${css['prompt_text']}" value='${inputValue}' ></div></div>`,
{
fn: () => { if (typeof ok === 'function') ok(document.getElementById('prompt_text').value) }
},
{
fn: () => { if (typeof cancel === 'function') cancel() }
}
)
},
confirm: function (title, text, ok, cancel) {
modal(title, yo`<div>${text}</div>`,
{
fn: () => { if (typeof ok === 'function') ok() }
},
{
fn: () => { if (typeof cancel === 'function') cancel() }
}
)
}
}

@ -83,6 +83,7 @@ module.exports = (title, content, ok, cancel) => {
document.querySelector('body').appendChild(html())
container = document.querySelector(`.${css.modal}`)
}
var closeDiv = document.getElementById('modal-close')
var okDiv = document.getElementById('modal-footer-ok')
@ -100,23 +101,22 @@ module.exports = (title, content, ok, cancel) => {
modal.innerHTML = ''
if (content) modal.appendChild(content)
container.style.display = container.style.display === 'block' ? hide() : show()
show()
function okListener () {
removeEventListener()
hide()
if (ok && ok.fn) ok.fn()
removeEventListener()
}
function cancelListener () {
removeEventListener()
hide()
if (cancel && cancel.fn) cancel.fn()
removeEventListener()
}
function hide () {
container.style.display = 'none'
container.parentElement.removeChild(container)
}
function show () {
@ -128,7 +128,6 @@ module.exports = (title, content, ok, cancel) => {
cancelDiv.removeEventListener('click', cancelListener)
closeDiv.removeEventListener('click', cancelListener)
}
okDiv.addEventListener('click', okListener)
cancelDiv.addEventListener('click', cancelListener)
closeDiv.addEventListener('click', cancelListener)

@ -1,4 +1,3 @@
/* global confirm, prompt */
'use strict'
var Web3 = require('web3')
@ -9,6 +8,7 @@ var StateManager = require('ethereumjs-vm/lib/stateManager')
var remix = require('ethereum-remix')
var Web3VMProvider = remix.web3.web3VMProvider
var rlp = ethUtil.rlp
var modalDialogCustom = require('./app/ui/modal-dialog-custom')
var injectedProvider
@ -111,21 +111,31 @@ function ExecutionContext () {
this.executionContextChange(context, endPointUrl)
}
this.executionContextChange = function (context, endPointUrl) {
if (context === 'web3' && !confirm('Are you sure you want to connect to an ethereum node?')) {
return false
this.executionContextChange = function (context, endPointUrl, cb) {
if (!cb) cb = () => {}
function runPrompt () {
executionContext = context
if (!endPointUrl) {
endPointUrl = 'http://localhost:8545'
}
modalDialogCustom.prompt(null, 'Web3 Provider Endpoint', endPointUrl, (target) => {
setProviderFromEndpoint(target)
self.event.trigger('contextChanged', ['web3'])
cb()
}, () => {
self.event.trigger('contextChanged', ['web3'])
cb()
})
}
if (context === 'web3') {
modalDialogCustom.confirm(null, 'Are you sure you want to connect to an ethereum node?',
() => { runPrompt(endPointUrl) }, () => { cb() }
)
} else if (context === 'injected' && injectedProvider === undefined) {
return false
cb()
} else {
if (context === 'web3') {
executionContext = context
if (!endPointUrl) {
endPointUrl = 'http://localhost:8545'
}
endPointUrl = prompt('Web3 Provider Endpoint', endPointUrl)
setProviderFromEndpoint(endPointUrl)
self.event.trigger('contextChanged', ['web3'])
} else if (context === 'injected') {
if (context === 'injected') {
executionContext = context
web3.setProvider(injectedProvider)
self.event.trigger('contextChanged', ['injected'])
@ -136,7 +146,6 @@ function ExecutionContext () {
})
self.event.trigger('contextChanged', ['vm'])
}
return true
}
}

@ -1,18 +1,26 @@
'use strict'
var modalDialogCustom = require('../app/ui/modal-dialog-custom')
// Allowing window to be overriden for testing
function GistHandler (_window) {
if (_window === undefined) _window = window
if (_window !== undefined) {
modalDialogCustom = _window
}
this.handleLoad = function (params, cb) {
if (!cb) cb = () => {}
var loadingFromGist = false
var gistId
if (params['gist'] === '') {
var str = _window.prompt('Enter the URL or ID of the Gist you would like to load.')
if (str !== '') {
gistId = getGistId(str)
loadingFromGist = !!gistId
}
loadingFromGist = true
modalDialogCustom.prompt(null, 'Enter the URL or ID of the Gist you would like to load.', null, (target) => {
if (target !== '') {
gistId = getGistId(target)
if (gistId) {
cb(gistId)
}
}
})
return loadingFromGist
} else {
gistId = params['gist']
loadingFromGist = !!gistId

@ -18,10 +18,10 @@ test('gistHandler.handleLoad with no gist param', function (t) {
test('gistHandler.handleLoad with blank gist param, and invalid user input', function (t) {
t.plan(3)
var fakeWindow = {prompt: function (message) {
var fakeWindow = {prompt: function (title, message, input, cb) {
t.ok(message)
t.ok(message.match(/gist/i))
return 'invalid'
cb('invalid')
}}
var gistHandler = new GistHandler(fakeWindow)
@ -29,16 +29,16 @@ test('gistHandler.handleLoad with blank gist param, and invalid user input', fun
var params = {'gist': ''}
var result = gistHandler.handleLoad(params, null)
t.equal(result, false)
t.equal(result, true)
})
test('gistHandler.handleLoad with blank gist param, and valid user input', function (t) {
t.plan(4)
var fakeWindow = {prompt: function (message) {
var fakeWindow = {prompt: function (title, message, input, cb) {
t.ok(message)
t.ok(message.match(/gist/i))
return 'Beef1234'
cb('Beef1234')
}}
var cb = function (gistId) {

Loading…
Cancel
Save