Merge pull request #1913 from ethereum/swap_it_style_fixes_l

Modal dialog
pull/1/head
yann300 6 years ago committed by GitHub
commit 383fbab0b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/app/files/file-explorer.js
  2. 4
      src/app/tabs/runTab/contractDropdown.js
  3. 4
      src/app/tabs/runTab/recorder.js
  4. 13
      src/app/tabs/runTab/settings.js
  5. 10
      src/app/ui/landing-page/landing-page.js
  6. 61
      src/app/ui/modaldialog.js
  7. 2
      src/app/ui/styles/auto-complete-popup-styles.js
  8. 66
      src/app/ui/styles/modaldialog-styles.js
  9. 2
      src/lib/gist-handler.js
  10. 2
      src/universal-dapp-ui.js
  11. 2
      test-browser/helpers/contracts.js
  12. 2
      test/gist-handler-test.js

@ -182,7 +182,7 @@ function fileExplorer (localRegistry, files, menuItems) {
},
'Delete': () => {
if (self.files.readonly) { return tooltip('cannot delete folder. ' + self.files.type + ' is a read only explorer') }
modalDialogCustom.confirm(null, 'Do you want to delete this folder?', () => { files.remove(key) }, () => {})
modalDialogCustom.confirm('Confirm to delete a folder', 'Are you sure you want to delete this folder?', () => { files.remove(key) }, () => {})
}
})
})
@ -198,7 +198,7 @@ function fileExplorer (localRegistry, files, menuItems) {
},
'Delete': () => {
if (self.files.readonly) { return tooltip('cannot delete file. ' + self.files.type + ' is a read only explorer') }
modalDialogCustom.confirm(null, 'Do you want to delete this file?', () => { files.remove(key) }, () => {})
modalDialogCustom.confirm('Delete a file', 'Are you sure you want to delete this file?', () => { files.remove(key) }, () => {})
}
})
})
@ -287,7 +287,7 @@ function fileExplorer (localRegistry, files, menuItems) {
var isFolder = label.className.indexOf('folder') !== -1
var save = textUnderEdit !== label.innerText
if (save) {
modalDialogCustom.confirm(null, 'Do you want to rename?', () => { rename() }, () => { label.innerText = textUnderEdit })
modalDialogCustom.confirm('Confirm to rename a file', 'Are you sure you want to rename this file?', () => { rename() }, () => { label.innerText = textUnderEdit })
}
label.removeAttribute('contenteditable')
label.classList.remove('bg-light')
@ -357,7 +357,7 @@ fileExplorer.prototype.uploadFile = function (event) {
if (!exist) {
loadFile()
} else {
modalDialogCustom.confirm(null, `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() })
modalDialogCustom.confirm('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() })
}
})
})
@ -369,7 +369,7 @@ fileExplorer.prototype.toGist = function (id) {
modalDialogCustom.alert('Failed to manage gist: ' + error)
} else {
if (data.html_url) {
modalDialogCustom.confirm(null, `The gist is at ${data.html_url}. Would you like to open it in a new window?`, () => {
modalDialogCustom.confirm('Gist is ready', `The gist is at ${data.html_url}. Would you like to open it in a new window?`, () => {
window.open(data.html_url, '_blank')
})
} else {
@ -450,7 +450,7 @@ fileExplorer.prototype.packageFiles = function (filesProvider, callback) {
fileExplorer.prototype.copyFiles = function () {
let self = this
modalDialogCustom.prompt(
null,
'Copy files from browser explorer',
'To which other remix-ide instance do you want to copy over all files?',
'https://remix.ethereum.org',
(target) => {
@ -488,7 +488,7 @@ fileExplorer.prototype.updateGist = function () {
fileExplorer.prototype.createNewFile = function () {
let self = this
modalDialogCustom.prompt(null, 'File Name', 'Untitled.sol', (input) => {
modalDialogCustom.prompt('Create new file', 'File Name', 'Untitled.sol', (input) => {
helper.createNonClashingName(input, self.files, (error, newName) => {
if (error) return modalDialogCustom.alert('Failed to create file ' + newName + ' ' + error)
if (!self.files.set(newName, '')) {

@ -141,7 +141,7 @@ class ContractDropdownUI {
}
var promptCb = (okCb, cancelCb) => {
modalDialogCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
modalDialogCustom.promptPassphrase('Passphrase requested', 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
}
var statusCb = (msg) => {
@ -182,7 +182,7 @@ class ContractDropdownUI {
var address = this.atAddressButtonInput.value
this.dropdownLogic.loadContractFromAddress(address,
(cb) => {
modalDialogCustom.confirm(null, 'Do you really want to interact with ' + address + ' using the current ABI definition ?', cb)
modalDialogCustom.confirm(null, 'Do you really want to interact with ' + address + ' using the current ABI definition?', cb)
},
(error, loadType, abi) => {
if (error) {

@ -56,7 +56,7 @@ class RecorderUI {
}
var promptCb = (okCb, cancelCb) => {
modalDialogCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
modalDialogCustom.promptPassphrase('Passphrase requested', 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
}
var alertCb = (msg) => {
@ -76,7 +76,7 @@ class RecorderUI {
triggerRecordButton () {
this.recorder.saveScenario(
(path, cb) => {
modalDialogCustom.prompt(null, 'Transactions will be saved in a file under ' + path, 'scenario.json', cb)
modalDialogCustom.prompt('Save transactions as scenario', 'Transactions will be saved in a file under ' + path, 'scenario.json', cb)
},
(error) => {
if (error) return modalDialogCustom.alert(error)

@ -150,9 +150,12 @@ class SettingsUI {
this.settings.event.register('addProvider', (network) => {
selectExEnv.appendChild(yo`<option
title="Manually added environment: ${network.url}"
value="${network.name}" name="executionContext"> ${network.name}
</option>`)
title="Manually added environment: ${network.url}"
value="${network.name}"
name="executionContext"
>
${network.name}
</option>`)
addTooltip(`${network.name} [${network.url}] added`)
})
@ -167,8 +170,8 @@ class SettingsUI {
selectExEnv.addEventListener('change', (event) => {
let context = selectExEnv.options[selectExEnv.selectedIndex].value
this.settings.changeExecutionContext(context, () => {
modalDialogCustom.confirm(null, 'Are you sure you want to connect to an ethereum node?', () => {
modalDialogCustom.prompt(null, 'Web3 Provider Endpoint', 'http://localhost:8545', (target) => {
modalDialogCustom.confirm('External node request', 'Are you sure you want to connect to an ethereum node?', () => {
modalDialogCustom.prompt('External node request', 'Web3 Provider Endpoint', 'http://localhost:8545', (target) => {
this.settings.setProviderFromEndpoint(target, context, (alertMsg) => {
if (alertMsg) {
modalDialogCustom.alert(alertMsg)

@ -90,10 +90,10 @@ export class LandingPage extends BaseApi {
}
render () {
let load = function (item) {
let load = function (service, item) {
let compilerImport = new CompilerImport()
let fileProviders = globalRegistry.get('fileproviders').api
modalDialogCustom.prompt(null, 'Enter the ' + item + ' you would like to load.', null, (target) => {
modalDialogCustom.prompt(`Import from ${service}`, 'Enter the ' + item + ' you would like to load.', null, (target) => {
if (target !== '') {
compilerImport.import(
target,
@ -212,9 +212,9 @@ export class LandingPage extends BaseApi {
<p class="mb-1">Import From:</p>
<div class="btn-group">
<button class="btn btn-sm btn-secondary" onclick=${() => { importFromGist() }}>Gist</button>
<button class="btn btn-sm btn-secondary" onclick=${() => { load('Github URL') }}>Github</button>
<button class="btn btn-sm btn-secondary" onclick=${() => { load('bzz-raw URL') }}>Swarm</button>
<button class="btn btn-sm btn-secondary" onclick=${() => { load('ipfs URL') }}>Ipfs</button>
<button class="btn btn-sm btn-secondary" onclick=${() => { load('Github', 'Github URL') }}>Github</button>
<button class="btn btn-sm btn-secondary" onclick=${() => { load('Swarm', 'bzz-raw URL') }}>Swarm</button>
<button class="btn btn-sm btn-secondary" onclick=${() => { load('Ipfs', 'ipfs URL') }}>Ipfs</button>
</div><!-- end of btn-group -->
</div><!-- end of div.file -->
</div><!-- end of #col1 -->

@ -3,11 +3,12 @@ var css = require('./styles/modaldialog-styles')
module.exports = (title, content, ok, cancel, focusSelector, opts) => {
let agreed = true
let footerIsActive = true
opts = opts || {}
var container = document.querySelector(`.${css.modal}`)
var container = document.querySelector(`.modal`)
if (!container) {
document.querySelector('body').appendChild(html(opts))
container = document.querySelector(`.${css.modal}`)
container = document.querySelector(`.modal`)
}
var closeDiv = document.getElementById('modal-close')
@ -21,11 +22,11 @@ module.exports = (title, content, ok, cancel, focusSelector, opts) => {
cancelDiv.innerHTML = (cancel && cancel.label !== undefined) ? cancel.label : 'Cancel'
cancelDiv.style.display = cancelDiv.innerHTML === '' ? 'none' : 'inline-block'
var modal = document.querySelector(`.${css.modalBody}`)
var modalTitle = document.querySelector(`.${css.modalHeader} h3`)
var modal = document.querySelector(`.modal-body`)
var modalTitle = document.querySelector(`.modal-header h6`)
modalTitle.innerHTML = ''
if (title) modalTitle.innerHTML = title
if (title) modalTitle.innerText = title
modal.innerHTML = ''
if (content) modal.appendChild(content)
@ -57,22 +58,22 @@ module.exports = (title, content, ok, cancel, focusSelector, opts) => {
hide()
if (cancel && cancel.fn) cancel.fn()
if (container) {
container.class = css.modal
container.class = `modal`
container = null
}
}
function modalKeyEvent (e) {
if (e.keyCode === 27) {
if (e.keyCode === 27) { // Esc
cancelListener()
} else if (e.keyCode === 13) {
} else if (e.keyCode === 13) { // Enter
e.preventDefault()
okListener()
} else if (e.keyCode === 37) {
} else if (e.keyCode === 37 && footerIsActive) { // Arrow Left
e.preventDefault()
agreed = true
setFocusOn('ok')
} else if (e.keyCode === 39) {
} else if (e.keyCode === 39 && footerIsActive) { // Arrow Right
e.preventDefault()
agreed = false
setFocusOn('cancel')
@ -87,7 +88,7 @@ module.exports = (title, content, ok, cancel, focusSelector, opts) => {
if (!container) return
container.style.display = 'block'
if (focusSelector) {
const focusTarget = document.querySelector(`.${css.modal} ${focusSelector}`)
const focusTarget = document.querySelector(`.modal ${focusSelector}`)
if (focusTarget) {
focusTarget.focus()
if (typeof focusTarget.setSelectionRange === 'function') {
@ -110,25 +111,35 @@ module.exports = (title, content, ok, cancel, focusSelector, opts) => {
cancelDiv.addEventListener('click', cancelListener)
closeDiv.addEventListener('click', cancelListener)
document.addEventListener('keydown', modalKeyEvent)
if (document.getElementById('modal-background')) {
document.getElementById('modal-background').addEventListener('click', cancelListener)
let modalDialog = document.getElementById('modal-dialog')
if (modalDialog) {
modalDialog.addEventListener('click', (e) => {
footerIsActive = document.activeElement === modalDialog
if (e.toElement === modalDialog) {
cancelListener() // click is outside of modal-content
}
})
}
return { container, okListener, cancelListener }
}
function html (opts) {
return yo`<div id="modal-dialog" class="${css.modal}">
<div id="modal-background" class="${css['modalBackground']}"> </div>
<div class="${css['modalContent']} bg-light text-secondary ${opts.class}">
<div class="${css['modalHeader']}">
<h3></h3>
<i id="modal-close" title="Close" class="fas fa-times ${css['modalClose']}" aria-hidden="true"></i>
</div>
<div class="${css['modalBody']}"> -
</div>
<div class="${css['modalFooter']}">
<span id="modal-footer-ok" class="${css['modalFooterOk']} btn btn-sm btn-light">OK</span>
<span id="modal-footer-cancel" class="${css['modalFooterCancel']} btn btn-sm btn-light">Cancel</span>
return yo`
<div id="modal-dialog" class="modal" tabindex="-1" role="dialog">
<div id="modal-background" class="modal-dialog" role="document">
<div class="modal-content ${css.modalContent} ${opts.class}">
<div class="modal-header">
<h6 class="modal-title"></h6>
<span class="modal-close">
<i id="modal-close" title="Close" class="fas fa-times" aria-hidden="true"></i>
</span>
</div>
<div class="modal-body"> - </div>
<div class="modal-footer" autofocus>
<span id="modal-footer-ok" class="${css['modalFooterOk']} modal-ok btn btn-sm btn-light" tabindex='5'>OK</span>
<span id="modal-footer-cancel" class="${css['modalFooterCancel']} modal-cancel btn btn-sm btn-light" tabindex='10' data-dismiss="modal">Cancel</span>
</div>
</div>
</div>
</div>`

@ -46,7 +46,7 @@ var css = csjs`
padding : 0;
line-height : 18px;
font-size : 12px;
width : 50%;
width : 40%;
box-shadow : 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 0.4s;

@ -1,54 +1,10 @@
var csjs = require('csjs-inject')
var css = csjs`
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1000; /* Sit on top of everything including the dragbar */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
word-wrap: break-word;
}
.modalHeader {
padding: 2px 16px;
display: flex;
justify-content: space-between;
background: var(--info);
color: var(--primary);
}
.modalBody {
padding: 1.5em;
line-height: 1.5em;
color: var(--primary);
}
.modalBody em {
color: var(--success);
}
.modalBody a {
color: var(--secondary);
}
.modalBody a:hover {
color: var(--success);
}
.modalFooter {
display: flex;
justify-content: flex-end;
padding: 10px 30px;
text-align: right;
font-weight: 700;
cursor: pointer;
background-color: var(--info);
}
.modalContent {
position: relative;
margin: auto;
padding: 0;
line-height: 18px;
font-size: 14px;
width: 50%;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
-webkit-animation-name: animatetop;
-webkit-animation-duration: 0.4s;
@ -56,28 +12,8 @@ var css = csjs`
animation-duration: 0.4s
}
.modalFooterOk {
cursor: pointer;
}
.modalFooterOk:hover {
cursor: pointer;
}
.modalFooterCancel {
margin-left: 1em;
cursor: pointer;
}
.modalFooterCancel:hover {
margin-left: 1em;
cursor: pointer;
}
.modalClose {
margin: auto 0;
cursor: pointer;
}
.modalBackground {
width: 100%;
height: 100%;
position: fixed;
top:0;
}
@-webkit-keyframes animatetop {
from {top: -300px; opacity: 0}

@ -12,7 +12,7 @@ function GistHandler (_window) {
var gistId
if (params['gist'] === '') {
loadingFromGist = true
modalDialogCustom.prompt(null, 'Enter the ID of the Gist or URL you would like to load.', null, (target) => {
modalDialogCustom.prompt('Load a Gist', 'Enter the ID of the Gist or URL you would like to load.', null, (target) => {
if (target !== '') {
gistId = getGistId(target)
if (gistId) {

@ -229,7 +229,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
}
var promptCb = (okCb, cancelCb) => {
modalCustom.promptPassphrase(null, 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
modalCustom.promptPassphrase('Passphrase requested', 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
}
// contractsDetails is used to resolve libraries

@ -238,7 +238,7 @@ function addInstance (browser, address, isValidFormat, isValidChecksum, callback
browser.clickLaunchIcon('run').clearValue('.ataddressinput').setValue('.ataddressinput', address, function () {
browser.click('div[class^="atAddress"]')
.execute(function () {
var ret = document.querySelector('div[class^="modalBody"] div').innerHTML
var ret = document.querySelector('div[class="modal-body"] div').innerHTML
document.querySelector('#modal-footer-ok').click()
return ret
}, [], function (result) {

@ -19,7 +19,7 @@ function GistHandler (_window) {
if (params['gist'] === '') {
loadingFromGist = true
modalDialogCustom.prompt(
null,
'Load a Gist',
'Enter the URL or ID of the Gist you would like to load.',
null,
target => {

Loading…
Cancel
Save