Merge pull request #1629 from ethereum/addAutoCompletePopupPaddy
Add auto complete popup -rebased version of PR #1528 for @PaddyMcpull/1/head
commit
ce1ef91a79
@ -0,0 +1,58 @@ |
|||||||
|
const allPrograms = [ |
||||||
|
{'ethers': 'The ethers.js library is a compact and complete JavaScript library for Ethereum.'}, |
||||||
|
{'remix': 'Ethereum IDE and tools for the web.'}, |
||||||
|
{'web3': 'The web3.js library is a collection of modules which contain specific functionality for the ethereum ecosystem.'}, |
||||||
|
{'swarmgw': 'This library can be used to upload/download files to Swarm via https://swarm-gateways.net/.'} |
||||||
|
] |
||||||
|
|
||||||
|
const allCommands = [ |
||||||
|
{'remix.debug(hash)': 'Start debugging a transaction.'}, |
||||||
|
{'remix.debugHelp()': 'Display help message for debugging'}, |
||||||
|
{'remix.execute(filepath)': 'Run the script specified by file path. If filepath is empty, script currently displayed in the editor is executed.'}, |
||||||
|
{'remix.exeCurrent()': 'Run the script currently displayed in the editor.'}, |
||||||
|
{'remix.getFile(path)': 'Returns the content of the file located at the given path'}, |
||||||
|
{'remix.help()': 'Display this help message.'}, |
||||||
|
{'remix.loadgist(id)': 'Load a gist in the file explorer.'}, |
||||||
|
{'remix.loadurl(url)': 'Load the given url in the file explorer. The url can be of type github, swarm or ipfs.'}, |
||||||
|
{'remix.setFile(path, content)': 'set the content of the file located at the given path'}, |
||||||
|
{'remix.setproviderurl(url)': 'Change the current provider to Web3 provider and set the url endpoint.'}, |
||||||
|
|
||||||
|
{'swarmgw.get(url, cb)': 'Download files from Swarm via https://swarm-gateways.net/'}, |
||||||
|
{'swarmgw.put(content, cb)': 'Upload files to Swarm via https://swarm-gateways.net/'}, |
||||||
|
|
||||||
|
{'ethers.Contract': 'This API provides a graceful connection to a contract deployed on the blockchain, simplifying calling and querying its functions and handling all the binary protocol and conversion as necessarily.'}, |
||||||
|
{'ethers.HDNode': 'A Hierarchical Deterministic Wallet represents a large tree of private keys which can reliably be reproduced from an initial seed.'}, |
||||||
|
{'ethers.Interface': 'The Interface Object is a meta-class that accepts a Solidity (or compatible) Application Binary Interface (ABI) and populates functions to deal with encoding and decoding the parameters to pass in and results returned.'}, |
||||||
|
{'ethers.providers': 'A Provider abstracts a connection to the Ethereum blockchain, for issuing queries and sending state changing transactions.'}, |
||||||
|
{'ethers.SigningKey': 'The SigningKey interface provides an abstraction around the secp256k1 elliptic curve cryptography library.'}, |
||||||
|
{'ethers.utils': 'The utility functions exposed in both the ethers umbrella package and the ethers-utils.'}, |
||||||
|
{'ethers.utils.AbiCoder': 'Create a new ABI Coder object'}, |
||||||
|
{'ethers.utils.RLP': 'This encoding method is used internally for several aspects of Ethereum, such as encoding transactions and determining contract addresses.'}, |
||||||
|
{'ethers.Wallet': 'A wallet manages a private/public key pair which is used to cryptographically sign transactions and prove ownership on the Ethereum network.'}, |
||||||
|
{'ethers.version': 'Contains the version of the ethers container object.'}, |
||||||
|
|
||||||
|
{'web3.bzz': 'Bzz module for interacting with the swarm network.'}, |
||||||
|
{'web3.eth': 'Eth module for interacting with the Ethereum network.'}, |
||||||
|
{'web3.eth.accounts': 'The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.'}, |
||||||
|
{'web3.eth.abi': 'The web3.eth.abi functions let you de- and encode parameters to ABI (Application Binary Interface) for function calls to the EVM (Ethereum Virtual Machine).'}, |
||||||
|
{'web3.eth.ens': 'The web3.eth.ens functions let you interacting with ENS.'}, |
||||||
|
{'web3.eth.Iban': 'The web3.eth.Iban function lets convert Ethereum addresses from and to IBAN and BBAN.'}, |
||||||
|
{'web3.eth.net': 'Net module for interacting with network properties.'}, |
||||||
|
{'web3.eth.personal': 'Personal module for interacting with the Ethereum accounts.'}, |
||||||
|
{'web3.eth.subscribe': 'The web3.eth.subscribe function lets you subscribe to specific events in the blockchain.'}, |
||||||
|
{'web3.givenProvider': 'When using web3.js in an Ethereum compatible browser, it will set with the current native provider by that browser. Will return the given provider by the (browser) environment, otherwise null.'}, |
||||||
|
{'web3.modules': 'Contains the version of the web3 container object.'}, |
||||||
|
{'web3.providers': 'Contains the current available providers.'}, |
||||||
|
{'web3.shh': 'Shh module for interacting with the whisper protocol'}, |
||||||
|
{'web3.utils': 'This package provides utility functions for Ethereum dapps and other web3.js packages.'}, |
||||||
|
{'web3.version': 'Contains the version of the web3 container object.'}, |
||||||
|
|
||||||
|
{'web3.eth.clearSubscriptions();': 'Resets subscriptions.'}, |
||||||
|
{'web3.eth.Contract(jsonInterface[, address][, options])': 'The web3.eth.Contract object makes it easy to interact with smart contracts on the ethereum blockchain.'}, |
||||||
|
{'web3.eth.accounts.create([entropy]);': 'The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.'} |
||||||
|
] |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
allPrograms, |
||||||
|
allCommands |
||||||
|
} |
@ -0,0 +1,135 @@ |
|||||||
|
var yo = require('yo-yo') |
||||||
|
var remixLib = require('remix-lib') |
||||||
|
var EventManager = remixLib.EventManager |
||||||
|
|
||||||
|
var modal = require('./modaldialog.js') |
||||||
|
|
||||||
|
// -------------- styling ----------------------
|
||||||
|
var css = require('./styles/auto-complete-popup-styles') |
||||||
|
var cssModal = require('./styles/modaldialog-styles') |
||||||
|
|
||||||
|
/* USAGE: |
||||||
|
|
||||||
|
var autoCompletePopup = new AutoCompletePopup({ |
||||||
|
options: [] |
||||||
|
}) |
||||||
|
autoCompletePopup.event.register('handleSelect', function (input) { }) |
||||||
|
autoCompletePopup.event.register('updateList', function () { }) |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
class AutoCompletePopup { |
||||||
|
constructor (opts = {}) { |
||||||
|
var self = this |
||||||
|
self.event = new EventManager() |
||||||
|
self.data = { |
||||||
|
_options: opts.options || [] |
||||||
|
} |
||||||
|
self._view = {} |
||||||
|
self._startingElement = 0 |
||||||
|
self._elementsToShow = 3 |
||||||
|
self._removePopUp = this.resetCSSValuesModalContainer |
||||||
|
} |
||||||
|
|
||||||
|
resetCSSValuesModalContainer () { |
||||||
|
var modalContainer = document.querySelector(`.${cssModal.modal}`) |
||||||
|
modalContainer.style.display = 'none' |
||||||
|
var modalContent = document.querySelector(`.${css.modalContent}`) |
||||||
|
let newModalContent = modalContent ? document.querySelector(`.${css.modalContent}`) : document.querySelector(`.${cssModal.modalContent}`) |
||||||
|
newModalContent.className = cssModal.modalContent |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
var self = this |
||||||
|
var header = yo`<div class="${css.text}">Remix Commands</div>` |
||||||
|
self._view.autoComplete = yo` |
||||||
|
<div class="${css.popup}"> |
||||||
|
<div> |
||||||
|
${self.data._options.map((item, index) => { |
||||||
|
return yo` |
||||||
|
<div class="${css.listHandlerHide}"> |
||||||
|
<a value=${index}> |
||||||
|
<div onclick=${handleSelect}> |
||||||
|
${Object.keys(item)[0]}
|
||||||
|
</div> |
||||||
|
</a> |
||||||
|
<div> |
||||||
|
${Object.values(item)[0]} |
||||||
|
</div> |
||||||
|
<hr/> |
||||||
|
</div> |
||||||
|
` |
||||||
|
})} |
||||||
|
</div> |
||||||
|
<div class="${css.listHandlerHide}"> |
||||||
|
<button value=false onclick=${handleListIteration}>▲</button> |
||||||
|
<button value=true onclick=${handleListIteration}>▼</button> |
||||||
|
<div class="${css.pageNumberAlignment}">Page ${(self._startingElement / self._elementsToShow) + 1} of ${Math.ceil(self.data._options.length / self._elementsToShow)}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
` |
||||||
|
function setUpPopUp () { |
||||||
|
handleOpenPopup() |
||||||
|
handleNagivationButtons() |
||||||
|
handleListSize() |
||||||
|
} |
||||||
|
|
||||||
|
function handleOpenPopup () { |
||||||
|
if (self.data._options.length > 1) { |
||||||
|
self._view.autoComplete.style.display = 'block' |
||||||
|
modal(header.innerText, self._view.autoComplete, {label: null}, |
||||||
|
{ |
||||||
|
fn: () => { self._removePopUp() } |
||||||
|
}) |
||||||
|
editCSSValuesModalContainer() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function handleSelect (event) { |
||||||
|
self._removePopUp() |
||||||
|
self._view.autoComplete.style.display = 'none' |
||||||
|
self.event.trigger('handleSelect', [event.srcElement.innerText]) |
||||||
|
} |
||||||
|
|
||||||
|
function handleNagivationButtons () { |
||||||
|
if (self.data._options.length > self._elementsToShow) { |
||||||
|
self._view.autoComplete.children[1].className = css.listHandlerButtonShow |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function handleListSize () { |
||||||
|
if (self.data._options.length >= self._startingElement) { |
||||||
|
for (let i = self._startingElement; i < (self._elementsToShow + self._startingElement); i++) { |
||||||
|
if (self._view.autoComplete.children[0].children[i]) { |
||||||
|
self._view.autoComplete.children[0].children[i].className = css.listHandlerShow |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function handleListIteration (event) { |
||||||
|
if (event.srcElement.value === 'true' || event.which === 40) { |
||||||
|
if ((self._startingElement + self._elementsToShow) < self.data._options.length) { |
||||||
|
self._startingElement += self._elementsToShow |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (self._startingElement > 0) { |
||||||
|
self._startingElement -= self._elementsToShow |
||||||
|
} |
||||||
|
} |
||||||
|
self.event.trigger('updateList') |
||||||
|
} |
||||||
|
|
||||||
|
function editCSSValuesModalContainer () { |
||||||
|
var modalContent = document.querySelector(`.${cssModal.modalContent}`) |
||||||
|
let newModalContent = modalContent ? document.querySelector(`.${cssModal.modalContent}`) : document.querySelector(`.${css.modalContent}`) |
||||||
|
newModalContent.className = css.modalContent |
||||||
|
} |
||||||
|
|
||||||
|
setUpPopUp() |
||||||
|
return self._view |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
module.exports = AutoCompletePopup |
@ -0,0 +1,67 @@ |
|||||||
|
var csjs = require('csjs-inject') |
||||||
|
var styleGuide = require('../styles-guide/theme-chooser') |
||||||
|
var styles = styleGuide.chooser() |
||||||
|
|
||||||
|
var css = csjs` |
||||||
|
.popup { |
||||||
|
text-align : left; |
||||||
|
display : none; |
||||||
|
width : 100%; |
||||||
|
font-family : monospace; |
||||||
|
font-size : 10px; |
||||||
|
overflow : auto; |
||||||
|
padding-bottom : 13px; |
||||||
|
} |
||||||
|
|
||||||
|
.popup a { |
||||||
|
cursor : pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.listHandlerShow { |
||||||
|
display : block; |
||||||
|
} |
||||||
|
|
||||||
|
.listHandlerHide { |
||||||
|
display : none; |
||||||
|
} |
||||||
|
|
||||||
|
.listHandlerButtonShow { |
||||||
|
position : fixed; |
||||||
|
width : 46%; |
||||||
|
} |
||||||
|
|
||||||
|
.pageNumberAlignment { |
||||||
|
font-size : 10px; |
||||||
|
float : right; |
||||||
|
} |
||||||
|
|
||||||
|
.modalContent { |
||||||
|
position : absolute; |
||||||
|
margin-left : 20%; |
||||||
|
margin-bottom : 32px; |
||||||
|
bottom : 0px; |
||||||
|
background-color : ${styles.colors.black}; |
||||||
|
padding : 0; |
||||||
|
line-height : 18px; |
||||||
|
font-size : 12px; |
||||||
|
border : 1px solid ${styles.colors.grey}; |
||||||
|
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: animatebottom; |
||||||
|
-webkit-animation-duration: 0.4s; |
||||||
|
animation-name : animatetop; |
||||||
|
animation-duration: 0.4s |
||||||
|
} |
||||||
|
|
||||||
|
@-webkit-keyframes animatetop { |
||||||
|
from {bottom: -300px; opacity: 0} |
||||||
|
to {bottom: 0; opacity: 1} |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes animatetop { |
||||||
|
from {bottom: -300px; opacity: 0} |
||||||
|
to {bottom: 0; opacity: 1} |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
module.exports = css |
Loading…
Reference in new issue