Commit 70c7710b authored by yann300's avatar yann300 Committed by GitHub

Merge pull request #793 from ethereum/modal_prompt_confirm

Modal prompt confirm
parents ff588cec fe462d91
...@@ -43,11 +43,15 @@ module.exports = (contract, appAPI, cb) => { ...@@ -43,11 +43,15 @@ module.exports = (contract, appAPI, cb) => {
} }
cb() cb()
}) })
}, function () { }, function (error) {
// publish the list of sources in order, fail if any failed if (error) {
async.eachSeries(sources, function (item, cb) { cb(error)
swarmVerifiedPublish(item.content, item.hash, cb) } else {
}, cb) // publish the list of sources in order, fail if any failed
async.eachSeries(sources, function (item, cb) {
swarmVerifiedPublish(item.content, item.hash, cb)
}, cb)
}
}) })
} }
......
/* global confirm, chrome */ /* global chrome */
'use strict' 'use strict'
var modalDialogCustom = require('../ui/modal-dialog-custom')
module.exports = function (filesProviders) { module.exports = function (filesProviders) {
if (typeof chrome === 'undefined' || !chrome || !chrome.storage || !chrome.storage.sync) { if (typeof chrome === 'undefined' || !chrome || !chrome.storage || !chrome.storage.sync) {
...@@ -13,9 +14,18 @@ module.exports = function (filesProviders) { ...@@ -13,9 +14,18 @@ module.exports = function (filesProviders) {
function check (key) { function check (key) {
chrome.storage.sync.get(key, function (resp) { chrome.storage.sync.get(key, function (resp) {
console.log('comparing to cloud', key, 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) function confirmDialog (callback) {
filesProviders['browser'].set(key, resp[key]) 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 { } else {
console.log('add to obj', obj, key) console.log('add to obj', obj, key)
filesProviders['browser'].get(key, (error, content) => { filesProviders['browser'].get(key, (error, content) => {
...@@ -26,6 +36,7 @@ module.exports = function (filesProviders) { ...@@ -26,6 +36,7 @@ module.exports = function (filesProviders) {
} }
}) })
} }
done++ done++
if (done >= count) { if (done >= count) {
chrome.storage.sync.set(obj, function () { chrome.storage.sync.set(obj, function () {
......
/* global FileReader, confirm */ /* global FileReader */
var yo = require('yo-yo') var yo = require('yo-yo')
var csjs = require('csjs-inject') var csjs = require('csjs-inject')
var Treeview = require('ethereum-remix').ui.TreeView var Treeview = require('ethereum-remix').ui.TreeView
...@@ -133,8 +133,7 @@ function fileExplorer (appAPI, files) { ...@@ -133,8 +133,7 @@ function fileExplorer (appAPI, files) {
this.events = events this.events = events
var api = {} var api = {}
api.addFile = function addFile (file) { api.addFile = function addFile (file) {
var name = files.type + '/' + file.name function loadFile () {
if (!files.exists(name) || confirm('The file ' + name + ' already exists! Would you like to overwrite it?')) {
var fileReader = new FileReader() var fileReader = new FileReader()
fileReader.onload = function (event) { fileReader.onload = function (event) {
var success = files.set(name, event.target.result) var success = files.set(name, event.target.result)
...@@ -143,6 +142,13 @@ function fileExplorer (appAPI, files) { ...@@ -143,6 +142,13 @@ function fileExplorer (appAPI, files) {
} }
fileReader.readAsText(file) 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 this.api = api
...@@ -193,10 +199,10 @@ function fileExplorer (appAPI, files) { ...@@ -193,10 +199,10 @@ function fileExplorer (appAPI, files) {
var path = label.dataset.path var path = label.dataset.path
var isFolder = !!~label.className.indexOf('folder') var isFolder = !!~label.className.indexOf('folder')
if (isFolder) path += '/' 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) li.parentElement.removeChild(li)
removeSubtree(files, path, isFolder) removeSubtree(files, path, isFolder)
} })
} }
function editModeOn (event) { function editModeOn (event) {
...@@ -213,29 +219,36 @@ function fileExplorer (appAPI, files) { ...@@ -213,29 +219,36 @@ function fileExplorer (appAPI, files) {
function editModeOff (event) { function editModeOff (event) {
var label = this 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.which === 13) event.preventDefault()
if ((event.type === 'blur' || event.which === 27 || event.which === 13) && label.getAttribute('contenteditable')) { if ((event.type === 'blur' || event.which === 27 || event.which === 13) && label.getAttribute('contenteditable')) {
var isFolder = label.className.indexOf('folder') !== -1 var isFolder = label.className.indexOf('folder') !== -1
var save = textUnderEdit !== label.innerText var save = textUnderEdit !== label.innerText
if (save && event.which !== 13) save = confirm('Do you want to rename?') if (save && event.which !== 13) {
if (save) { modalDialogCustom.confirm(null, `Do you want to rename?`, () => { rename() }, () => { cancelRename() })
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
label.removeAttribute('contenteditable') label.removeAttribute('contenteditable')
label.classList.remove(css.rename) label.classList.remove(css.rename)
} }
......
/* global confirm, prompt */
var async = require('async') var async = require('async')
var $ = require('jquery') var $ = require('jquery')
var csjs = require('csjs-inject') var csjs = require('csjs-inject')
...@@ -314,13 +313,15 @@ function filepanel (appAPI, filesProvider) { ...@@ -314,13 +313,15 @@ function filepanel (appAPI, filesProvider) {
modalDialogCustom.alert('Failed to create gist: ' + (data || 'Unknown transport error')) modalDialogCustom.alert('Failed to create gist: ' + (data || 'Unknown transport error'))
} else { } else {
data = JSON.parse(data) 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?')) { if (data.html_url) {
window.open(data.html_url, '_blank') 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) => { packageFiles(filesProvider['browser'], (error, packaged) => {
if (error) { if (error) {
console.log(error) console.log(error)
...@@ -339,30 +340,31 @@ function filepanel (appAPI, filesProvider) { ...@@ -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 -------------- // ------------------ copy files --------------
function copyFiles () { function copyFiles () {
var target = prompt( modalDialogCustom.prompt(null, 'To which other browser-solidity instance do you want to copy over all files?', 'https://ethereum.github.io/browser-solidity/', (target) => {
'To which other browser-solidity instance do you want to copy over all files?', doCopy(target)
'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')
}
}) })
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')
}
})
}
} }
} }
......
/* global alert */ /* global */
var $ = require('jquery') var $ = require('jquery')
var yo = require('yo-yo') var yo = require('yo-yo')
...@@ -434,9 +434,13 @@ function compileTab (container, appAPI, appEvents, opts) { ...@@ -434,9 +434,13 @@ function compileTab (container, appAPI, appEvents, opts) {
} else { } else {
publishOnSwarm(contract, appAPI, function (err) { publishOnSwarm(contract, appAPI, function (err) {
if (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 { } 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) { ...@@ -199,9 +199,11 @@ function runTab (container, appAPI, appEvents, opts) {
// DROPDOWN // DROPDOWN
var selectExEnv = el.querySelector('#selectExEnvOptions') var selectExEnv = el.querySelector('#selectExEnvOptions')
selectExEnv.addEventListener('change', function (event) { 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() selectExEnv.value = executionContext.getProvider()
} })
fillAccountsList(appAPI, el) fillAccountsList(appAPI, el)
instanceContainer.innerHTML = '' // clear the instances list instanceContainer.innerHTML = '' // clear the instances list
noInstancesText.style.display = 'block' noInstancesText.style.display = 'block'
......
var modal = require('./modaldialog.js') var modal = require('./modaldialog.js')
var yo = require('yo-yo') var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
.prompt_text {
width: 300px;
}
`
module.exports = { module.exports = {
alert: function (text) { alert: function (text) {
modal('', yo`<div>${text}</div>`, null, { label: null }) 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) => { ...@@ -83,6 +83,7 @@ module.exports = (title, content, ok, cancel) => {
document.querySelector('body').appendChild(html()) document.querySelector('body').appendChild(html())
container = document.querySelector(`.${css.modal}`) container = document.querySelector(`.${css.modal}`)
} }
var closeDiv = document.getElementById('modal-close') var closeDiv = document.getElementById('modal-close')
var okDiv = document.getElementById('modal-footer-ok') var okDiv = document.getElementById('modal-footer-ok')
...@@ -100,23 +101,22 @@ module.exports = (title, content, ok, cancel) => { ...@@ -100,23 +101,22 @@ module.exports = (title, content, ok, cancel) => {
modal.innerHTML = '' modal.innerHTML = ''
if (content) modal.appendChild(content) if (content) modal.appendChild(content)
container.style.display = container.style.display === 'block' ? hide() : show() show()
function okListener () { function okListener () {
removeEventListener()
hide() hide()
if (ok && ok.fn) ok.fn() if (ok && ok.fn) ok.fn()
removeEventListener()
} }
function cancelListener () { function cancelListener () {
removeEventListener()
hide() hide()
if (cancel && cancel.fn) cancel.fn() if (cancel && cancel.fn) cancel.fn()
removeEventListener()
} }
function hide () { function hide () {
container.style.display = 'none' container.style.display = 'none'
container.parentElement.removeChild(container)
} }
function show () { function show () {
...@@ -128,7 +128,6 @@ module.exports = (title, content, ok, cancel) => { ...@@ -128,7 +128,6 @@ module.exports = (title, content, ok, cancel) => {
cancelDiv.removeEventListener('click', cancelListener) cancelDiv.removeEventListener('click', cancelListener)
closeDiv.removeEventListener('click', cancelListener) closeDiv.removeEventListener('click', cancelListener)
} }
okDiv.addEventListener('click', okListener) okDiv.addEventListener('click', okListener)
cancelDiv.addEventListener('click', cancelListener) cancelDiv.addEventListener('click', cancelListener)
closeDiv.addEventListener('click', cancelListener) closeDiv.addEventListener('click', cancelListener)
......
/* global confirm, prompt */
'use strict' 'use strict'
var Web3 = require('web3') var Web3 = require('web3')
...@@ -9,6 +8,7 @@ var StateManager = require('ethereumjs-vm/lib/stateManager') ...@@ -9,6 +8,7 @@ var StateManager = require('ethereumjs-vm/lib/stateManager')
var remix = require('ethereum-remix') var remix = require('ethereum-remix')
var Web3VMProvider = remix.web3.web3VMProvider var Web3VMProvider = remix.web3.web3VMProvider
var rlp = ethUtil.rlp var rlp = ethUtil.rlp
var modalDialogCustom = require('./app/ui/modal-dialog-custom')
var injectedProvider var injectedProvider
...@@ -111,21 +111,31 @@ function ExecutionContext () { ...@@ -111,21 +111,31 @@ function ExecutionContext () {
this.executionContextChange(context, endPointUrl) this.executionContextChange(context, endPointUrl)
} }
this.executionContextChange = function (context, endPointUrl) { this.executionContextChange = function (context, endPointUrl, cb) {
if (context === 'web3' && !confirm('Are you sure you want to connect to an ethereum node?')) { if (!cb) cb = () => {}
return false 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) { } else if (context === 'injected' && injectedProvider === undefined) {
return false cb()
} else { } else {
if (context === 'web3') { if (context === 'injected') {
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') {
executionContext = context executionContext = context
web3.setProvider(injectedProvider) web3.setProvider(injectedProvider)
self.event.trigger('contextChanged', ['injected']) self.event.trigger('contextChanged', ['injected'])
...@@ -136,7 +146,6 @@ function ExecutionContext () { ...@@ -136,7 +146,6 @@ function ExecutionContext () {
}) })
self.event.trigger('contextChanged', ['vm']) self.event.trigger('contextChanged', ['vm'])
} }
return true
} }
} }
......
'use strict' 'use strict'
var modalDialogCustom = require('../app/ui/modal-dialog-custom')
// Allowing window to be overriden for testing // Allowing window to be overriden for testing
function GistHandler (_window) { function GistHandler (_window) {
if (_window === undefined) _window = window if (_window !== undefined) {
modalDialogCustom = _window
}
this.handleLoad = function (params, cb) { this.handleLoad = function (params, cb) {
if (!cb) cb = () => {}
var loadingFromGist = false var loadingFromGist = false
var gistId var gistId
if (params['gist'] === '') { if (params['gist'] === '') {
var str = _window.prompt('Enter the URL or ID of the Gist you would like to load.') loadingFromGist = true
if (str !== '') { modalDialogCustom.prompt(null, 'Enter the URL or ID of the Gist you would like to load.', null, (target) => {
gistId = getGistId(str) if (target !== '') {
loadingFromGist = !!gistId gistId = getGistId(target)
} if (gistId) {
cb(gistId)
}
}
})
return loadingFromGist
} else { } else {
gistId = params['gist'] gistId = params['gist']
loadingFromGist = !!gistId loadingFromGist = !!gistId
......
...@@ -18,10 +18,10 @@ test('gistHandler.handleLoad with no gist param', function (t) { ...@@ -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) { test('gistHandler.handleLoad with blank gist param, and invalid user input', function (t) {
t.plan(3) t.plan(3)
var fakeWindow = {prompt: function (message) { var fakeWindow = {prompt: function (title, message, input, cb) {
t.ok(message) t.ok(message)
t.ok(message.match(/gist/i)) t.ok(message.match(/gist/i))
return 'invalid' cb('invalid')
}} }}
var gistHandler = new GistHandler(fakeWindow) var gistHandler = new GistHandler(fakeWindow)
...@@ -29,16 +29,16 @@ test('gistHandler.handleLoad with blank gist param, and invalid user input', fun ...@@ -29,16 +29,16 @@ test('gistHandler.handleLoad with blank gist param, and invalid user input', fun
var params = {'gist': ''} var params = {'gist': ''}
var result = gistHandler.handleLoad(params, null) 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) { test('gistHandler.handleLoad with blank gist param, and valid user input', function (t) {
t.plan(4) t.plan(4)
var fakeWindow = {prompt: function (message) { var fakeWindow = {prompt: function (title, message, input, cb) {
t.ok(message) t.ok(message)
t.ok(message.match(/gist/i)) t.ok(message.match(/gist/i))
return 'Beef1234' cb('Beef1234')
}} }}
var cb = function (gistId) { var cb = function (gistId) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment