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