From: Andrew Lorimer Date: Mon, 19 Aug 2019 09:01:20 +0000 (+1000) Subject: new directory structure X-Git-Url: https://git.lorimer.id.au/newtab.git/diff_plain/158443130e7a7e429fcd71ac29ecaca02472583e?ds=sidebyside new directory structure --- diff --git a/main.js b/main.js deleted file mode 100644 index 3af538f..0000000 --- a/main.js +++ /dev/null @@ -1,608 +0,0 @@ -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; - -} diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 320055b..0000000 --- a/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "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" -} diff --git a/newtab.html b/newtab.html deleted file mode 100644 index b572bfe..0000000 --- a/newtab.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - New Tab - - - - - - - - - - - - - e - + - - - - - - diff --git a/options.html b/options.html deleted file mode 100644 index 1cbdbf3..0000000 --- a/options.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - newtab - - - - - - - - - - - - - - - - - -
Background
Foreground
Hover
- - - -

Made by
Andrew Lorimer

- - - - diff --git a/options.js b/options.js deleted file mode 100644 index 31ff156..0000000 --- a/options.js +++ /dev/null @@ -1,32 +0,0 @@ -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); diff --git a/sortable.min.js b/sortable.min.js deleted file mode 100644 index e95d2a3..0000000 --- a/sortable.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! 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=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 diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..3af538f --- /dev/null +++ b/src/main.js @@ -0,0 +1,608 @@ +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; + +} diff --git a/src/manifest.json b/src/manifest.json new file mode 100644 index 0000000..320055b --- /dev/null +++ b/src/manifest.json @@ -0,0 +1,15 @@ +{ + "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" +} diff --git a/src/newtab.html b/src/newtab.html new file mode 100644 index 0000000..b572bfe --- /dev/null +++ b/src/newtab.html @@ -0,0 +1,26 @@ + + + + + + New Tab + + + + + + + + + + + + + e + + + + + + + + diff --git a/src/options.html b/src/options.html new file mode 100644 index 0000000..1cbdbf3 --- /dev/null +++ b/src/options.html @@ -0,0 +1,46 @@ + + + + + + newtab + + + + + + + + + + + + + + + + + +
Background
Foreground
Hover
+ + + +

Made by
Andrew Lorimer

+ + + + diff --git a/src/options.js b/src/options.js new file mode 100644 index 0000000..31ff156 --- /dev/null +++ b/src/options.js @@ -0,0 +1,32 @@ +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); diff --git a/src/sortable.min.js b/src/sortable.min.js new file mode 100644 index 0000000..e95d2a3 --- /dev/null +++ b/src/sortable.min.js @@ -0,0 +1,2 @@ +/*! 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=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 diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..c29e55d --- /dev/null +++ b/src/style.css @@ -0,0 +1,248 @@ +: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; +} diff --git a/style.css b/style.css deleted file mode 100644 index c29e55d..0000000 --- a/style.css +++ /dev/null @@ -1,248 +0,0 @@ -: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; -}