diff --git a/README.md b/README.md
index 61e0dd4..02d996b 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,28 @@
+# Tilde Enhanced
+
+Based on [Cade Scroggins](https://github.com/cadejscroggins)'s [Tilde](https://github.com/cadejscroggins/tilde).
+
## Screenshots

-# Tilde Enhanced
-
-A slightly modified version of [Cade Scroggins](https://github.com/cadejscroggins)'s homepage [Tilde](https://github.com/cadejscroggins/tilde).
-Most of the features are carried over from the original source.
## Added Features
+Most of the features are carried over from the original source.
+Few of the added features are:
-- Clicking on the clock will bring up pre-defined sites.
+- Added a "Quick Launch" functionality, which launches all the sites with `quickLaunch`
+property set to true upon hitting `!` key.
+- Clicking on the clock brings up pre-defined sites.
- Available sites show their icons instead of their corresponding keys.
-- Other small changes on grids and boxes.
+- Added the option to invert colour theme. You can either edit config or use `invert!` command.
+- Other small changes on grids.
## Usage
+To use Tilde as your homepage, simply set your browser's home URL to
+Tilde's index file.
To go to a site, enter the first letter of the site then hit enter.
To view the available sites, press `?` or click on the clock.
If your input doesn't match any of the commands,
@@ -26,7 +33,9 @@ a generic DuckDuckGo search will be triggered. For example:
- Entering `cats` would search [Cats](https://duckduckgo.com/?q=cats).
Note that by default, queries are searched on DuckDuckGo but this can be
-configured easily by updating two lines.
+configured easily by updating two lines on. Check [Configuration](#configuration) for details.
+
+You might have to allow pop-ups for your homepage to use quick launch feature.
This version is not suitable for use on mobile as clicking on the clock will
only bring up pre-defined sites.
@@ -73,9 +82,8 @@ This allows you to invoke Tilde with your native browser search bar.
## Configuration
-The above is just the beginning. Open up the [index.html](index.html) file and
-read through the `CONFIG`!
+Open up the [script.js](assets/script.js) file and read through the `CONFIG`!
## License
-Feel free to [use this and modify it however you like](https://github.com/cadejscroggins/tilde/blob/master/LICENSE).
+Feel free to [use this and modify it however you like](https://github.com/Ozencb/tilde-enhanced/blob/master/LICENSE).
diff --git a/assets/fonts/Roboto-Black.woff b/assets/fonts/Roboto-Black.woff
new file mode 100644
index 0000000..bd0494e
Binary files /dev/null and b/assets/fonts/Roboto-Black.woff differ
diff --git a/assets/fonts/Roboto-Black.woff2 b/assets/fonts/Roboto-Black.woff2
new file mode 100644
index 0000000..30a1e36
Binary files /dev/null and b/assets/fonts/Roboto-Black.woff2 differ
diff --git a/assets/fonts/Roboto-Regular.woff b/assets/fonts/Roboto-Regular.woff
new file mode 100644
index 0000000..3acceb6
Binary files /dev/null and b/assets/fonts/Roboto-Regular.woff differ
diff --git a/assets/fonts/Roboto-Regular.woff2 b/assets/fonts/Roboto-Regular.woff2
new file mode 100644
index 0000000..1999612
Binary files /dev/null and b/assets/fonts/Roboto-Regular.woff2 differ
diff --git a/assets/icons/arstechnica.png b/assets/icons/arstechnica.png
new file mode 100644
index 0000000..9e1af2d
Binary files /dev/null and b/assets/icons/arstechnica.png differ
diff --git a/assets/icons/drive.png b/assets/icons/drive.png
new file mode 100644
index 0000000..dc54a16
Binary files /dev/null and b/assets/icons/drive.png differ
diff --git a/assets/icons/github.png b/assets/icons/github.png
new file mode 100644
index 0000000..d94c475
Binary files /dev/null and b/assets/icons/github.png differ
diff --git a/assets/icons/imdb.png b/assets/icons/imdb.png
new file mode 100644
index 0000000..36a5069
Binary files /dev/null and b/assets/icons/imdb.png differ
diff --git a/assets/icons/linkedin.png b/assets/icons/linkedin.png
new file mode 100644
index 0000000..7e30f2e
Binary files /dev/null and b/assets/icons/linkedin.png differ
diff --git a/assets/icons/mail.png b/assets/icons/mail.png
new file mode 100644
index 0000000..95aa209
Binary files /dev/null and b/assets/icons/mail.png differ
diff --git a/assets/icons/netflix.png b/assets/icons/netflix.png
new file mode 100644
index 0000000..4112d7c
Binary files /dev/null and b/assets/icons/netflix.png differ
diff --git a/assets/icons/reddit.png b/assets/icons/reddit.png
new file mode 100644
index 0000000..24d50bb
Binary files /dev/null and b/assets/icons/reddit.png differ
diff --git a/assets/icons/stackoverflow.png b/assets/icons/stackoverflow.png
new file mode 100644
index 0000000..623409a
Binary files /dev/null and b/assets/icons/stackoverflow.png differ
diff --git a/assets/icons/twitch.png b/assets/icons/twitch.png
new file mode 100644
index 0000000..050aa5e
Binary files /dev/null and b/assets/icons/twitch.png differ
diff --git a/assets/icons/twitter.png b/assets/icons/twitter.png
new file mode 100644
index 0000000..84ddb4e
Binary files /dev/null and b/assets/icons/twitter.png differ
diff --git a/assets/icons/youtube.png b/assets/icons/youtube.png
new file mode 100644
index 0000000..d555971
Binary files /dev/null and b/assets/icons/youtube.png differ
diff --git a/assets/screenshot.png b/assets/screenshot.png
index 5b9d493..2623faf 100644
Binary files a/assets/screenshot.png and b/assets/screenshot.png differ
diff --git a/fonts/lato-v14-latin-900.woff b/fonts/lato-v14-latin-900.woff
deleted file mode 100644
index 6f251d9..0000000
Binary files a/fonts/lato-v14-latin-900.woff and /dev/null differ
diff --git a/fonts/lato-v14-latin-900.woff2 b/fonts/lato-v14-latin-900.woff2
deleted file mode 100644
index a5abe36..0000000
Binary files a/fonts/lato-v14-latin-900.woff2 and /dev/null differ
diff --git a/fonts/lato-v14-latin-regular.woff b/fonts/lato-v14-latin-regular.woff
deleted file mode 100644
index 97ab144..0000000
Binary files a/fonts/lato-v14-latin-regular.woff and /dev/null differ
diff --git a/fonts/lato-v14-latin-regular.woff2 b/fonts/lato-v14-latin-regular.woff2
deleted file mode 100644
index b14c76c..0000000
Binary files a/fonts/lato-v14-latin-regular.woff2 and /dev/null differ
diff --git a/icons/arstechnica.png b/icons/arstechnica.png
deleted file mode 100644
index fcad23a..0000000
Binary files a/icons/arstechnica.png and /dev/null differ
diff --git a/icons/drive.png b/icons/drive.png
deleted file mode 100644
index aed7903..0000000
Binary files a/icons/drive.png and /dev/null differ
diff --git a/icons/github.png b/icons/github.png
deleted file mode 100644
index b1dee4c..0000000
Binary files a/icons/github.png and /dev/null differ
diff --git a/icons/imdb.png b/icons/imdb.png
deleted file mode 100644
index 9cd497a..0000000
Binary files a/icons/imdb.png and /dev/null differ
diff --git a/icons/linkedin.png b/icons/linkedin.png
deleted file mode 100644
index ad1981f..0000000
Binary files a/icons/linkedin.png and /dev/null differ
diff --git a/icons/mail.png b/icons/mail.png
deleted file mode 100644
index 4e2c0d5..0000000
Binary files a/icons/mail.png and /dev/null differ
diff --git a/icons/netflix.png b/icons/netflix.png
deleted file mode 100644
index e3fd657..0000000
Binary files a/icons/netflix.png and /dev/null differ
diff --git a/icons/reddit.png b/icons/reddit.png
deleted file mode 100644
index 18462a3..0000000
Binary files a/icons/reddit.png and /dev/null differ
diff --git a/icons/stackoverflow.png b/icons/stackoverflow.png
deleted file mode 100644
index d416ee2..0000000
Binary files a/icons/stackoverflow.png and /dev/null differ
diff --git a/icons/twitch.png b/icons/twitch.png
deleted file mode 100644
index 55b4c8f..0000000
Binary files a/icons/twitch.png and /dev/null differ
diff --git a/icons/twitter.png b/icons/twitter.png
deleted file mode 100644
index 49b33d6..0000000
Binary files a/icons/twitter.png and /dev/null differ
diff --git a/icons/youtube.png b/icons/youtube.png
deleted file mode 100644
index c731edc..0000000
Binary files a/icons/youtube.png and /dev/null differ
diff --git a/index.html b/index.html
index 7de082f..90e0b22 100644
--- a/index.html
+++ b/index.html
@@ -1,1258 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
Home
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+ Home
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/script/script.js b/script/script.js
new file mode 100644
index 0000000..3e563ee
--- /dev/null
+++ b/script/script.js
@@ -0,0 +1,968 @@
+let invertColorCookie;
+
+if (localStorage.getItem('invertColorCookie') === null){
+ invertColorCookie = false;
+}
+
+else {
+ invertColorCookie = JSON.parse(localStorage.getItem('invertColorCookie'));
+}
+
+const CONFIG = {
+ /**
+ * The category, name, key, url, search path, color, icon, and quicklaunch properties for your commands.
+ * Icons must be added to "icons" folder and their values/names must be updated.
+ * If none of the specified keys are matched, the '*' key is used.
+ * Commands without a category don't show up in the help menu.
+ * Update line 11 and 13 if you prefer using Google.
+ */
+ commands: [
+ {
+ name: 'Duckduckgo',
+ key: '*',
+ url: 'https://duckduckgo.com',
+ search: '/?q={}',
+ color: '#DE5833',
+ },
+ {
+ category: 'General',
+ name: 'Mail',
+ key: 'm',
+ url: 'https://gmail.com',
+ search: '/#search/text={}',
+ color: 'linear-gradient(135deg, #dd5145, #dd5145)',
+ icon: 'mail',
+ quickLaunch: true,
+ },
+ {
+ category: 'General',
+ name: 'Drive',
+ key: 'd',
+ url: 'https://drive.google.com',
+ search: '/drive/search?q={}',
+ color: 'linear-gradient(135deg, #FFD04B, #1EA362, #4688F3)',
+ icon: 'drive',
+ quickLaunch: false,
+ },
+ {
+ category: 'General',
+ name: 'LinkedIn',
+ key: 'l',
+ url: 'https://linkedin.com',
+ search: '/search/results/all/?keywords={}',
+ color: 'linear-gradient(135deg, #006CA4, #0077B5)',
+ icon: 'linkedin',
+ quickLaunch: true,
+ },
+ {
+ category: 'Tech',
+ name: 'GitHub',
+ key: 'g',
+ url: 'https://github.com',
+ search: '/search?q={}',
+ color: 'linear-gradient(135deg, #2b2b2b, #3b3b3b)',
+ icon: 'github',
+ quickLaunch: true,
+ },
+ {
+ category: 'Tech',
+ name: 'StackOverflow',
+ key: 's',
+ url: 'https://stackoverflow.com',
+ search: '/search?q={}',
+ color: 'linear-gradient(135deg, #53341C, #F48024)',
+ icon: 'stackoverflow',
+ quickLaunch: true,
+ },
+ {
+ category: 'Tech',
+ name: 'Ars Technica',
+ key: 'a',
+ url: 'https://arstechnica.com',
+ search: '/search/?ie=UTF-8&q={}',
+ color: 'linear-gradient(135deg, #FF4E00, #B83800)',
+ icon: 'arstechnica',
+ quickLaunch: false,
+ },
+ {
+ category: 'Fun',
+ name: 'YouTube',
+ key: 'y',
+ url: 'https://youtube.com',
+ search: '/results?search_query={}',
+ color: 'linear-gradient(135deg, #cd201f, #cd4c1f)',
+ icon: 'youtube',
+ quickLaunch: false,
+ },
+ {
+ category: 'Fun',
+ name: 'Netflix',
+ key: 'n',
+ url: 'https://www.netflix.com',
+ color: 'linear-gradient(135deg, #E50914, #CB020C)',
+ icon: 'netflix',
+ quickLaunch: false,
+ },
+ {
+ category: 'Fun',
+ name: 'Twitch',
+ key: 't',
+ url: 'https://www.twitch.tv',
+ search: '/directory/game/{}',
+ color: 'linear-gradient(135deg, #6441a5, #4b367c)',
+ icon: 'twitch',
+ quickLaunch: false,
+ },
+ {
+ category: 'Other',
+ name: 'Reddit',
+ key: 'r',
+ url: 'https://reddit.com',
+ search: '/search?q={}',
+ color: 'linear-gradient(135deg, #FF8456, #FF4500)',
+ icon: 'reddit',
+ quickLaunch: false,
+ },
+ {
+ category: 'Other',
+ name: 'Twitter',
+ key: 'o',
+ url: 'https://twitter.com',
+ color: 'linear-gradient(135deg, #C0A886, #E2DBC8)',
+ icon: 'twitter',
+ quickLaunch: true,
+ },
+ {
+ category: 'Other',
+ name: 'IMDb',
+ key: 'i',
+ url: 'https://imdb.com',
+ search: '/find?ref_=nv_sr_fn&q={}',
+ color: 'linear-gradient(135deg, #7A5F00, #E8B708)',
+ icon: 'imdb',
+ quickLaunch: false,
+ },
+ ],
+
+ /**
+ * Get suggestions as you type.
+ */
+ suggestions: true,
+ suggestionsLimit: 4,
+
+ /**
+ * The order and limit for each suggestion influencer. An "influencer" is
+ * just a suggestion source. The following influencers are available:
+ *
+ * - "Default" suggestions come from CONFIG.defaultSuggestions
+ * - "DuckDuckGo" suggestions come from the duck duck go search api
+ * - "History" suggestions come from your previously entered queries
+ */
+ influencers: [
+ { name: 'Default', limit: 4 },
+ { name: 'History', limit: 1 },
+ { name: 'DuckDuckGo', limit: 4 },
+ ],
+
+ /**
+ * Default search suggestions for the specified queries.
+ */
+ defaultSuggestions: {
+ g: ['g/issues', 'g/pulls', 'gist.github.com'],
+ r: ['r/r/unixporn', 'r/r/startpages', 'r/r/webdev', 'r/r/technology'],
+ },
+
+ /**
+ * Instantly redirect when a key is matched. Put a space before any other
+ * queries to prevent unwanted redirects.
+ */
+ instantRedirect: false,
+
+ /**
+ * Open triggered queries in a new tab.
+ */
+ newTab: false,
+
+ /**
+ * Dynamic overlay background colors when command domains are matched.
+ */
+ colors: true,
+
+ /**
+ * Invert color theme
+ */
+ invertedColors: invertColorCookie,
+
+ /**
+ * The delimiter between a command key and your search query. For example,
+ * to search GitHub for potatoes, you'd type "g:potatoes".
+ */
+ searchDelimiter: ':',
+
+ /**
+ * The delimiter between a command key and a path. For example, you'd type
+ * "r/r/unixporn" to go to "https://reddit.com/r/unixporn".
+ */
+ pathDelimiter: '/',
+
+ /**
+ * The delimiter between the hours and minutes on the clock.
+ */
+ clockDelimiter: ' ',
+
+ /**
+ * Show a twenty-four-hour clock instead of a twelve-hour clock with AM/PM.
+ */
+ twentyFourHourClock: true,
+};
+
+
+const $ = {
+ bodyClassAdd: c => $.el('body').classList.add(c),
+ bodyClassRemove: c => $.el('body').classList.remove(c),
+ el: s => document.querySelector(s),
+ els: s => [].slice.call(document.querySelectorAll(s) || []),
+ escapeRegex: s => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),
+ flattenAndUnique: arr => [...new Set([].concat.apply([], arr))],
+ ieq: (a, b) => a.toLowerCase() === b.toLowerCase(),
+ iin: (a, b) => a.toLowerCase().indexOf(b.toLowerCase()) !== -1,
+ isDown: e => ['c-n', 'down', 'tab'].includes($.key(e)),
+ isRemove: e => ['backspace', 'delete'].includes($.key(e)),
+ isUp: e => ['c-p', 'up', 's-tab'].includes($.key(e)),
+
+ jsonp: url => {
+ let script = document.createElement('script');
+ script.src = url;
+ $.el('head').appendChild(script);
+ },
+
+ key: e => {
+ const ctrl = e.ctrlKey;
+ const shift = e.shiftKey;
+
+ switch (e.which) {
+ case 8:
+ return 'backspace';
+ case 9:
+ return shift ? 's-tab' : 'tab';
+ case 13:
+ return 'enter';
+ case 16:
+ return 'shift';
+ case 17:
+ return 'ctrl';
+ case 18:
+ return 'alt';
+ case 27:
+ return 'escape';
+ case 38:
+ return 'up';
+ case 40:
+ return 'down';
+ case 46:
+ return 'delete';
+ case 78:
+ return ctrl ? 'c-n' : 'n';
+ case 80:
+ return ctrl ? 'c-p' : 'p';
+ case 189:
+ return 'dash';
+ case 91:
+ case 93:
+ case 224:
+ return 'super';
+ }
+ },
+
+ pad: v => ('0' + v.toString()).slice(-2),
+};
+
+class Clock {
+ constructor(options) {
+ this._el = $.el('#clock');
+ this._delimiter = options.delimiter;
+ this._twentyFourHourClock = options.twentyFourHourClock;
+ this._setTime = this._setTime.bind(this);
+ this._el.addEventListener('click', options.toggleHelp);
+ this._start();
+ }
+
+ _setTime() {
+ const date = new Date();
+ let hours = $.pad(date.getHours());
+ let amPm = '';
+
+ if (!this._twentyFourHourClock) {
+ hours = date.getHours();
+ if (hours > 12) hours -= 12;
+ else if (hours === 0) hours = 12;
+
+ amPm =
+ ` ` +
+ `${date.getHours() >= 12 ? 'PM' : 'AM'}`;
+ }
+
+ const minutes = $.pad(date.getMinutes());
+ this._el.innerHTML = `${hours}${this._delimiter}${minutes}${amPm}`;
+ this._el.setAttribute('datetime', date.toTimeString());
+ }
+
+ _start() {
+ this._setTime();
+ setInterval(this._setTime, 1000);
+ }
+}
+
+class Help {
+ constructor(options) {
+ this._el = $.el('#help');
+ this._commands = options.commands;
+ this._newTab = options.newTab;
+ this._toggled = false;
+ this._handleKeydown = this._handleKeydown.bind(this);
+ this.toggle = this.toggle.bind(this);
+ this.launch = this.launch.bind(this);
+ this._inputEl = $.el('#search-input');
+ this._inputElVal = '';
+ this._suggester = options.suggester;
+ this._invertColors = options.invertedColors;
+ this._buildAndAppendLists();
+ this._registerEvents();
+ this._invertValue;
+ }
+
+ toggle(show) {
+ this._toggled = typeof show !== 'undefined' ? show : !this._toggled;
+ this._toggled ? $.bodyClassAdd('help') : $.bodyClassRemove('help');
+ }
+
+ hide() {
+ $.bodyClassRemove('form');
+ this._inputEl.value = '';
+ this._inputElVal = '';
+ this._suggester.suggest('');
+ }
+
+ launch() {
+ this.hide();
+ this.toggle(true);
+ $.bodyClassAdd('help');
+ for (let i = 0; i < CONFIG.commands.length; i++) {
+ if (CONFIG.commands[i].quickLaunch === true) {
+ window.open(CONFIG.commands[i].url);
+ }
+ }
+ }
+
+ _buildAndAppendLists() {
+ const lists = document.createElement('ul');
+ lists.classList.add('categories');
+
+ this._getCategories().forEach(category => {
+ lists.insertAdjacentHTML(
+ 'beforeend',
+ `