From 2f9b73292e0d6749c5bebd08ab3f9355829cd9ee Mon Sep 17 00:00:00 2001 From: PaddyMc Date: Tue, 18 Sep 2018 12:50:22 +0100 Subject: [PATCH 1/4] Issue#1462: Terminal command autocomplete support --- src/app/constants/commands.js | 56 +++++++++++ src/app/panels/terminal.js | 54 +++++++++++ src/app/ui/auto-complete-popup.js | 95 +++++++++++++++++++ .../ui/styles/auto-complete-popup-styles.js | 68 +++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 src/app/constants/commands.js create mode 100644 src/app/ui/auto-complete-popup.js create mode 100644 src/app/ui/styles/auto-complete-popup-styles.js diff --git a/src/app/constants/commands.js b/src/app/constants/commands.js new file mode 100644 index 0000000000..6406d0911f --- /dev/null +++ b/src/app/constants/commands.js @@ -0,0 +1,56 @@ +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.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.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 +} diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js index 7b379d2be5..0d8f5c2826 100644 --- a/src/app/panels/terminal.js +++ b/src/app/panels/terminal.js @@ -13,6 +13,8 @@ var swarmgw = require('swarmgw')() var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI') var executionContext = require('../../execution-context') var Dropdown = require('../ui/dropdown') +var AutoCompletePopup = require('../ui/auto-complete-popup') +var Commands = require('../constants/commands') var csjs = require('csjs-inject') var styleGuide = require('../ui/styles-guide/theme-chooser') @@ -62,6 +64,17 @@ class Terminal { self.updateJournal({ type: 'select', value: label }) } }) + self._components.autoCompletePopup = new AutoCompletePopup() + self._components.autoCompletePopup.event.register('handleSelect', function (input) { + self._components.autoCompletePopup.data._options = [] + self._components.autoCompletePopup._startingElement = 0 + self._view.input.innerText = input + self._view.input.focus() + yo.update(self._view.autoCompletePopup, self._components.autoCompletePopup.render()) + }) + self._components.autoCompletePopup.event.register('updateList', function () { + yo.update(self._view.autoCompletePopup, self._components.autoCompletePopup.render()) + }) self._commands = {} self.commands = {} self._JOURNAL = [] @@ -149,10 +162,12 @@ class Terminal { ` + self._view.autoCompletePopup = self._components.autoCompletePopup.render() self._view.el = yo`
${self._view.bar} ${self._view.term} + ${self._view.autoCompletePopup}
` setInterval(() => { @@ -391,12 +406,14 @@ class Terminal { return self._view.el function change (event) { + handleAutoComplete(event) if (self._view.input.innerText.length === 0) self._view.input.innerText += '\n' if (event.which === 13) { if (event.ctrlKey) { // self._view.input.innerText += '\n' putCursor2End(self._view.input) self.scroll2bottom() + removeAutoComplete() } else { // self._cmdIndex = -1 self._cmdTemp = '' @@ -407,6 +424,7 @@ class Terminal { self._cmdHistory.unshift(script) self.commands.script(script) } + removeAutoComplete() } } else if (event.which === 38) { // var len = self._cmdHistory.length @@ -417,6 +435,7 @@ class Terminal { self._view.input.innerText = self._cmdHistory[self._cmdIndex] putCursor2End(self._view.input) self.scroll2bottom() + removeAutoComplete() } else if (event.which === 40) { // if (self._cmdIndex > -1) { self._cmdIndex-- @@ -424,6 +443,7 @@ class Terminal { self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp putCursor2End(self._view.input) self.scroll2bottom() + removeAutoComplete() } else { self._cmdTemp = self._view.input.innerText } @@ -455,6 +475,40 @@ class Terminal { editable.focus() } + function handleAutoComplete (event) { + if (event.which === 9) { + event.preventDefault() + if (self._view.input.innerText.length >= 2) { + self._components.autoCompletePopup.data._options = [] + Commands.allPrograms.forEach(item => { + if (Object.keys(item)[0].substring(0, Object.keys(item)[0].length - 1).includes(self._view.input.innerText.trim())) { + self._components.autoCompletePopup.data._options.push(item) + } else if (self._view.input.innerText.trim().includes(Object.keys(item)[0]) || (Object.keys(item)[0] === self._view.input.innerText.trim())) { + Commands.allCommands.forEach(item => { + if (Object.keys(item)[0].includes(self._view.input.innerText.trim())) { + self._components.autoCompletePopup.data._options.push(item) + } + }) + } + }) + } + if (self._components.autoCompletePopup.data._options.length === 1) { + self._view.input.innerText = Object.keys(self._components.autoCompletePopup.data._options[0])[0] + self._components.autoCompletePopup.data._options = [] + putCursor2End(self._view.input) + } + } + if (event.which === 27 || event.which === 8 || event.which === 46) { + self._components.autoCompletePopup.data._options = [] + self._components.autoCompletePopup._startingElement = 0 + } + yo.update(self._view.autoCompletePopup, self._components.autoCompletePopup.render()) + } + function removeAutoComplete () { + self._components.autoCompletePopup.data._options = [] + self._components.autoCompletePopup._startingElement = 0 + yo.update(self._view.autoCompletePopup, self._components.autoCompletePopup.render()) + } } updateJournal (filterEvent) { var self = this diff --git a/src/app/ui/auto-complete-popup.js b/src/app/ui/auto-complete-popup.js new file mode 100644 index 0000000000..9b429e0d40 --- /dev/null +++ b/src/app/ui/auto-complete-popup.js @@ -0,0 +1,95 @@ +var yo = require('yo-yo') +var remixLib = require('remix-lib') +var EventManager = remixLib.EventManager + +// -------------- styling ---------------------- +var css = require('./styles/auto-complete-popup-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 + } + + render () { + var self = this + self._view.autoComplete = yo` +
+
+ ${self.data._options.map((item, index) => { + return yo` +
+
+ +
+ ${Object.keys(item)[0]} +
+
+
+ ${Object.values(item)[0]} +
+
+
+ ` + })} +
+ + +
Page ${(self._startingElement / self._elementsToShow) + 1} of ${Math.ceil(self.data._options.length / self._elementsToShow)}
+
+ ` + handleNagivationButtons() + handleListSize() + return self._view.autoComplete + + function handleSelect (event) { + self.event.trigger('handleSelect', [event.srcElement.innerText]) + } + function handleNagivationButtons () { + if (self.data._options.length > self._elementsToShow) { + self._view.autoComplete.children[1].className = css.listHandlerButtonShow + self._view.autoComplete.children[2].className = css.listHandlerButtonShow + self._view.autoComplete.children[3].className = css.pageNumberAlignment + } + } + 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') { + 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') + } + } +} + +module.exports = AutoCompletePopup diff --git a/src/app/ui/styles/auto-complete-popup-styles.js b/src/app/ui/styles/auto-complete-popup-styles.js new file mode 100644 index 0000000000..20584e8d70 --- /dev/null +++ b/src/app/ui/styles/auto-complete-popup-styles.js @@ -0,0 +1,68 @@ +var csjs = require('csjs-inject') +var styleGuide = require('../styles-guide/theme-chooser') +var styles = styleGuide.chooser() + +var css = csjs` + .popup { + text-align : center; + z-index : 1; + position : absolute; + width : 100%; + justify-content : center; + bottom : 0; + margin-bottom : 32px; + border-radius : 6px; + padding : 8px 0; + opacity : 0.8; + } + + .popupcontent { + display : block; + position : absolute; + background-color : #f1f1f1; + width : 100%; + box-shadow : 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index : 1; + bottom : 100%; + } + + .popupcontent a { + color : ${styles.terminal.text_Primary}; + font-family : monospace; + font-size : 10px; + display : block; + } + + .popupcontent div { + font-family : monospace; + font-size : 10px; + } + + .popupcontent a:hover { + background-color : #ddd; + } + + .listHandlerShow { + display : block; + } + + .listHandlerHide { + display : none; + } + + .listHandlerButtonShow { + display : inline; + float : center; + opacity : 0.8; + } + + .pageNumberAlignment { + display : inline; + position : absolute; + padding-right : 10px; + font-family : monospace; + font-size : 10px; + margin-left : 30%; + } +` +module.exports = css From 21a010b72b6ecbb41122eccaae6300c15d494ae2 Mon Sep 17 00:00:00 2001 From: PaddyMc Date: Tue, 18 Sep 2018 19:23:09 +0100 Subject: [PATCH 2/4] Issue#1462: Added directional keys list iteration --- src/app/panels/terminal.js | 34 ++++++++++++++++++------------- src/app/ui/auto-complete-popup.js | 2 +- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js index 0d8f5c2826..0fa4f961f4 100644 --- a/src/app/panels/terminal.js +++ b/src/app/panels/terminal.js @@ -427,23 +427,29 @@ class Terminal { removeAutoComplete() } } else if (event.which === 38) { // - var len = self._cmdHistory.length - if (len === 0) return event.preventDefault() - if (self._cmdHistory.length - 1 > self._cmdIndex) { - self._cmdIndex++ + if (self._components.autoCompletePopup.data._options.length > self._components.autoCompletePopup._elementsToShow) { + self._components.autoCompletePopup._view.autoComplete.children[1].onclick(event) + } else { + var len = self._cmdHistory.length + if (len === 0) return event.preventDefault() + if (self._cmdHistory.length - 1 > self._cmdIndex) { + self._cmdIndex++ + } + self._view.input.innerText = self._cmdHistory[self._cmdIndex] + putCursor2End(self._view.input) + self.scroll2bottom() } - self._view.input.innerText = self._cmdHistory[self._cmdIndex] - putCursor2End(self._view.input) - self.scroll2bottom() - removeAutoComplete() } else if (event.which === 40) { // - if (self._cmdIndex > -1) { - self._cmdIndex-- + if (self._components.autoCompletePopup.data._options.length > self._components.autoCompletePopup._elementsToShow) { + self._components.autoCompletePopup._view.autoComplete.children[1].onclick(event) + } else { + if (self._cmdIndex > -1) { + self._cmdIndex-- + } + self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp + putCursor2End(self._view.input) + self.scroll2bottom() } - self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp - putCursor2End(self._view.input) - self.scroll2bottom() - removeAutoComplete() } else { self._cmdTemp = self._view.input.innerText } diff --git a/src/app/ui/auto-complete-popup.js b/src/app/ui/auto-complete-popup.js index 9b429e0d40..43c4d760c5 100644 --- a/src/app/ui/auto-complete-popup.js +++ b/src/app/ui/auto-complete-popup.js @@ -78,7 +78,7 @@ class AutoCompletePopup { } } function handleListIteration (event) { - if (event.srcElement.value === 'true') { + if (event.srcElement.value === 'true' || event.which === 40) { if ((self._startingElement + self._elementsToShow) < self.data._options.length) { self._startingElement += self._elementsToShow } From 189992777cabb37e1c324b3dfca0cb02bb7503c2 Mon Sep 17 00:00:00 2001 From: PaddyMc Date: Tue, 9 Oct 2018 15:53:53 +0100 Subject: [PATCH 3/4] Fixes#1462 Update cursor on auto complete popup --- src/app/ui/styles/auto-complete-popup-styles.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/ui/styles/auto-complete-popup-styles.js b/src/app/ui/styles/auto-complete-popup-styles.js index 20584e8d70..f3897072d2 100644 --- a/src/app/ui/styles/auto-complete-popup-styles.js +++ b/src/app/ui/styles/auto-complete-popup-styles.js @@ -31,6 +31,7 @@ var css = csjs` font-family : monospace; font-size : 10px; display : block; + cursor : pointer; } .popupcontent div { From 1da2a737cc2684f3e5cf51c746d7c1eb33805f92 Mon Sep 17 00:00:00 2001 From: PaddyMc Date: Fri, 16 Nov 2018 00:04:14 +0000 Subject: [PATCH 4/4] Fixes #1462: UI update & sentance autocomplete --- src/app/constants/commands.js | 2 + src/app/panels/terminal.js | 23 +++-- src/app/ui/auto-complete-popup.js | 92 +++++++++++++------ .../ui/styles/auto-complete-popup-styles.js | 78 ++++++++-------- 4 files changed, 121 insertions(+), 74 deletions(-) diff --git a/src/app/constants/commands.js b/src/app/constants/commands.js index 6406d0911f..fe579ee037 100644 --- a/src/app/constants/commands.js +++ b/src/app/constants/commands.js @@ -10,9 +10,11 @@ const allCommands = [ {'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/'}, diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js index 0fa4f961f4..a5cb7ea3e7 100644 --- a/src/app/panels/terminal.js +++ b/src/app/panels/terminal.js @@ -68,7 +68,10 @@ class Terminal { self._components.autoCompletePopup.event.register('handleSelect', function (input) { self._components.autoCompletePopup.data._options = [] self._components.autoCompletePopup._startingElement = 0 - self._view.input.innerText = input + let textList = self._view.input.innerText.split(' ') + textList.pop() + textList.push(input) + self._view.input.innerText = `${textList}`.replace(/,/g, ' ') self._view.input.focus() yo.update(self._view.autoCompletePopup, self._components.autoCompletePopup.render()) }) @@ -167,7 +170,6 @@ class Terminal {
${self._view.bar} ${self._view.term} - ${self._view.autoCompletePopup}
` setInterval(() => { @@ -428,7 +430,7 @@ class Terminal { } } else if (event.which === 38) { // if (self._components.autoCompletePopup.data._options.length > self._components.autoCompletePopup._elementsToShow) { - self._components.autoCompletePopup._view.autoComplete.children[1].onclick(event) + self._components.autoCompletePopup._view.autoComplete.children[1].children[0].onclick(event) } else { var len = self._cmdHistory.length if (len === 0) return event.preventDefault() @@ -441,7 +443,7 @@ class Terminal { } } else if (event.which === 40) { // if (self._components.autoCompletePopup.data._options.length > self._components.autoCompletePopup._elementsToShow) { - self._components.autoCompletePopup._view.autoComplete.children[1].onclick(event) + self._components.autoCompletePopup._view.autoComplete.children[1].children[1].onclick(event) } else { if (self._cmdIndex > -1) { self._cmdIndex-- @@ -484,14 +486,16 @@ class Terminal { function handleAutoComplete (event) { if (event.which === 9) { event.preventDefault() + let textList = self._view.input.innerText.split(' ') + let autoCompleteInput = textList.length > 1 ? textList[textList.length - 1] : textList[0] if (self._view.input.innerText.length >= 2) { self._components.autoCompletePopup.data._options = [] Commands.allPrograms.forEach(item => { - if (Object.keys(item)[0].substring(0, Object.keys(item)[0].length - 1).includes(self._view.input.innerText.trim())) { + if (Object.keys(item)[0].substring(0, Object.keys(item)[0].length - 1).includes(autoCompleteInput.trim())) { self._components.autoCompletePopup.data._options.push(item) - } else if (self._view.input.innerText.trim().includes(Object.keys(item)[0]) || (Object.keys(item)[0] === self._view.input.innerText.trim())) { + } else if (autoCompleteInput.trim().includes(Object.keys(item)[0]) || (Object.keys(item)[0] === autoCompleteInput.trim())) { Commands.allCommands.forEach(item => { - if (Object.keys(item)[0].includes(self._view.input.innerText.trim())) { + if (Object.keys(item)[0].includes(autoCompleteInput.trim())) { self._components.autoCompletePopup.data._options.push(item) } }) @@ -499,7 +503,9 @@ class Terminal { }) } if (self._components.autoCompletePopup.data._options.length === 1) { - self._view.input.innerText = Object.keys(self._components.autoCompletePopup.data._options[0])[0] + textList.pop() + textList.push(Object.keys(self._components.autoCompletePopup.data._options[0])[0]) + self._view.input.innerText = `${textList}`.replace(/,/g, ' ') self._components.autoCompletePopup.data._options = [] putCursor2End(self._view.input) } @@ -513,6 +519,7 @@ class Terminal { function removeAutoComplete () { self._components.autoCompletePopup.data._options = [] self._components.autoCompletePopup._startingElement = 0 + self._components.autoCompletePopup._removePopUp() yo.update(self._view.autoCompletePopup, self._components.autoCompletePopup.render()) } } diff --git a/src/app/ui/auto-complete-popup.js b/src/app/ui/auto-complete-popup.js index 43c4d760c5..5c829104f0 100644 --- a/src/app/ui/auto-complete-popup.js +++ b/src/app/ui/auto-complete-popup.js @@ -2,8 +2,11 @@ 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: @@ -25,49 +28,75 @@ class AutoCompletePopup { 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`
Remix Commands
` self._view.autoComplete = yo` -
-
- ${self.data._options.map((item, index) => { - return yo` -
-
- -
- ${Object.keys(item)[0]} -
-
-
- ${Object.values(item)[0]} + + ` + })} +
+
+ + +
Page ${(self._startingElement / self._elementsToShow) + 1} of ${Math.ceil(self.data._options.length / self._elementsToShow)}
+
` - handleNagivationButtons() - handleListSize() - return self._view.autoComplete + 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 - self._view.autoComplete.children[2].className = css.listHandlerButtonShow - self._view.autoComplete.children[3].className = css.pageNumberAlignment } } + function handleListSize () { if (self.data._options.length >= self._startingElement) { for (let i = self._startingElement; i < (self._elementsToShow + self._startingElement); i++) { @@ -77,6 +106,7 @@ class AutoCompletePopup { } } } + function handleListIteration (event) { if (event.srcElement.value === 'true' || event.which === 40) { if ((self._startingElement + self._elementsToShow) < self.data._options.length) { @@ -89,7 +119,17 @@ class AutoCompletePopup { } 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 diff --git a/src/app/ui/styles/auto-complete-popup-styles.js b/src/app/ui/styles/auto-complete-popup-styles.js index f3897072d2..5141ce7436 100644 --- a/src/app/ui/styles/auto-complete-popup-styles.js +++ b/src/app/ui/styles/auto-complete-popup-styles.js @@ -4,43 +4,17 @@ var styles = styleGuide.chooser() var css = csjs` .popup { - text-align : center; - z-index : 1; - position : absolute; - width : 100%; - justify-content : center; - bottom : 0; - margin-bottom : 32px; - border-radius : 6px; - padding : 8px 0; - opacity : 0.8; - } - - .popupcontent { - display : block; - position : absolute; - background-color : #f1f1f1; + text-align : left; + display : none; width : 100%; - box-shadow : 0px 8px 16px 0px rgba(0,0,0,0.2); - z-index : 1; - bottom : 100%; - } - - .popupcontent a { - color : ${styles.terminal.text_Primary}; - font-family : monospace; - font-size : 10px; - display : block; - cursor : pointer; - } - - .popupcontent div { font-family : monospace; font-size : 10px; + overflow : auto; + padding-bottom : 13px; } - .popupcontent a:hover { - background-color : #ddd; + .popup a { + cursor : pointer; } .listHandlerShow { @@ -52,18 +26,42 @@ var css = csjs` } .listHandlerButtonShow { - display : inline; - float : center; - opacity : 0.8; + position : fixed; + width : 46%; } .pageNumberAlignment { - display : inline; - position : absolute; - padding-right : 10px; - font-family : monospace; font-size : 10px; - margin-left : 30%; + 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