+++ /dev/null
-var tick = "✔";
-var addText = "+";
-var rmText = "−";
-var removebg = "#bf616a";
-var hovergrn = "#a3be8c";
-var hoverbg = "#434c5e";
-var hoverbg2 = "#848ead";
-var editMode = false;
-var dragSrcEl = null;
-var thumbServer = "https://www.google.com/s2/favicons?domain=";
-var defaultColumns= [
- ["General",
- ["Github", "https://github.com"],
- ["Wikipedia", "https://en.wikipedia.org"],
- ["Gmail", "https://mail.google.com"]
- ],
- ["Productivity",
- ["Desmos", "https://www.desmos.com/calculator"],
- ["Wolfram", "https://wolframalpha.com"],
- ["Hacker News", "https://news.ycombinator.com"]
- ],
- ["Social",
- ["Reddit", "https://www.reddit.com"],
- ["YouTube", "https://youtube.com"],
- ["Instagram", "https://instagram.com"]
- ]
-]
-
-
-// --------------------------------
-//
-// Initialisation
-//
-// --------------------------------
-
-
-document.addEventListener("DOMContentLoaded", loadLists);
-
-function loadLists() {
-
- // Retrieve lists from storage and trigger callback to generate HTML
-
- console.log("Getting lists from storage");
- chrome.storage.sync.get({"lists": defaultColumns}, parseColumns);
-
- document.getElementById('edit').addEventListener('click', edit, false);
- document.getElementById('addcol').addEventListener('click', addColumn, false);
-
- // Set colours from preferences
-
- var bgCallback = function(colourPref) { document.body.style.background = colourPref["bgvalue"]; };
- var fgCallback = function(colourPref) { document.body.style.color = colourPref["fgvalue"]; };
- var hrCallback = function(colourPref) {
- document.documentElement.style.setProperty('--hover-bg', colourPref["hrvalue"]);
- hoverbg = colourPref["hrvalue"];
- };
-
- chrome.storage.sync.get({"bgvalue": "#2e3440"}, bgCallback);
- chrome.storage.sync.get({"fgvalue": "#d8dee9"}, fgCallback);
- chrome.storage.sync.get({"hrvalue": "#434c5e"}, hrCallback);
-
-}
-
-
-function parseColumns(config) {
-
- var columns = config["lists"]
-
- // Generate elements for each column
- for (let col of columns) {
-
- var ul = genColumn(col[0]);
- document.getElementById("links").appendChild(ul);
-
- // Iterate through links
- for(let item of col.slice(1)) {
- li = genItem(ul, item[0], item[1]);
- ul.appendChild(li);
- }
-
- var sortableProperties = { group: "usercolumns", animation: 150, onSort: function (evt) {saveConfig();} };
- new Sortable(ul, sortableProperties);
-
- }
-}
-
-
-function genColumn(title) {
-
- // Generate HTML elements for a column (without items)
-
- var ul = document.createElement("ul");
- ul.setAttribute("id", title);
- ul.setAttribute('draggable', 'false');
-
- var grip = document.createElement("span");
- grip.setAttribute("class", "grip");
- grip.addEventListener('mousedown', enableDrag);
- grip.addEventListener('mouseup', disableDrag);
- ul.appendChild(grip)
-
- var titleDiv = document.createElement("div");
- titleDiv.setAttribute("class", "title");
-
- var titleText = document.createElement("p");
- titleText.innerText = title;
- titleDiv.appendChild(titleText);
-
- var addBtn = document.createElement("span");
- addBtn.innerText = addText;
- addBtn.setAttribute("class", "add");
- addBtn.setAttribute("id", "add-" + title);
- addBtn.addEventListener("click", addItem);
- titleDiv.appendChild(addBtn);
-
- ul.appendChild(titleDiv);
-
- return ul;
-
-}
-
-
-function genItem(ul, nme, url) {
-
- // Generate HTML elements for an item
-
- var li = document.createElement("li");
- li.setAttribute("class", ul.id + "-" + (ul.getElementsByTagName("li").length + 1).toString() );
- li.addEventListener("mouseup", saveConfig);
-
- var img = requestThumbnail(url);
-
- var link = document.createElement("a");
- link.className = "item";
- link.href = url;
-
- var rmBtn = document.createElement("span");
- rmBtn.className = "remove";
- rmBtn.id = "delete-" + li.id;
- rmBtn.innerText = "-";
- rmBtn.addEventListener("click", removeItem);
-
- link.appendChild(img);
- link.insertAdjacentHTML("beforeend", nme);
- li.appendChild(link);
- li.appendChild(rmBtn);
-
- return li;
-
-}
-
-
-function requestThumbnail(imageUrl) {
- // Get thumbnail from Google's favicon server
- var img = document.createElement("img");
- var xhr = new XMLHttpRequest();
- xhr.open('GET', thumbServer + imageUrl);
- xhr.responseType = "blob";
- xhr.onload = function() {
- img.setAttribute("data-src", thumbServer + imageUrl);
- img.className = "icon";
- var objUrl = URL.createObjectURL(xhr.response);
- img.setAttribute("src", objUrl);
- }.bind(this);
- xhr.send();
- return img;
-}
-
-
-// --------------------------------
-//
-// Edit mode
-//
-// --------------------------------
-
-
-function edit(event) {
-
- // Enter/exit edit mode
-
- if (editMode == true) {
- console.log("Exited edit mode");
- closeEdit(this);
- return false;
- }
-
- console.log("Entered edit mode");
-
- this.style.background = hovergrn;
- this.innerText = tick;
- addBtn= document.getElementById("addcol");
- addBtn.style.display = "flex";
- var cols = document.getElementsByTagName("ul");
-
- for (let col of cols) {
-
- var titleDiv = col.getElementsByClassName("title")[0];
- titleDiv.getElementsByClassName("add")[0].style.display = "flex";
-
- col.style.bottom = "26px";
- col.getElementsByClassName("grip")[0].style.display = "inline-block";
-
- var rmColBtn = document.createElement("span");
- rmColBtn.className = "rmcol";
- rmColBtn.id = "rmcol-" + col.id;
- rmColBtn.innerText = rmText;
- titleDiv.appendChild(rmColBtn);
-
- var titleStatic = titleDiv.getElementsByTagName("p")[0];
- var titleInput = document.createElement("input");
- titleInput.type = "text";
- titleInput.className = "colname";
- titleInput.placeholder = titleStatic.innerText;
- titleInput.value = titleStatic.innerText;
- titleDiv.insertBefore(titleInput, titleStatic);
- titleStatic.remove();
-
- }
-
- updateListeners();
- editMode = true;
-}
-
-function closeEdit(editBtn) {
-
- // Exit edit mode and clean up elements
-
- editMode = false;
- editBtn.style.background = "";
- editBtn.innerText = "e";
-
- var addBtn = document.getElementById("addcol");
- addBtn.style.display = "none";
-
- var cols = document.getElementsByTagName("ul");
-
- for (let col of cols) {
-
- col.style.bottom = "0";
- col.getElementsByClassName("grip")[0].style.display = "none";
-
- var rmColBtn = col.getElementsByClassName("title")[0].getElementsByClassName("rmcol")[0];
- rmColBtn.remove();
-
- var titleDiv = col.getElementsByClassName("title")[0];
- titleDiv.getElementsByClassName("add")[0].style.display = "";
-
- titleInput = titleDiv.getElementsByClassName("colname")[0];
- titleStatic = document.createElement("p");
- titleStatic.innerText = titleInput.value;
- if (titleStatic.innerText == "") {
- titleStatic.innerText = titleInput.placeholder;
- }
- titleInput.remove();
- titleDiv.appendChild(titleStatic);
-
- }
-
- saveConfig();
-
-}
-
-function addColumn(event) {
-
- // Create a new column from Edit mode
-
- var ul = document.createElement("ul");
-
- // Make sure columns do not share an id
- var ex = document.querySelectorAll('[id^="new "]'); // existing "new" columns
- if (ex.length > 0) {
- indices = []
- for (let i of ex) {
- indices.push(Number(i.id.split(" ")[1]));
- }
- ul.setAttribute("id", "new " + (Math.max.apply(Math, indices)+1).toString());
- }
- else {
- ul.setAttribute("id", "new 1");
- }
- ul.setAttribute('draggable', 'false');
-
- var grip = document.createElement("span");
- grip.setAttribute("class", "grip");
- grip.addEventListener("mousedown", enableDrag);
- grip.addEventListener("mouseup", disableDrag);
- grip.style.display = "inline-block";
- ul.style.bottom = "26px";
- ul.appendChild(grip)
-
- var titleDiv = document.createElement("div");
- titleDiv.setAttribute("class", "title");
-
- var titleInput = document.createElement("input");
- titleInput.type = "text";
- titleInput.className = "colname";
- titleInput.placeholder = ul.id;
- titleDiv.appendChild(titleInput);
-
- var addBtn = document.createElement("span");
- addBtn.style.display = "flex";
- addBtn.innerText = addText;
- addBtn.setAttribute("class", "add");
- addBtn.setAttribute("id", "add-" + ul.id);
- addBtn.addEventListener("click", addItem);
- titleDiv.appendChild(addBtn);
-
- var rmColBtn = document.createElement("span");
- rmColBtn.className = "rmcol";
- rmColBtn.id = "rmcol-" + ul.id;
- rmColBtn.innerText = rmText;
- titleDiv.appendChild(rmColBtn);
-
- ul.appendChild(titleDiv);
-
- document.getElementById("links").appendChild(ul);
- saveConfig();
- updateListeners();
- titleInput.focus();
-
-}
-
-
-function removeColumn(event) {
-
- // Delete column in edit mode
-
- this.parentNode.parentNode.remove();
- saveConfig();
-
-}
-
-
-function removeItem(event) {
-
- // Remove link in edit or normal mode
-
- this.parentNode.outerHTML = "";
- delete this.parentNode;
- saveConfig();
-
-}
-
-
-function addItem(event) {
-
- // Interface for adding a new list item to an existing category
-
- var ul = this.parentNode.parentNode;
- var id = ul.id;
-
- // Check if a form has already been generated for this column
- existing = ul.getElementsByClassName("new");
- if (existing.length > 0) {
- existing[0].getElementsByClassName("name")[0].focus();
- return false;
- }
-
- var li = document.createElement("li");
- li.setAttribute("class", "new");
- li.addEventListener("keyup", formKeys);
-
- var saveBtn = document.createElement("span");
- saveBtn.className = "save";
- saveBtn.tabIndex = "3";
- saveBtn.id = "save-" + ul.id;
- saveBtn.innerText = tick;
- saveBtn.addEventListener("click", saveItem);
- saveBtn.addEventListener("mouseover", saveMouseOver);
- saveBtn.addEventListener("mouseout", saveMouseOut);
- li.appendChild(saveBtn);
-
- var nameInput = document.createElement("input");
- nameInput.type = "text";
- nameInput.className = "name";
- nameInput.placeholder = "name";
- nameInput.tabIndex = "1";
- li.appendChild(nameInput);
-
- var urlInput = document.createElement("input");
- urlInput.type = "url";
- urlInput.className = "url";
- urlInput.placeholder = "url";
- urlInput.tabIndex = "2";
- urlInput.spellcheck = "false";
- li.appendChild(urlInput);
-
- ul.appendChild(li);
- updateListeners();
- nameInput.focus();
-
-}
-
-
-function saveItem(event) {
-
- // Add new item to a column after pressing the save button in form
-
- var li = this.parentNode;
- var ul = this.parentNode.parentNode;
- var nameField = li.getElementsByClassName("name")[0];
- var urlField = li.getElementsByClassName("url")[0];
-
- if (nameField.value != "" && urlField.value != "" && urlField.validity.typeMismatch== false) {
-
- var newli = genItem(ul, nameField.value, urlField.value);
- li.remove();
- delete li;
-
- ul.appendChild(newli);
- saveConfig();
-
- }
- else {
-
- if (nameField.value == "" && urlField.value == "") {
- console.log("No data supplied, deleting form");
- li.remove();
- }
- else {
- console.log("Missing data, press Esc to delete form");
- }
-
- }
-
-}
-
-
-// --------------------------------
-//
-// UI event listeners
-//
-// --------------------------------
-
-
-function updateListeners() {
-
- // Update event listeners for interface elements, since listeners are tied DOM objects which are lost on dataTransfer operations
-
- var addBtns = document.getElementsByClassName("add");
- for (let addBtn of addBtns) {
- addBtn.addEventListener("click", addItem);
- }
-
- var rmBtns = document.getElementsByClassName("rm");
- for (let rmBtn of rmBtns) {
- rmBtn.addEventListener("click", removeItem);
- }
-
- var rmColBtns = document.getElementsByClassName("rmcol");
- for (let rmColBtn of rmColBtns) {
- rmColBtn.addEventListener("click", removeColumn);
- }
-
- var saveBtns = document.getElementsByClassName("save");
- for (let saveBtn of saveBtns) {
- saveBtn.addEventListener("click", saveItem);
- saveBtn.addEventListener("mouseover", saveMouseOver);
- saveBtn.addEventListener("mouseout", saveMouseOut);
- }
-
-}
-
-
-function saveMouseOver(event) {
- nameField = this.parentNode.getElementsByClassName("name")[0];
- urlField = this.parentNode.getElementsByClassName("url")[0];
- if (nameField.value === '' || urlField.value === '' || urlField.validity.typeMismatch == true) {
- this.style.background = removebg;
- }
- else {
- this.style.background = hovergrn;
- }
-}
-
-
-function saveMouseOut(event) {
- this.style.background = hoverbg2;
-}
-
-
-function enableDrag() {
- // Enable drag & drop when grip is grabbed (otherwise any mouse click triggers dragStart)
- console.log("Drag started");
- uls = document.getElementsByTagName("ul");
- for (let ul of uls) {
- ul.setAttribute("draggable", "true");
- ul.addEventListener('dragstart', dragStart, false);
- ul.addEventListener('dragover', dragOver, false);
- ul.addEventListener('drop', drop, false);
- }
-}
-
-
-function disableDrag() {
- // Disable drag after grip has been released
- console.log("Drag ended");
- uls = document.getElementsByTagName("ul");
- for (let ul of uls) {
- ul.setAttribute("draggable", "false");
- ul.removeEventListener('dragstart');
- ul.removeEventListener('dragover');
- ul.removeEventListener('drop');
- }
-}
-
-
-function dragStart(e) {
- dragSrcEl = this;
- e.dataTransfer.effectAllowed = 'move';
- e.dataTransfer.setData('text/html', this.innerHTML);
-}
-
-
-function dragOver(e) {
- if (e.preventDefault) {
- e.preventDefault();
- }
- e.dataTransfer.dropEffect = 'move';
- return false;
-}
-
-
-function drop(e) {
- if (e.stopPropagation); {
- e.stopPropagation();
- }
- if (dragSrcEl != this) {
- var srcTitleInput = dragSrcEl.getElementsByClassName("colname")[0].value;
- var destTitleInput = this.getElementsByClassName("colname")[0].value;
- dragSrcEl.innerHTML = this.innerHTML;
- dragSrcEl.getElementsByClassName("colname")[0].value = destTitleInput;
- this.innerHTML = e.dataTransfer.getData('text/html');
- this.getElementsByClassName("colname")[0].value = srcTitleInput;
- saveConfig();
- updateListeners();
- }
- return false;
-}
-
-
-function formKeys(e) {
- var focus = document.activeElement;
- if (focus.parentNode.className != "new") {
- return false;
- }
- switch (e.which) {
- case 27: // escape
- focus.parentNode.remove();
- break;
- case 13: // enter
- focus.parentNode.getElementsByClassName("save")[0].click();
- break;
- }
-}
-
-
-// --------------------------------
-//
-// Configuration management
-//
-// --------------------------------
-
-
-function saveConfig() {
-
- // Save current DOM structure as JSON data
-
- console.log("Saving settings");
- data = []
- for (let ul of document.getElementsByTagName("ul")) {
- data.push(columnToArray(ul, true));
- }
- chrome.storage.sync.set( {"lists": data} );
-
-}
-
-
-function columnToArray(ul, title = false) {
-
- // Convert a column of data (ul) to a 2D array, optionally including the title
-
- var data = [];
- var items = ul.getElementsByClassName("item");
-
- if (title == true && editMode == true) {
- data[0] = ul.getElementsByClassName("title")[0].getElementsByTagName("input")[0].value;
- if (data[0] == "" || data[0] == null) {
- console.log("Using default category name since input was empty");
- data[0] = ul.getElementsByClassName("title")[0].getElementsByTagName("input")[0].placeholder;
- }
- }
- else if (title == true) {
- data[0] = ul.getElementsByClassName('title')[0].getElementsByTagName("p")[0].textContent;
- }
-
- for (let li of items) {
- if (li.class == "new" || li.class == "title") {
- continue; // Ignore input forms and titles (already handled)
- }
- else {
- data.push([li.innerText, li.getAttribute("href")]);
- }
- }
-
- return data;
-
-}
+++ /dev/null
-{
- "chrome_url_overrides": {
- "newtab": "newtab.html"
- },
- "content_security_policy": "script-src 'self'; object-src 'self'",
- "manifest_version": 2,
- "name": "newtab",
- "description": "A simple new tab page with customisable links",
- "options_ui": {
- "chrome_style": true,
- "page": "options.html"
- },
- "permissions": [ "storage" ],
- "version": "2"
-}
+++ /dev/null
-<!DOCTYPE html>
-<html>
-
- <head>
-
- <title>New Tab</title>
- <meta charset="utf-8">
- <meta name=viewport content="width=device-width, initial-scale=1">
-
- <script type="text/javascript" src="main.js" ></script>
- <script type="text/javascript" src="sortable.min.js"></script>
-
- <link rel="stylesheet" href="style.css">
-
- </head>
-
- <body>
-
- <span id="edit">e</span>
- <span id="addcol">+</span>
-
- <div id="links"></div>
-
- </body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html>
-<html>
-
- <head>
-
- <title>newtab</title>
- <script src="options.js"></script>
- <style>
- body {
- padding-left: 65px;
- padding-right: 65px;
- }
-
- button {
- float: right;
- width: 65px;
- }
-
- table {
- text-align: right;
- }
- </style>
-
- </head>
-
- <body>
-
- <table>
- <tr>
- <td>Background</td><td><input type="text" id="bg"></td>
- </tr>
- <tr>
- <td>Foreground</td><td><input type="text" id="fg"></td>
- </tr>
- <tr>
- <td>Hover</td><td><input type="text" id="hr"></td>
- </tr>
- </table>
-
- <button id="save">Save</button>
-
- <p>Made by<br /><a href="https://git.lorimer.id.au/newtab.git">Andrew Lorimer</a></p>
-
- </body>
-
-</html>
+++ /dev/null
-function save_options() {
- var bgvalue = document.getElementById('bg').value;
- var fgvalue = document.getElementById('fg').value;
- var hrvalue = document.getElementById('hr').value;
- console.log(bgvalue);
-
- chrome.storage.sync.set({
- "bgvalue": bgvalue,
- "fgvalue": fgvalue,
- "hrvalue": hrvalue,
- }, function() {
- window.close();
-
- });
-}
-
-
-function restore_options() {
- chrome.storage.sync.get({
- "bgvalue": "#2e3440",
- "fgvalue": "#d8dee9",
- "hrvalue": "#434c5e"
- },
- function(items) {
- document.getElementById('bg').value = items["bgvalue"];
- document.getElementById('fg').value = items["fgvalue"];
- document.getElementById('hr').value = items["hrvalue"];
- });
- document.getElementById('save').addEventListener('click', save_options);
-}
-
-document.addEventListener('DOMContentLoaded', restore_options);
+++ /dev/null
-/*! Sortable 1.4.2 - MIT | git://github.com/rubaxa/Sortable.git */
-!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():"undefined"!=typeof Package?Sortable=a():window.Sortable=a()}(function(){"use strict";function a(a,b){if(!a||!a.nodeType||1!==a.nodeType)throw"Sortable: `el` must be HTMLElement, and not "+{}.toString.call(a);this.el=a,this.options=b=r({},b),a[L]=this;var c={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",ignore:"a, img",filter:null,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1};for(var d in c)!(d in b)&&(b[d]=c[d]);V(b);for(var f in this)"_"===f.charAt(0)&&(this[f]=this[f].bind(this));this.nativeDraggable=b.forceFallback?!1:P,e(a,"mousedown",this._onTapStart),e(a,"touchstart",this._onTapStart),this.nativeDraggable&&(e(a,"dragover",this),e(a,"dragenter",this)),T.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a){v&&v.state!==a&&(h(v,"display",a?"none":""),!a&&v.state&&w.insertBefore(v,s),v.state=a)}function c(a,b,c){if(a){c=c||N,b=b.split(".");var d=b.shift().toUpperCase(),e=new RegExp("\\s("+b.join("|")+")(?=\\s)","g");do if(">*"===d&&a.parentNode===c||(""===d||a.nodeName.toUpperCase()==d)&&(!b.length||((" "+a.className+" ").match(e)||[]).length==b.length))return a;while(a!==c&&(a=a.parentNode))}return null}function d(a){a.dataTransfer&&(a.dataTransfer.dropEffect="move"),a.preventDefault()}function e(a,b,c){a.addEventListener(b,c,!1)}function f(a,b,c){a.removeEventListener(b,c,!1)}function g(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(K," ").replace(" "+b+" "," ");a.className=(d+(c?" "+b:"")).replace(K," ")}}function h(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return N.defaultView&&N.defaultView.getComputedStyle?c=N.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function i(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;f>e;e++)c(d[e],e);return d}return[]}function j(a,b,c,d,e,f,g){var h=N.createEvent("Event"),i=(a||b[L]).options,j="on"+c.charAt(0).toUpperCase()+c.substr(1);h.initEvent(c,!0,!0),h.to=b,h.from=e||b,h.item=d||b,h.clone=v,h.oldIndex=f,h.newIndex=g,b.dispatchEvent(h),i[j]&&i[j].call(a,h)}function k(a,b,c,d,e,f){var g,h,i=a[L],j=i.options.onMove;return g=N.createEvent("Event"),g.initEvent("move",!0,!0),g.to=b,g.from=a,g.dragged=c,g.draggedRect=d,g.related=e||b,g.relatedRect=f||b.getBoundingClientRect(),a.dispatchEvent(g),j&&(h=j.call(i,g)),h}function l(a){a.draggable=!1}function m(){R=!1}function n(a,b){var c=a.lastElementChild,d=c.getBoundingClientRect();return(b.clientY-(d.top+d.height)>5||b.clientX-(d.right+d.width)>5)&&c}function o(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function p(a){var b=0;if(!a||!a.parentNode)return-1;for(;a&&(a=a.previousElementSibling);)"TEMPLATE"!==a.nodeName.toUpperCase()&&b++;return b}function q(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}function r(a,b){if(a&&b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}var s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J={},K=/\s+/g,L="Sortable"+(new Date).getTime(),M=window,N=M.document,O=M.parseInt,P=!!("draggable"in N.createElement("div")),Q=function(a){return a=N.createElement("x"),a.style.cssText="pointer-events:auto","auto"===a.style.pointerEvents}(),R=!1,S=Math.abs,T=([].slice,[]),U=q(function(a,b,c){if(c&&b.scroll){var d,e,f,g,h=b.scrollSensitivity,i=b.scrollSpeed,j=a.clientX,k=a.clientY,l=window.innerWidth,m=window.innerHeight;if(z!==c&&(y=b.scroll,z=c,y===!0)){y=c;do if(y.offsetWidth<y.scrollWidth||y.offsetHeight<y.scrollHeight)break;while(y=y.parentNode)}y&&(d=y,e=y.getBoundingClientRect(),f=(S(e.right-j)<=h)-(S(e.left-j)<=h),g=(S(e.bottom-k)<=h)-(S(e.top-k)<=h)),f||g||(f=(h>=l-j)-(h>=j),g=(h>=m-k)-(h>=k),(f||g)&&(d=M)),(J.vx!==f||J.vy!==g||J.el!==d)&&(J.el=d,J.vx=f,J.vy=g,clearInterval(J.pid),d&&(J.pid=setInterval(function(){d===M?M.scrollTo(M.pageXOffset+f*i,M.pageYOffset+g*i):(g&&(d.scrollTop+=g*i),f&&(d.scrollLeft+=f*i))},24)))}},30),V=function(a){var b=a.group;b&&"object"==typeof b||(b=a.group={name:b}),["pull","put"].forEach(function(a){a in b||(b[a]=!0)}),a.groups=" "+b.name+(b.put.join?" "+b.put.join(" "):"")+" "};return a.prototype={constructor:a,_onTapStart:function(a){var b=this,d=this.el,e=this.options,f=a.type,g=a.touches&&a.touches[0],h=(g||a).target,i=h,k=e.filter;if(!("mousedown"===f&&0!==a.button||e.disabled)&&(h=c(h,e.draggable,d))){if(D=p(h),"function"==typeof k){if(k.call(this,a,h,this))return j(b,i,"filter",h,d,D),void a.preventDefault()}else if(k&&(k=k.split(",").some(function(a){return a=c(i,a.trim(),d),a?(j(b,a,"filter",h,d,D),!0):void 0})))return void a.preventDefault();(!e.handle||c(i,e.handle,d))&&this._prepareDragStart(a,g,h)}},_prepareDragStart:function(a,b,c){var d,f=this,h=f.el,j=f.options,k=h.ownerDocument;c&&!s&&c.parentNode===h&&(G=a,w=h,s=c,t=s.parentNode,x=s.nextSibling,F=j.group,d=function(){f._disableDelayedDrag(),s.draggable=!0,g(s,f.options.chosenClass,!0),f._triggerDragStart(b)},j.ignore.split(",").forEach(function(a){i(s,a.trim(),l)}),e(k,"mouseup",f._onDrop),e(k,"touchend",f._onDrop),e(k,"touchcancel",f._onDrop),j.delay?(e(k,"mouseup",f._disableDelayedDrag),e(k,"touchend",f._disableDelayedDrag),e(k,"touchcancel",f._disableDelayedDrag),e(k,"mousemove",f._disableDelayedDrag),e(k,"touchmove",f._disableDelayedDrag),f._dragStartTimer=setTimeout(d,j.delay)):d())},_disableDelayedDrag:function(){var a=this.el.ownerDocument;clearTimeout(this._dragStartTimer),f(a,"mouseup",this._disableDelayedDrag),f(a,"touchend",this._disableDelayedDrag),f(a,"touchcancel",this._disableDelayedDrag),f(a,"mousemove",this._disableDelayedDrag),f(a,"touchmove",this._disableDelayedDrag)},_triggerDragStart:function(a){a?(G={target:s,clientX:a.clientX,clientY:a.clientY},this._onDragStart(G,"touch")):this.nativeDraggable?(e(s,"dragend",this),e(w,"dragstart",this._onDragStart)):this._onDragStart(G,!0);try{N.selection?N.selection.empty():window.getSelection().removeAllRanges()}catch(b){}},_dragStarted:function(){w&&s&&(g(s,this.options.ghostClass,!0),a.active=this,j(this,w,"start",s,w,D))},_emulateDragOver:function(){if(H){if(this._lastX===H.clientX&&this._lastY===H.clientY)return;this._lastX=H.clientX,this._lastY=H.clientY,Q||h(u,"display","none");var a=N.elementFromPoint(H.clientX,H.clientY),b=a,c=" "+this.options.group.name,d=T.length;if(b)do{if(b[L]&&b[L].options.groups.indexOf(c)>-1){for(;d--;)T[d]({clientX:H.clientX,clientY:H.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);Q||h(u,"display","")}},_onTouchMove:function(b){if(G){a.active||this._dragStarted(),this._appendGhost();var c=b.touches?b.touches[0]:b,d=c.clientX-G.clientX,e=c.clientY-G.clientY,f=b.touches?"translate3d("+d+"px,"+e+"px,0)":"translate("+d+"px,"+e+"px)";I=!0,H=c,h(u,"webkitTransform",f),h(u,"mozTransform",f),h(u,"msTransform",f),h(u,"transform",f),b.preventDefault()}},_appendGhost:function(){if(!u){var a,b=s.getBoundingClientRect(),c=h(s),d=this.options;u=s.cloneNode(!0),g(u,d.ghostClass,!1),g(u,d.fallbackClass,!0),h(u,"top",b.top-O(c.marginTop,10)),h(u,"left",b.left-O(c.marginLeft,10)),h(u,"width",b.width),h(u,"height",b.height),h(u,"opacity","0.8"),h(u,"position","fixed"),h(u,"zIndex","100000"),h(u,"pointerEvents","none"),d.fallbackOnBody&&N.body.appendChild(u)||w.appendChild(u),a=u.getBoundingClientRect(),h(u,"width",2*b.width-a.width),h(u,"height",2*b.height-a.height)}},_onDragStart:function(a,b){var c=a.dataTransfer,d=this.options;this._offUpEvents(),"clone"==F.pull&&(v=s.cloneNode(!0),h(v,"display","none"),w.insertBefore(v,s)),b?("touch"===b?(e(N,"touchmove",this._onTouchMove),e(N,"touchend",this._onDrop),e(N,"touchcancel",this._onDrop)):(e(N,"mousemove",this._onTouchMove),e(N,"mouseup",this._onDrop)),this._loopId=setInterval(this._emulateDragOver,50)):(c&&(c.effectAllowed="move",d.setData&&d.setData.call(this,c,s)),e(N,"drop",this),setTimeout(this._dragStarted,0))},_onDragOver:function(a){var d,e,f,g=this.el,i=this.options,j=i.group,l=j.put,o=F===j,p=i.sort;if(void 0!==a.preventDefault&&(a.preventDefault(),!i.dragoverBubble&&a.stopPropagation()),I=!0,F&&!i.disabled&&(o?p||(f=!w.contains(s)):F.pull&&l&&(F.name===j.name||l.indexOf&&~l.indexOf(F.name)))&&(void 0===a.rootEl||a.rootEl===this.el)){if(U(a,i,this.el),R)return;if(d=c(a.target,i.draggable,g),e=s.getBoundingClientRect(),f)return b(!0),void(v||x?w.insertBefore(s,v||x):p||w.appendChild(s));if(0===g.children.length||g.children[0]===u||g===a.target&&(d=n(g,a))){if(d){if(d.animated)return;r=d.getBoundingClientRect()}b(o),k(w,g,s,e,d,r)!==!1&&(s.contains(g)||(g.appendChild(s),t=g),this._animate(e,s),d&&this._animate(r,d))}else if(d&&!d.animated&&d!==s&&void 0!==d.parentNode[L]){A!==d&&(A=d,B=h(d),C=h(d.parentNode));var q,r=d.getBoundingClientRect(),y=r.right-r.left,z=r.bottom-r.top,D=/left|right|inline/.test(B.cssFloat+B.display)||"flex"==C.display&&0===C["flex-direction"].indexOf("row"),E=d.offsetWidth>s.offsetWidth,G=d.offsetHeight>s.offsetHeight,H=(D?(a.clientX-r.left)/y:(a.clientY-r.top)/z)>.5,J=d.nextElementSibling,K=k(w,g,s,e,d,r);if(K!==!1){if(R=!0,setTimeout(m,30),b(o),1===K||-1===K)q=1===K;else if(D){var M=s.offsetTop,N=d.offsetTop;q=M===N?d.previousElementSibling===s&&!E||H&&E:N>M}else q=J!==s&&!G||H&&G;s.contains(g)||(q&&!J?g.appendChild(s):d.parentNode.insertBefore(s,q?J:d)),t=s.parentNode,this._animate(e,s),this._animate(r,d)}}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();h(b,"transition","none"),h(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,h(b,"transition","all "+c+"ms"),h(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){h(b,"transition",""),h(b,"transform",""),b.animated=!1},c)}},_offUpEvents:function(){var a=this.el.ownerDocument;f(N,"touchmove",this._onTouchMove),f(a,"mouseup",this._onDrop),f(a,"touchend",this._onDrop),f(a,"touchcancel",this._onDrop)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(J.pid),clearTimeout(this._dragStartTimer),f(N,"mousemove",this._onTouchMove),this.nativeDraggable&&(f(N,"drop",this),f(c,"dragstart",this._onDragStart)),this._offUpEvents(),b&&(I&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation()),u&&u.parentNode.removeChild(u),s&&(this.nativeDraggable&&f(s,"dragend",this),l(s),g(s,this.options.ghostClass,!1),g(s,this.options.chosenClass,!1),w!==t?(E=p(s),E>=0&&(j(null,t,"sort",s,w,D,E),j(this,w,"sort",s,w,D,E),j(null,t,"add",s,w,D,E),j(this,w,"remove",s,w,D,E))):(v&&v.parentNode.removeChild(v),s.nextSibling!==x&&(E=p(s),E>=0&&(j(this,w,"update",s,w,D,E),j(this,w,"sort",s,w,D,E)))),a.active&&((null===E||-1===E)&&(E=D),j(this,w,"end",s,w,D,E),this.save())),w=s=t=u=x=v=y=z=G=H=I=E=A=B=F=a.active=null)},handleEvent:function(a){var b=a.type;"dragover"===b||"dragenter"===b?s&&(this._onDragOver(a),d(a)):("drop"===b||"dragend"===b)&&this._onDrop(a)},toArray:function(){for(var a,b=[],d=this.el.children,e=0,f=d.length,g=this.options;f>e;e++)a=d[e],c(a,g.draggable,this.el)&&b.push(a.getAttribute(g.dataIdAttr)||o(a));return b},sort:function(a){var b={},d=this.el;this.toArray().forEach(function(a,e){var f=d.children[e];c(f,this.options.draggable,d)&&(b[a]=f)},this),a.forEach(function(a){b[a]&&(d.removeChild(b[a]),d.appendChild(b[a]))})},save:function(){var a=this.options.store;a&&a.set(this)},closest:function(a,b){return c(a,b||this.options.draggable,this.el)},option:function(a,b){var c=this.options;return void 0===b?c[a]:(c[a]=b,void("group"===a&&V(c)))},destroy:function(){var a=this.el;a[L]=null,f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),this.nativeDraggable&&(f(a,"dragover",this),f(a,"dragenter",this)),Array.prototype.forEach.call(a.querySelectorAll("[draggable]"),function(a){a.removeAttribute("draggable")}),T.splice(T.indexOf(this._onDragOver),1),this._onDrop(),this.el=a=null}},a.utils={on:e,off:f,css:h,find:i,is:function(a,b){return!!c(a,b,a)},extend:r,throttle:q,closest:c,toggleClass:g,index:p},a.create=function(b,c){return new a(b,c)},a.version="1.4.2",a});
\ No newline at end of file
--- /dev/null
+var tick = "✔";
+var addText = "+";
+var rmText = "−";
+var removebg = "#bf616a";
+var hovergrn = "#a3be8c";
+var hoverbg = "#434c5e";
+var hoverbg2 = "#848ead";
+var editMode = false;
+var dragSrcEl = null;
+var thumbServer = "https://www.google.com/s2/favicons?domain=";
+var defaultColumns= [
+ ["General",
+ ["Github", "https://github.com"],
+ ["Wikipedia", "https://en.wikipedia.org"],
+ ["Gmail", "https://mail.google.com"]
+ ],
+ ["Productivity",
+ ["Desmos", "https://www.desmos.com/calculator"],
+ ["Wolfram", "https://wolframalpha.com"],
+ ["Hacker News", "https://news.ycombinator.com"]
+ ],
+ ["Social",
+ ["Reddit", "https://www.reddit.com"],
+ ["YouTube", "https://youtube.com"],
+ ["Instagram", "https://instagram.com"]
+ ]
+]
+
+
+// --------------------------------
+//
+// Initialisation
+//
+// --------------------------------
+
+
+document.addEventListener("DOMContentLoaded", loadLists);
+
+function loadLists() {
+
+ // Retrieve lists from storage and trigger callback to generate HTML
+
+ console.log("Getting lists from storage");
+ chrome.storage.sync.get({"lists": defaultColumns}, parseColumns);
+
+ document.getElementById('edit').addEventListener('click', edit, false);
+ document.getElementById('addcol').addEventListener('click', addColumn, false);
+
+ // Set colours from preferences
+
+ var bgCallback = function(colourPref) { document.body.style.background = colourPref["bgvalue"]; };
+ var fgCallback = function(colourPref) { document.body.style.color = colourPref["fgvalue"]; };
+ var hrCallback = function(colourPref) {
+ document.documentElement.style.setProperty('--hover-bg', colourPref["hrvalue"]);
+ hoverbg = colourPref["hrvalue"];
+ };
+
+ chrome.storage.sync.get({"bgvalue": "#2e3440"}, bgCallback);
+ chrome.storage.sync.get({"fgvalue": "#d8dee9"}, fgCallback);
+ chrome.storage.sync.get({"hrvalue": "#434c5e"}, hrCallback);
+
+}
+
+
+function parseColumns(config) {
+
+ var columns = config["lists"]
+
+ // Generate elements for each column
+ for (let col of columns) {
+
+ var ul = genColumn(col[0]);
+ document.getElementById("links").appendChild(ul);
+
+ // Iterate through links
+ for(let item of col.slice(1)) {
+ li = genItem(ul, item[0], item[1]);
+ ul.appendChild(li);
+ }
+
+ var sortableProperties = { group: "usercolumns", animation: 150, onSort: function (evt) {saveConfig();} };
+ new Sortable(ul, sortableProperties);
+
+ }
+}
+
+
+function genColumn(title) {
+
+ // Generate HTML elements for a column (without items)
+
+ var ul = document.createElement("ul");
+ ul.setAttribute("id", title);
+ ul.setAttribute('draggable', 'false');
+
+ var grip = document.createElement("span");
+ grip.setAttribute("class", "grip");
+ grip.addEventListener('mousedown', enableDrag);
+ grip.addEventListener('mouseup', disableDrag);
+ ul.appendChild(grip)
+
+ var titleDiv = document.createElement("div");
+ titleDiv.setAttribute("class", "title");
+
+ var titleText = document.createElement("p");
+ titleText.innerText = title;
+ titleDiv.appendChild(titleText);
+
+ var addBtn = document.createElement("span");
+ addBtn.innerText = addText;
+ addBtn.setAttribute("class", "add");
+ addBtn.setAttribute("id", "add-" + title);
+ addBtn.addEventListener("click", addItem);
+ titleDiv.appendChild(addBtn);
+
+ ul.appendChild(titleDiv);
+
+ return ul;
+
+}
+
+
+function genItem(ul, nme, url) {
+
+ // Generate HTML elements for an item
+
+ var li = document.createElement("li");
+ li.setAttribute("class", ul.id + "-" + (ul.getElementsByTagName("li").length + 1).toString() );
+ li.addEventListener("mouseup", saveConfig);
+
+ var img = requestThumbnail(url);
+
+ var link = document.createElement("a");
+ link.className = "item";
+ link.href = url;
+
+ var rmBtn = document.createElement("span");
+ rmBtn.className = "remove";
+ rmBtn.id = "delete-" + li.id;
+ rmBtn.innerText = "-";
+ rmBtn.addEventListener("click", removeItem);
+
+ link.appendChild(img);
+ link.insertAdjacentHTML("beforeend", nme);
+ li.appendChild(link);
+ li.appendChild(rmBtn);
+
+ return li;
+
+}
+
+
+function requestThumbnail(imageUrl) {
+ // Get thumbnail from Google's favicon server
+ var img = document.createElement("img");
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', thumbServer + imageUrl);
+ xhr.responseType = "blob";
+ xhr.onload = function() {
+ img.setAttribute("data-src", thumbServer + imageUrl);
+ img.className = "icon";
+ var objUrl = URL.createObjectURL(xhr.response);
+ img.setAttribute("src", objUrl);
+ }.bind(this);
+ xhr.send();
+ return img;
+}
+
+
+// --------------------------------
+//
+// Edit mode
+//
+// --------------------------------
+
+
+function edit(event) {
+
+ // Enter/exit edit mode
+
+ if (editMode == true) {
+ console.log("Exited edit mode");
+ closeEdit(this);
+ return false;
+ }
+
+ console.log("Entered edit mode");
+
+ this.style.background = hovergrn;
+ this.innerText = tick;
+ addBtn= document.getElementById("addcol");
+ addBtn.style.display = "flex";
+ var cols = document.getElementsByTagName("ul");
+
+ for (let col of cols) {
+
+ var titleDiv = col.getElementsByClassName("title")[0];
+ titleDiv.getElementsByClassName("add")[0].style.display = "flex";
+
+ col.style.bottom = "26px";
+ col.getElementsByClassName("grip")[0].style.display = "inline-block";
+
+ var rmColBtn = document.createElement("span");
+ rmColBtn.className = "rmcol";
+ rmColBtn.id = "rmcol-" + col.id;
+ rmColBtn.innerText = rmText;
+ titleDiv.appendChild(rmColBtn);
+
+ var titleStatic = titleDiv.getElementsByTagName("p")[0];
+ var titleInput = document.createElement("input");
+ titleInput.type = "text";
+ titleInput.className = "colname";
+ titleInput.placeholder = titleStatic.innerText;
+ titleInput.value = titleStatic.innerText;
+ titleDiv.insertBefore(titleInput, titleStatic);
+ titleStatic.remove();
+
+ }
+
+ updateListeners();
+ editMode = true;
+}
+
+function closeEdit(editBtn) {
+
+ // Exit edit mode and clean up elements
+
+ editMode = false;
+ editBtn.style.background = "";
+ editBtn.innerText = "e";
+
+ var addBtn = document.getElementById("addcol");
+ addBtn.style.display = "none";
+
+ var cols = document.getElementsByTagName("ul");
+
+ for (let col of cols) {
+
+ col.style.bottom = "0";
+ col.getElementsByClassName("grip")[0].style.display = "none";
+
+ var rmColBtn = col.getElementsByClassName("title")[0].getElementsByClassName("rmcol")[0];
+ rmColBtn.remove();
+
+ var titleDiv = col.getElementsByClassName("title")[0];
+ titleDiv.getElementsByClassName("add")[0].style.display = "";
+
+ titleInput = titleDiv.getElementsByClassName("colname")[0];
+ titleStatic = document.createElement("p");
+ titleStatic.innerText = titleInput.value;
+ if (titleStatic.innerText == "") {
+ titleStatic.innerText = titleInput.placeholder;
+ }
+ titleInput.remove();
+ titleDiv.appendChild(titleStatic);
+
+ }
+
+ saveConfig();
+
+}
+
+function addColumn(event) {
+
+ // Create a new column from Edit mode
+
+ var ul = document.createElement("ul");
+
+ // Make sure columns do not share an id
+ var ex = document.querySelectorAll('[id^="new "]'); // existing "new" columns
+ if (ex.length > 0) {
+ indices = []
+ for (let i of ex) {
+ indices.push(Number(i.id.split(" ")[1]));
+ }
+ ul.setAttribute("id", "new " + (Math.max.apply(Math, indices)+1).toString());
+ }
+ else {
+ ul.setAttribute("id", "new 1");
+ }
+ ul.setAttribute('draggable', 'false');
+
+ var grip = document.createElement("span");
+ grip.setAttribute("class", "grip");
+ grip.addEventListener("mousedown", enableDrag);
+ grip.addEventListener("mouseup", disableDrag);
+ grip.style.display = "inline-block";
+ ul.style.bottom = "26px";
+ ul.appendChild(grip)
+
+ var titleDiv = document.createElement("div");
+ titleDiv.setAttribute("class", "title");
+
+ var titleInput = document.createElement("input");
+ titleInput.type = "text";
+ titleInput.className = "colname";
+ titleInput.placeholder = ul.id;
+ titleDiv.appendChild(titleInput);
+
+ var addBtn = document.createElement("span");
+ addBtn.style.display = "flex";
+ addBtn.innerText = addText;
+ addBtn.setAttribute("class", "add");
+ addBtn.setAttribute("id", "add-" + ul.id);
+ addBtn.addEventListener("click", addItem);
+ titleDiv.appendChild(addBtn);
+
+ var rmColBtn = document.createElement("span");
+ rmColBtn.className = "rmcol";
+ rmColBtn.id = "rmcol-" + ul.id;
+ rmColBtn.innerText = rmText;
+ titleDiv.appendChild(rmColBtn);
+
+ ul.appendChild(titleDiv);
+
+ document.getElementById("links").appendChild(ul);
+ saveConfig();
+ updateListeners();
+ titleInput.focus();
+
+}
+
+
+function removeColumn(event) {
+
+ // Delete column in edit mode
+
+ this.parentNode.parentNode.remove();
+ saveConfig();
+
+}
+
+
+function removeItem(event) {
+
+ // Remove link in edit or normal mode
+
+ this.parentNode.outerHTML = "";
+ delete this.parentNode;
+ saveConfig();
+
+}
+
+
+function addItem(event) {
+
+ // Interface for adding a new list item to an existing category
+
+ var ul = this.parentNode.parentNode;
+ var id = ul.id;
+
+ // Check if a form has already been generated for this column
+ existing = ul.getElementsByClassName("new");
+ if (existing.length > 0) {
+ existing[0].getElementsByClassName("name")[0].focus();
+ return false;
+ }
+
+ var li = document.createElement("li");
+ li.setAttribute("class", "new");
+ li.addEventListener("keyup", formKeys);
+
+ var saveBtn = document.createElement("span");
+ saveBtn.className = "save";
+ saveBtn.tabIndex = "3";
+ saveBtn.id = "save-" + ul.id;
+ saveBtn.innerText = tick;
+ saveBtn.addEventListener("click", saveItem);
+ saveBtn.addEventListener("mouseover", saveMouseOver);
+ saveBtn.addEventListener("mouseout", saveMouseOut);
+ li.appendChild(saveBtn);
+
+ var nameInput = document.createElement("input");
+ nameInput.type = "text";
+ nameInput.className = "name";
+ nameInput.placeholder = "name";
+ nameInput.tabIndex = "1";
+ li.appendChild(nameInput);
+
+ var urlInput = document.createElement("input");
+ urlInput.type = "url";
+ urlInput.className = "url";
+ urlInput.placeholder = "url";
+ urlInput.tabIndex = "2";
+ urlInput.spellcheck = "false";
+ li.appendChild(urlInput);
+
+ ul.appendChild(li);
+ updateListeners();
+ nameInput.focus();
+
+}
+
+
+function saveItem(event) {
+
+ // Add new item to a column after pressing the save button in form
+
+ var li = this.parentNode;
+ var ul = this.parentNode.parentNode;
+ var nameField = li.getElementsByClassName("name")[0];
+ var urlField = li.getElementsByClassName("url")[0];
+
+ if (nameField.value != "" && urlField.value != "" && urlField.validity.typeMismatch== false) {
+
+ var newli = genItem(ul, nameField.value, urlField.value);
+ li.remove();
+ delete li;
+
+ ul.appendChild(newli);
+ saveConfig();
+
+ }
+ else {
+
+ if (nameField.value == "" && urlField.value == "") {
+ console.log("No data supplied, deleting form");
+ li.remove();
+ }
+ else {
+ console.log("Missing data, press Esc to delete form");
+ }
+
+ }
+
+}
+
+
+// --------------------------------
+//
+// UI event listeners
+//
+// --------------------------------
+
+
+function updateListeners() {
+
+ // Update event listeners for interface elements, since listeners are tied DOM objects which are lost on dataTransfer operations
+
+ var addBtns = document.getElementsByClassName("add");
+ for (let addBtn of addBtns) {
+ addBtn.addEventListener("click", addItem);
+ }
+
+ var rmBtns = document.getElementsByClassName("rm");
+ for (let rmBtn of rmBtns) {
+ rmBtn.addEventListener("click", removeItem);
+ }
+
+ var rmColBtns = document.getElementsByClassName("rmcol");
+ for (let rmColBtn of rmColBtns) {
+ rmColBtn.addEventListener("click", removeColumn);
+ }
+
+ var saveBtns = document.getElementsByClassName("save");
+ for (let saveBtn of saveBtns) {
+ saveBtn.addEventListener("click", saveItem);
+ saveBtn.addEventListener("mouseover", saveMouseOver);
+ saveBtn.addEventListener("mouseout", saveMouseOut);
+ }
+
+}
+
+
+function saveMouseOver(event) {
+ nameField = this.parentNode.getElementsByClassName("name")[0];
+ urlField = this.parentNode.getElementsByClassName("url")[0];
+ if (nameField.value === '' || urlField.value === '' || urlField.validity.typeMismatch == true) {
+ this.style.background = removebg;
+ }
+ else {
+ this.style.background = hovergrn;
+ }
+}
+
+
+function saveMouseOut(event) {
+ this.style.background = hoverbg2;
+}
+
+
+function enableDrag() {
+ // Enable drag & drop when grip is grabbed (otherwise any mouse click triggers dragStart)
+ console.log("Drag started");
+ uls = document.getElementsByTagName("ul");
+ for (let ul of uls) {
+ ul.setAttribute("draggable", "true");
+ ul.addEventListener('dragstart', dragStart, false);
+ ul.addEventListener('dragover', dragOver, false);
+ ul.addEventListener('drop', drop, false);
+ }
+}
+
+
+function disableDrag() {
+ // Disable drag after grip has been released
+ console.log("Drag ended");
+ uls = document.getElementsByTagName("ul");
+ for (let ul of uls) {
+ ul.setAttribute("draggable", "false");
+ ul.removeEventListener('dragstart');
+ ul.removeEventListener('dragover');
+ ul.removeEventListener('drop');
+ }
+}
+
+
+function dragStart(e) {
+ dragSrcEl = this;
+ e.dataTransfer.effectAllowed = 'move';
+ e.dataTransfer.setData('text/html', this.innerHTML);
+}
+
+
+function dragOver(e) {
+ if (e.preventDefault) {
+ e.preventDefault();
+ }
+ e.dataTransfer.dropEffect = 'move';
+ return false;
+}
+
+
+function drop(e) {
+ if (e.stopPropagation); {
+ e.stopPropagation();
+ }
+ if (dragSrcEl != this) {
+ var srcTitleInput = dragSrcEl.getElementsByClassName("colname")[0].value;
+ var destTitleInput = this.getElementsByClassName("colname")[0].value;
+ dragSrcEl.innerHTML = this.innerHTML;
+ dragSrcEl.getElementsByClassName("colname")[0].value = destTitleInput;
+ this.innerHTML = e.dataTransfer.getData('text/html');
+ this.getElementsByClassName("colname")[0].value = srcTitleInput;
+ saveConfig();
+ updateListeners();
+ }
+ return false;
+}
+
+
+function formKeys(e) {
+ var focus = document.activeElement;
+ if (focus.parentNode.className != "new") {
+ return false;
+ }
+ switch (e.which) {
+ case 27: // escape
+ focus.parentNode.remove();
+ break;
+ case 13: // enter
+ focus.parentNode.getElementsByClassName("save")[0].click();
+ break;
+ }
+}
+
+
+// --------------------------------
+//
+// Configuration management
+//
+// --------------------------------
+
+
+function saveConfig() {
+
+ // Save current DOM structure as JSON data
+
+ console.log("Saving settings");
+ data = []
+ for (let ul of document.getElementsByTagName("ul")) {
+ data.push(columnToArray(ul, true));
+ }
+ chrome.storage.sync.set( {"lists": data} );
+
+}
+
+
+function columnToArray(ul, title = false) {
+
+ // Convert a column of data (ul) to a 2D array, optionally including the title
+
+ var data = [];
+ var items = ul.getElementsByClassName("item");
+
+ if (title == true && editMode == true) {
+ data[0] = ul.getElementsByClassName("title")[0].getElementsByTagName("input")[0].value;
+ if (data[0] == "" || data[0] == null) {
+ console.log("Using default category name since input was empty");
+ data[0] = ul.getElementsByClassName("title")[0].getElementsByTagName("input")[0].placeholder;
+ }
+ }
+ else if (title == true) {
+ data[0] = ul.getElementsByClassName('title')[0].getElementsByTagName("p")[0].textContent;
+ }
+
+ for (let li of items) {
+ if (li.class == "new" || li.class == "title") {
+ continue; // Ignore input forms and titles (already handled)
+ }
+ else {
+ data.push([li.innerText, li.getAttribute("href")]);
+ }
+ }
+
+ return data;
+
+}
--- /dev/null
+{
+ "chrome_url_overrides": {
+ "newtab": "newtab.html"
+ },
+ "content_security_policy": "script-src 'self'; object-src 'self'",
+ "manifest_version": 2,
+ "name": "newtab",
+ "description": "A simple new tab page with customisable links",
+ "options_ui": {
+ "chrome_style": true,
+ "page": "options.html"
+ },
+ "permissions": [ "storage" ],
+ "version": "2"
+}
--- /dev/null
+<!DOCTYPE html>
+<html>
+
+ <head>
+
+ <title>New Tab</title>
+ <meta charset="utf-8">
+ <meta name=viewport content="width=device-width, initial-scale=1">
+
+ <script type="text/javascript" src="main.js" ></script>
+ <script type="text/javascript" src="sortable.min.js"></script>
+
+ <link rel="stylesheet" href="style.css">
+
+ </head>
+
+ <body>
+
+ <span id="edit">e</span>
+ <span id="addcol">+</span>
+
+ <div id="links"></div>
+
+ </body>
+
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+
+ <head>
+
+ <title>newtab</title>
+ <script src="options.js"></script>
+ <style>
+ body {
+ padding-left: 65px;
+ padding-right: 65px;
+ }
+
+ button {
+ float: right;
+ width: 65px;
+ }
+
+ table {
+ text-align: right;
+ }
+ </style>
+
+ </head>
+
+ <body>
+
+ <table>
+ <tr>
+ <td>Background</td><td><input type="text" id="bg"></td>
+ </tr>
+ <tr>
+ <td>Foreground</td><td><input type="text" id="fg"></td>
+ </tr>
+ <tr>
+ <td>Hover</td><td><input type="text" id="hr"></td>
+ </tr>
+ </table>
+
+ <button id="save">Save</button>
+
+ <p>Made by<br /><a href="https://git.lorimer.id.au/newtab.git">Andrew Lorimer</a></p>
+
+ </body>
+
+</html>
--- /dev/null
+function save_options() {
+ var bgvalue = document.getElementById('bg').value;
+ var fgvalue = document.getElementById('fg').value;
+ var hrvalue = document.getElementById('hr').value;
+ console.log(bgvalue);
+
+ chrome.storage.sync.set({
+ "bgvalue": bgvalue,
+ "fgvalue": fgvalue,
+ "hrvalue": hrvalue,
+ }, function() {
+ window.close();
+
+ });
+}
+
+
+function restore_options() {
+ chrome.storage.sync.get({
+ "bgvalue": "#2e3440",
+ "fgvalue": "#d8dee9",
+ "hrvalue": "#434c5e"
+ },
+ function(items) {
+ document.getElementById('bg').value = items["bgvalue"];
+ document.getElementById('fg').value = items["fgvalue"];
+ document.getElementById('hr').value = items["hrvalue"];
+ });
+ document.getElementById('save').addEventListener('click', save_options);
+}
+
+document.addEventListener('DOMContentLoaded', restore_options);
--- /dev/null
+/*! Sortable 1.4.2 - MIT | git://github.com/rubaxa/Sortable.git */
+!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():"undefined"!=typeof Package?Sortable=a():window.Sortable=a()}(function(){"use strict";function a(a,b){if(!a||!a.nodeType||1!==a.nodeType)throw"Sortable: `el` must be HTMLElement, and not "+{}.toString.call(a);this.el=a,this.options=b=r({},b),a[L]=this;var c={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",ignore:"a, img",filter:null,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1};for(var d in c)!(d in b)&&(b[d]=c[d]);V(b);for(var f in this)"_"===f.charAt(0)&&(this[f]=this[f].bind(this));this.nativeDraggable=b.forceFallback?!1:P,e(a,"mousedown",this._onTapStart),e(a,"touchstart",this._onTapStart),this.nativeDraggable&&(e(a,"dragover",this),e(a,"dragenter",this)),T.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a){v&&v.state!==a&&(h(v,"display",a?"none":""),!a&&v.state&&w.insertBefore(v,s),v.state=a)}function c(a,b,c){if(a){c=c||N,b=b.split(".");var d=b.shift().toUpperCase(),e=new RegExp("\\s("+b.join("|")+")(?=\\s)","g");do if(">*"===d&&a.parentNode===c||(""===d||a.nodeName.toUpperCase()==d)&&(!b.length||((" "+a.className+" ").match(e)||[]).length==b.length))return a;while(a!==c&&(a=a.parentNode))}return null}function d(a){a.dataTransfer&&(a.dataTransfer.dropEffect="move"),a.preventDefault()}function e(a,b,c){a.addEventListener(b,c,!1)}function f(a,b,c){a.removeEventListener(b,c,!1)}function g(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(K," ").replace(" "+b+" "," ");a.className=(d+(c?" "+b:"")).replace(K," ")}}function h(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return N.defaultView&&N.defaultView.getComputedStyle?c=N.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function i(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;f>e;e++)c(d[e],e);return d}return[]}function j(a,b,c,d,e,f,g){var h=N.createEvent("Event"),i=(a||b[L]).options,j="on"+c.charAt(0).toUpperCase()+c.substr(1);h.initEvent(c,!0,!0),h.to=b,h.from=e||b,h.item=d||b,h.clone=v,h.oldIndex=f,h.newIndex=g,b.dispatchEvent(h),i[j]&&i[j].call(a,h)}function k(a,b,c,d,e,f){var g,h,i=a[L],j=i.options.onMove;return g=N.createEvent("Event"),g.initEvent("move",!0,!0),g.to=b,g.from=a,g.dragged=c,g.draggedRect=d,g.related=e||b,g.relatedRect=f||b.getBoundingClientRect(),a.dispatchEvent(g),j&&(h=j.call(i,g)),h}function l(a){a.draggable=!1}function m(){R=!1}function n(a,b){var c=a.lastElementChild,d=c.getBoundingClientRect();return(b.clientY-(d.top+d.height)>5||b.clientX-(d.right+d.width)>5)&&c}function o(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function p(a){var b=0;if(!a||!a.parentNode)return-1;for(;a&&(a=a.previousElementSibling);)"TEMPLATE"!==a.nodeName.toUpperCase()&&b++;return b}function q(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}function r(a,b){if(a&&b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}var s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J={},K=/\s+/g,L="Sortable"+(new Date).getTime(),M=window,N=M.document,O=M.parseInt,P=!!("draggable"in N.createElement("div")),Q=function(a){return a=N.createElement("x"),a.style.cssText="pointer-events:auto","auto"===a.style.pointerEvents}(),R=!1,S=Math.abs,T=([].slice,[]),U=q(function(a,b,c){if(c&&b.scroll){var d,e,f,g,h=b.scrollSensitivity,i=b.scrollSpeed,j=a.clientX,k=a.clientY,l=window.innerWidth,m=window.innerHeight;if(z!==c&&(y=b.scroll,z=c,y===!0)){y=c;do if(y.offsetWidth<y.scrollWidth||y.offsetHeight<y.scrollHeight)break;while(y=y.parentNode)}y&&(d=y,e=y.getBoundingClientRect(),f=(S(e.right-j)<=h)-(S(e.left-j)<=h),g=(S(e.bottom-k)<=h)-(S(e.top-k)<=h)),f||g||(f=(h>=l-j)-(h>=j),g=(h>=m-k)-(h>=k),(f||g)&&(d=M)),(J.vx!==f||J.vy!==g||J.el!==d)&&(J.el=d,J.vx=f,J.vy=g,clearInterval(J.pid),d&&(J.pid=setInterval(function(){d===M?M.scrollTo(M.pageXOffset+f*i,M.pageYOffset+g*i):(g&&(d.scrollTop+=g*i),f&&(d.scrollLeft+=f*i))},24)))}},30),V=function(a){var b=a.group;b&&"object"==typeof b||(b=a.group={name:b}),["pull","put"].forEach(function(a){a in b||(b[a]=!0)}),a.groups=" "+b.name+(b.put.join?" "+b.put.join(" "):"")+" "};return a.prototype={constructor:a,_onTapStart:function(a){var b=this,d=this.el,e=this.options,f=a.type,g=a.touches&&a.touches[0],h=(g||a).target,i=h,k=e.filter;if(!("mousedown"===f&&0!==a.button||e.disabled)&&(h=c(h,e.draggable,d))){if(D=p(h),"function"==typeof k){if(k.call(this,a,h,this))return j(b,i,"filter",h,d,D),void a.preventDefault()}else if(k&&(k=k.split(",").some(function(a){return a=c(i,a.trim(),d),a?(j(b,a,"filter",h,d,D),!0):void 0})))return void a.preventDefault();(!e.handle||c(i,e.handle,d))&&this._prepareDragStart(a,g,h)}},_prepareDragStart:function(a,b,c){var d,f=this,h=f.el,j=f.options,k=h.ownerDocument;c&&!s&&c.parentNode===h&&(G=a,w=h,s=c,t=s.parentNode,x=s.nextSibling,F=j.group,d=function(){f._disableDelayedDrag(),s.draggable=!0,g(s,f.options.chosenClass,!0),f._triggerDragStart(b)},j.ignore.split(",").forEach(function(a){i(s,a.trim(),l)}),e(k,"mouseup",f._onDrop),e(k,"touchend",f._onDrop),e(k,"touchcancel",f._onDrop),j.delay?(e(k,"mouseup",f._disableDelayedDrag),e(k,"touchend",f._disableDelayedDrag),e(k,"touchcancel",f._disableDelayedDrag),e(k,"mousemove",f._disableDelayedDrag),e(k,"touchmove",f._disableDelayedDrag),f._dragStartTimer=setTimeout(d,j.delay)):d())},_disableDelayedDrag:function(){var a=this.el.ownerDocument;clearTimeout(this._dragStartTimer),f(a,"mouseup",this._disableDelayedDrag),f(a,"touchend",this._disableDelayedDrag),f(a,"touchcancel",this._disableDelayedDrag),f(a,"mousemove",this._disableDelayedDrag),f(a,"touchmove",this._disableDelayedDrag)},_triggerDragStart:function(a){a?(G={target:s,clientX:a.clientX,clientY:a.clientY},this._onDragStart(G,"touch")):this.nativeDraggable?(e(s,"dragend",this),e(w,"dragstart",this._onDragStart)):this._onDragStart(G,!0);try{N.selection?N.selection.empty():window.getSelection().removeAllRanges()}catch(b){}},_dragStarted:function(){w&&s&&(g(s,this.options.ghostClass,!0),a.active=this,j(this,w,"start",s,w,D))},_emulateDragOver:function(){if(H){if(this._lastX===H.clientX&&this._lastY===H.clientY)return;this._lastX=H.clientX,this._lastY=H.clientY,Q||h(u,"display","none");var a=N.elementFromPoint(H.clientX,H.clientY),b=a,c=" "+this.options.group.name,d=T.length;if(b)do{if(b[L]&&b[L].options.groups.indexOf(c)>-1){for(;d--;)T[d]({clientX:H.clientX,clientY:H.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);Q||h(u,"display","")}},_onTouchMove:function(b){if(G){a.active||this._dragStarted(),this._appendGhost();var c=b.touches?b.touches[0]:b,d=c.clientX-G.clientX,e=c.clientY-G.clientY,f=b.touches?"translate3d("+d+"px,"+e+"px,0)":"translate("+d+"px,"+e+"px)";I=!0,H=c,h(u,"webkitTransform",f),h(u,"mozTransform",f),h(u,"msTransform",f),h(u,"transform",f),b.preventDefault()}},_appendGhost:function(){if(!u){var a,b=s.getBoundingClientRect(),c=h(s),d=this.options;u=s.cloneNode(!0),g(u,d.ghostClass,!1),g(u,d.fallbackClass,!0),h(u,"top",b.top-O(c.marginTop,10)),h(u,"left",b.left-O(c.marginLeft,10)),h(u,"width",b.width),h(u,"height",b.height),h(u,"opacity","0.8"),h(u,"position","fixed"),h(u,"zIndex","100000"),h(u,"pointerEvents","none"),d.fallbackOnBody&&N.body.appendChild(u)||w.appendChild(u),a=u.getBoundingClientRect(),h(u,"width",2*b.width-a.width),h(u,"height",2*b.height-a.height)}},_onDragStart:function(a,b){var c=a.dataTransfer,d=this.options;this._offUpEvents(),"clone"==F.pull&&(v=s.cloneNode(!0),h(v,"display","none"),w.insertBefore(v,s)),b?("touch"===b?(e(N,"touchmove",this._onTouchMove),e(N,"touchend",this._onDrop),e(N,"touchcancel",this._onDrop)):(e(N,"mousemove",this._onTouchMove),e(N,"mouseup",this._onDrop)),this._loopId=setInterval(this._emulateDragOver,50)):(c&&(c.effectAllowed="move",d.setData&&d.setData.call(this,c,s)),e(N,"drop",this),setTimeout(this._dragStarted,0))},_onDragOver:function(a){var d,e,f,g=this.el,i=this.options,j=i.group,l=j.put,o=F===j,p=i.sort;if(void 0!==a.preventDefault&&(a.preventDefault(),!i.dragoverBubble&&a.stopPropagation()),I=!0,F&&!i.disabled&&(o?p||(f=!w.contains(s)):F.pull&&l&&(F.name===j.name||l.indexOf&&~l.indexOf(F.name)))&&(void 0===a.rootEl||a.rootEl===this.el)){if(U(a,i,this.el),R)return;if(d=c(a.target,i.draggable,g),e=s.getBoundingClientRect(),f)return b(!0),void(v||x?w.insertBefore(s,v||x):p||w.appendChild(s));if(0===g.children.length||g.children[0]===u||g===a.target&&(d=n(g,a))){if(d){if(d.animated)return;r=d.getBoundingClientRect()}b(o),k(w,g,s,e,d,r)!==!1&&(s.contains(g)||(g.appendChild(s),t=g),this._animate(e,s),d&&this._animate(r,d))}else if(d&&!d.animated&&d!==s&&void 0!==d.parentNode[L]){A!==d&&(A=d,B=h(d),C=h(d.parentNode));var q,r=d.getBoundingClientRect(),y=r.right-r.left,z=r.bottom-r.top,D=/left|right|inline/.test(B.cssFloat+B.display)||"flex"==C.display&&0===C["flex-direction"].indexOf("row"),E=d.offsetWidth>s.offsetWidth,G=d.offsetHeight>s.offsetHeight,H=(D?(a.clientX-r.left)/y:(a.clientY-r.top)/z)>.5,J=d.nextElementSibling,K=k(w,g,s,e,d,r);if(K!==!1){if(R=!0,setTimeout(m,30),b(o),1===K||-1===K)q=1===K;else if(D){var M=s.offsetTop,N=d.offsetTop;q=M===N?d.previousElementSibling===s&&!E||H&&E:N>M}else q=J!==s&&!G||H&&G;s.contains(g)||(q&&!J?g.appendChild(s):d.parentNode.insertBefore(s,q?J:d)),t=s.parentNode,this._animate(e,s),this._animate(r,d)}}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();h(b,"transition","none"),h(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,h(b,"transition","all "+c+"ms"),h(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){h(b,"transition",""),h(b,"transform",""),b.animated=!1},c)}},_offUpEvents:function(){var a=this.el.ownerDocument;f(N,"touchmove",this._onTouchMove),f(a,"mouseup",this._onDrop),f(a,"touchend",this._onDrop),f(a,"touchcancel",this._onDrop)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(J.pid),clearTimeout(this._dragStartTimer),f(N,"mousemove",this._onTouchMove),this.nativeDraggable&&(f(N,"drop",this),f(c,"dragstart",this._onDragStart)),this._offUpEvents(),b&&(I&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation()),u&&u.parentNode.removeChild(u),s&&(this.nativeDraggable&&f(s,"dragend",this),l(s),g(s,this.options.ghostClass,!1),g(s,this.options.chosenClass,!1),w!==t?(E=p(s),E>=0&&(j(null,t,"sort",s,w,D,E),j(this,w,"sort",s,w,D,E),j(null,t,"add",s,w,D,E),j(this,w,"remove",s,w,D,E))):(v&&v.parentNode.removeChild(v),s.nextSibling!==x&&(E=p(s),E>=0&&(j(this,w,"update",s,w,D,E),j(this,w,"sort",s,w,D,E)))),a.active&&((null===E||-1===E)&&(E=D),j(this,w,"end",s,w,D,E),this.save())),w=s=t=u=x=v=y=z=G=H=I=E=A=B=F=a.active=null)},handleEvent:function(a){var b=a.type;"dragover"===b||"dragenter"===b?s&&(this._onDragOver(a),d(a)):("drop"===b||"dragend"===b)&&this._onDrop(a)},toArray:function(){for(var a,b=[],d=this.el.children,e=0,f=d.length,g=this.options;f>e;e++)a=d[e],c(a,g.draggable,this.el)&&b.push(a.getAttribute(g.dataIdAttr)||o(a));return b},sort:function(a){var b={},d=this.el;this.toArray().forEach(function(a,e){var f=d.children[e];c(f,this.options.draggable,d)&&(b[a]=f)},this),a.forEach(function(a){b[a]&&(d.removeChild(b[a]),d.appendChild(b[a]))})},save:function(){var a=this.options.store;a&&a.set(this)},closest:function(a,b){return c(a,b||this.options.draggable,this.el)},option:function(a,b){var c=this.options;return void 0===b?c[a]:(c[a]=b,void("group"===a&&V(c)))},destroy:function(){var a=this.el;a[L]=null,f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),this.nativeDraggable&&(f(a,"dragover",this),f(a,"dragenter",this)),Array.prototype.forEach.call(a.querySelectorAll("[draggable]"),function(a){a.removeAttribute("draggable")}),T.splice(T.indexOf(this._onDragOver),1),this._onDrop(),this.el=a=null}},a.utils={on:e,off:f,css:h,find:i,is:function(a,b){return!!c(a,b,a)},extend:r,throttle:q,closest:c,toggleClass:g,index:p},a.create=function(b,c){return new a(b,c)},a.version="1.4.2",a});
\ No newline at end of file
--- /dev/null
+:root {
+ --hover-bg: #434c5e;
+ --hover-grn: #a3be8c;
+ --hover-bg-2: #848ead;
+ --remove-bg: #bf616a;
+ --default-fg: #d8dee9;
+ --default-bg: #2e3440;
+}
+
+html, body {
+ font-size: 16px !important;
+ width: 100%;
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ color: var(--default-fg);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+#links {
+ display: flex;
+ flex-direction: row;
+ display: -webkit-flex;
+ -webkit-flex-direction: row;
+ min-height: 283px;
+}
+
+ul {
+ position: relative;
+ list-style: none;
+ padding: 0;
+ width: 10rem;
+ margin: 0.5rem 2em 2em 2em;
+ float: left;
+}
+
+img {
+ float: left;
+ margin-top: 1px;
+ padding-right: 3px;
+}
+
+input {
+ font-size: 16px !important;
+ padding: 0;
+ height: 18.5px;
+ width: 112px;
+ margin: 5px;
+}
+
+input.name {
+ margin-bottom: 2.5px
+}
+
+input.url {
+ margin-top: 2.5px
+}
+
+input.colname {
+ width: calc(100% - 68px);
+ height: 19px;
+ margin: 14px 0 6px 0;
+ border: 2px var(--hover-bg) dashed;
+ background-color: var(inherit);
+ color: inherit;
+ font-family: inherit;
+}
+
+.remove {
+ width: 29px;
+ height: 35px;
+ padding: 0;
+ background-color: var(--hover-bg);
+ float: right;
+ text-align: center;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ font-family: monospace;
+ display: flex;
+}
+
+.save {
+ padding-left: 8px;
+ float: right;
+ height: 60px;
+ width: 21px;
+ display: flex;
+ text-align: center;
+ align-items: center;
+ cursor: pointer;
+ background-color: var(--hover-bg-2);
+}
+
+.save:hover, .save:focus, .save:focus-within {
+ background-color: var(--hover-grn);
+}
+
+.remove:hover {
+ background-color: var(--remove-bg);
+}
+
+#edit, #addcol {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ background-color: var(--hover-bg);
+ width: 29px;
+ height: 29px;
+ padding: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ font-weight: bold;
+}
+
+#edit:hover {
+ background-color: var(--hover-bg-2);
+}
+
+#addcol {
+ display: none;
+ right: 29px;
+}
+
+#addcol:hover {
+ background-color: var(--hover-grn);
+}
+
+.add, .rmcol {
+ background-color: var(--hover-bg);
+ margin-top: 14px;
+ width: 29px;
+ height: 29px;
+ padding: 0;
+ justify-content: center;
+ align-items: center;
+ float: right;
+ display: none;
+ cursor: pointer;
+}
+
+.add:hover {
+ background-color: var(--hover-grn) !important;
+}
+
+.rmcol {
+ display: flex;
+}
+
+.rmcol:hover {
+ background-color: var(--remove-bg) !important;
+}
+
+.new {
+ background-color: var(--hover-bg);
+}
+
+.title:hover > .add {
+ display: flex;
+}
+
+.title:hover .add:not(:hover),
+li:hover > .remove:not(:hover) {
+ display: flex;
+ background-color: var(--hover-bg);
+}
+
+li:hover > a, li > a:focus, li > a:focus-within {
+ display: inline-block;
+ background-color: var(--hover-bg);
+}
+
+li:hover {
+ background-color: var(--hover-bg);
+}
+
+a {
+ color: inherit;
+ outline: none;
+ display: block;
+ text-decoration: none;
+ padding: 0.5rem;
+ height: 19px;
+}
+
+.remove:not(:hover) {
+ display: none;
+}
+
+a, ul > .title > p, .colname {
+ width: calc(100% - 45px);
+ display: inline-block;
+}
+
+li.sortable-chosen.sortable-ghost {
+ background-color: var(--hover-bg-2);
+}
+
+.over {
+ /* border: 2px dashed var(--default-fg);*/
+}
+
+span.grip {
+ content: '....';
+ position: relative;
+ right: 20px;
+ top: 36px;
+ width: 10px;
+ height: 20px;
+ display: none;
+ overflow: hidden;
+ line-height: 5px;
+ padding: 3px 4px;
+ cursor: move;
+ vertical-align: middle;
+ font-size: 12px;
+ font-family: sans-serif;
+ font-weight: bold;
+ letter-spacing: 2px;
+}
+
+span.grip::after {
+ content: '.. .. .. ..';
+}
+
+.glyphicon-move {
+ cursor: move;
+ cursor: -webkit-grabbing;
+}
+
+.title {
+ margin-bottom: 0.5rem;
+ font-weight: bold;
+ text-align: left;
+ border-bottom: 1px solid var(--hover-bg);
+}
+
+.title p {
+ width: 160px;
+ margin: 16px 0 8px 0;
+}
+++ /dev/null
-:root {
- --hover-bg: #434c5e;
- --hover-grn: #a3be8c;
- --hover-bg-2: #848ead;
- --remove-bg: #bf616a;
- --default-fg: #d8dee9;
- --default-bg: #2e3440;
-}
-
-html, body {
- font-size: 16px !important;
- width: 100%;
- height: 100%;
-}
-
-body {
- margin: 0;
- color: var(--default-fg);
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
-}
-
-#links {
- display: flex;
- flex-direction: row;
- display: -webkit-flex;
- -webkit-flex-direction: row;
- min-height: 283px;
-}
-
-ul {
- position: relative;
- list-style: none;
- padding: 0;
- width: 10rem;
- margin: 0.5rem 2em 2em 2em;
- float: left;
-}
-
-img {
- float: left;
- margin-top: 1px;
- padding-right: 3px;
-}
-
-input {
- font-size: 16px !important;
- padding: 0;
- height: 18.5px;
- width: 112px;
- margin: 5px;
-}
-
-input.name {
- margin-bottom: 2.5px
-}
-
-input.url {
- margin-top: 2.5px
-}
-
-input.colname {
- width: calc(100% - 68px);
- height: 19px;
- margin: 14px 0 6px 0;
- border: 2px var(--hover-bg) dashed;
- background-color: var(inherit);
- color: inherit;
- font-family: inherit;
-}
-
-.remove {
- width: 29px;
- height: 35px;
- padding: 0;
- background-color: var(--hover-bg);
- float: right;
- text-align: center;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- font-family: monospace;
- display: flex;
-}
-
-.save {
- padding-left: 8px;
- float: right;
- height: 60px;
- width: 21px;
- display: flex;
- text-align: center;
- align-items: center;
- cursor: pointer;
- background-color: var(--hover-bg-2);
-}
-
-.save:hover, .save:focus, .save:focus-within {
- background-color: var(--hover-grn);
-}
-
-.remove:hover {
- background-color: var(--remove-bg);
-}
-
-#edit, #addcol {
- position: absolute;
- right: 0;
- bottom: 0;
- background-color: var(--hover-bg);
- width: 29px;
- height: 29px;
- padding: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- font-weight: bold;
-}
-
-#edit:hover {
- background-color: var(--hover-bg-2);
-}
-
-#addcol {
- display: none;
- right: 29px;
-}
-
-#addcol:hover {
- background-color: var(--hover-grn);
-}
-
-.add, .rmcol {
- background-color: var(--hover-bg);
- margin-top: 14px;
- width: 29px;
- height: 29px;
- padding: 0;
- justify-content: center;
- align-items: center;
- float: right;
- display: none;
- cursor: pointer;
-}
-
-.add:hover {
- background-color: var(--hover-grn) !important;
-}
-
-.rmcol {
- display: flex;
-}
-
-.rmcol:hover {
- background-color: var(--remove-bg) !important;
-}
-
-.new {
- background-color: var(--hover-bg);
-}
-
-.title:hover > .add {
- display: flex;
-}
-
-.title:hover .add:not(:hover),
-li:hover > .remove:not(:hover) {
- display: flex;
- background-color: var(--hover-bg);
-}
-
-li:hover > a, li > a:focus, li > a:focus-within {
- display: inline-block;
- background-color: var(--hover-bg);
-}
-
-li:hover {
- background-color: var(--hover-bg);
-}
-
-a {
- color: inherit;
- outline: none;
- display: block;
- text-decoration: none;
- padding: 0.5rem;
- height: 19px;
-}
-
-.remove:not(:hover) {
- display: none;
-}
-
-a, ul > .title > p, .colname {
- width: calc(100% - 45px);
- display: inline-block;
-}
-
-li.sortable-chosen.sortable-ghost {
- background-color: var(--hover-bg-2);
-}
-
-.over {
- /* border: 2px dashed var(--default-fg);*/
-}
-
-span.grip {
- content: '....';
- position: relative;
- right: 20px;
- top: 36px;
- width: 10px;
- height: 20px;
- display: none;
- overflow: hidden;
- line-height: 5px;
- padding: 3px 4px;
- cursor: move;
- vertical-align: middle;
- font-size: 12px;
- font-family: sans-serif;
- font-weight: bold;
- letter-spacing: 2px;
-}
-
-span.grip::after {
- content: '.. .. .. ..';
-}
-
-.glyphicon-move {
- cursor: move;
- cursor: -webkit-grabbing;
-}
-
-.title {
- margin-bottom: 0.5rem;
- font-weight: bold;
- text-align: left;
- border-bottom: 1px solid var(--hover-bg);
-}
-
-.title p {
- width: 160px;
- margin: 16px 0 8px 0;
-}