-var mainlist;
var rmspan = ["<span class='remove' id='delete-", "'>–</span>"]
var tick = "✔";
+var addText = "+";
+var rmText = "−";
var removebg = "#bf616a";
var hovergrn = "#a3be8c";
var hoverbg = "#434c5e";
var hoverbg2 = "#848ead";
-document.addEventListener("DOMContentLoaded", function() {
- chrome.storage.sync.get(
- {"lists": [
+var editMode = false;
+var dragSrcEl = null;
+var defaultColumns= [
["General",
["Github", "https://github.com"],
["Wikipedia", "https://en.wikipedia.org"],
["YouTube", "https://youtube.com"],
["Instagram", "https://instagram.com"]
]
- ]
-},
- userListsCallback);
-});
-
-function columnToArray(list) {
- var l = [];
- var elem = list.getElementsByClassName("item");
- for (var i = 0; i < elem.length; ++i) {
- l[i] = [elem[i].innerText, elem[i].getAttribute("href")];
- }
- return l;
+]
+
+
+// --------------------------------
+//
+// 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);
+
}
-function listToArray(list) {
- var l = [];
- console.log("looking at list:");
- console.log(list);
- if (editMode == true) {
- l[0] = list.getElementsByClassName('title')[0].getElementsByTagName("input")[0].value;
- }
- else {
- l[0] = list.getElementsByClassName('title')[0].getElementsByTagName("p")[0].textContent;
- }
- var elem = list.getElementsByTagName("li");
- for (var i = 0; i < elem.length; ++i) {
- if (elem[i].class == "new") {
- continue;
- }
- else {
- l[i+1] = [elem[i].getElementsByTagName("a")[0].innerText, elem[i].getElementsByTagName("a")[0].getAttribute("href")];
+
+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);
+
}
- return l;
}
-var userListsCallback = function(lists) {
- mainlist = []
- for (let x of lists['lists']) {
- mainlist.push(x[0]);
- }
- for(var i=0;i<lists["lists"].length;i++) {
- document.getElementById('edit').addEventListener('click', edit, false);
- document.getElementById('addcol').addEventListener('click', addCol, false);
+function genColumn(title) {
+
+ // Generate HTML elements for a column (without items)
+
var ul = document.createElement("ul");
- ul.setAttribute("id", mainlist[i]);
- ul.setAttribute('draggable', 'false'); // Draggable attribute must be set on mousedown event, otherwise any cursor movement causes dragstart()
- document.getElementById("links").appendChild(ul);
+ ul.setAttribute("id", title);
+ ul.setAttribute('draggable', 'false');
var grip = document.createElement("span");
grip.setAttribute("class", "grip");
- grip.addEventListener('mousedown', function() {
- console.log("Drag started");
- uls = document.getElementsByTagName("ul");
- for (let ul of uls) {
- ul.setAttribute("draggable", "true");
- ul.addEventListener('dragstart', dragStart, false);
- ul.addEventListener('dragenter', dragEnter, false);
- ul.addEventListener('dragover', dragOver, false);
- ul.addEventListener('dragleave', dragLeave, false);
- ul.addEventListener('drop', drop, false);
- }
- });
-
- grip.addEventListener('mouseup', function() {
- console.log("Drag ended");
- uls = document.getElementsByTagName("ul");
- for (let ul of uls) {
- ul.setAttribute("draggable", "false");
- ul.removeEventListener('dragstart');
- ul.removeEventListener('dragenter');
- ul.removeEventListener('dragover');
- ul.removeEventListener('dragleave');
- ul.removeEventListener('drop');
- }
- });
-
- var title = document.createElement("div");
- title.setAttribute("class", "title");
+ grip.addEventListener('mousedown', enableDrag);
+ grip.addEventListener('mouseup', disableDrag);
ul.appendChild(grip)
- ul.appendChild(title);
-
- var p = document.createElement("p");
- p.innerText = mainlist[i];
- title.appendChild(p);
-
- title.insertAdjacentHTML("beforeend", "<span class='add' id='add-"+mainlist[i]+"'>+</span>");
-
- var list = lists["lists"][i];
- for(var j=1;j<lists["lists"][i].length;j++) {
- var li = document.createElement("li");
- li.setAttribute("id", mainlist[i]+"-"+j);
- var siteurl = list[j][1];
- var nme = list[j][0];
- var img = document.createElement("img");
- img.className = "icon";
- img.src = "https://www.google.com/s2/favicons?domain="+siteurl+"";
- li.insertAdjacentHTML("beforeend", "<a class='item' href="+siteurl+"><img src="+img.src+" alt="+extractDomain(siteurl,1)+"/> "+nme+"</a>");
- li.insertAdjacentHTML("beforeend", rmspan[0] + j + "-" + mainlist[i] + rmspan[1]);
- ul.appendChild(li);
- }
- new Sortable(ul, {
- group: "userlists",
- animation: 150,
- onUpdate: function (evt) {
- save();
- }
- });
- }
+ var titleDiv = document.createElement("div");
+ titleDiv.setAttribute("class", "title");
- menu();
+ 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);
-function dragStart(e) {
- dragSrcEl = this;
- e.dataTransfer.effectAllowed = 'move';
- e.dataTransfer.setData('text/html', this.innerHTML);
-}
+ ul.appendChild(titleDiv);
-function dragOver(e) {
- if (e.preventDefault) {
- e.preventDefault();
- }
- e.dataTransfer.dropEffect = 'move';
- return false;
-}
+ return ul;
-function dragEnter(e) {
- this.classList.add('over');
}
-function dragLeave(e) {
- this.classList.remove('over');
-}
+function genItem(ul, nme, url) {
-function drop(e) {
- if (e.stopPropagation); {
- e.stopPropagation();
- }
- if (dragSrcEl != this) {
- dragSrcEl.innerHTML = this.innerHTML;
- this.innerHTML = e.dataTransfer.getData('text/html');
- save();
- menu();
- }
- return false;
-}
+ // Generate HTML elements for an item
-var dragSrcEl = null;
+ var li = document.createElement("li");
+ li.setAttribute("class", ul.id + "-" + (ul.getElementsByTagName("li").length + 1).toString() );
+ li.addEventListener("mouseup", saveConfig);
+
+ var img = document.createElement("img");
+ img.className = "icon";
+ img.src = "https://www.google.com/s2/favicons?domain=" + url;
+ img.alt = extractDomain(url, 1);
+
+ 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;
-document.onkeyup=function(e){
- var e = e || window.event; // for IE to cover IEs window event-object
- fields = document.getElementsByClassName("new");
- if(e.which == 27 && fields != null) {
- fields[fields.length-1].remove();
- return false;
- }
- if(e.which == 13 && fields.length > 0) {
- fields[fields.length-1].getElementsByClassName("save")[0].click();
- return false;
- }
}
-var editMode = false;
-function edit() {
+// --------------------------------
+//
+// Edit mode
+//
+// --------------------------------
+
+
+function edit(event) {
+
+ // Enter/exit edit mode
+
if (editMode == true) {
console.log("Exited edit mode");
closeEdit(this);
- return 0;
+ return false;
}
+
console.log("Entered edit mode");
+
this.style.background = hovergrn;
this.innerText = tick;
- addbtn = document.getElementById("addcol");
- addbtn.style.display = "flex";
+ 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";
- title = col.getElementsByClassName("title")[0];
- rmbutton = document.createElement("span");
- rmbutton.setAttribute("class", "rmcol");
- rmbutton.setAttribute("id", "rmcol-"+col.id);
- rmbutton.innerText = "-";
- rmbutton.addEventListener('click', function(event){
- console.log("Deleting column " + this.parentNode.parentNode);
- this.parentNode.parentNode.remove();
- var index = mainlist.indexOf(this.parentNode.parentNode.id);
- console.log("Found deleted node " + this.parentNode.parentNode.id + " at index " + index);
- if (index > -1) {
- mainlist.splice(index, 1);
- }
- save();
- });
- title.appendChild(rmbutton);
- title.getElementsByClassName("add")[0].style.display = "flex";
- titlep = title.getElementsByTagName("p")[0];
- editTitle = document.createElement("input");
- titlep.insertAdjacentHTML("afterend", "<input type='text' class='colname' placeholder='category' value='" + titlep.innerText + "'>");
- titlep.remove();
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) {
+function closeEdit(editBtn) {
+
+ // Exit edit mode and clean up elements
+
editMode = false;
- editbtn.style.background = "";
- editbtn.innerText = "e";
- addbtn = document.getElementById("addcol");
- addbtn.style.display = "none";
+ 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";
- rmbutton = col.getElementsByClassName("title")[0].getElementsByClassName("rmcol")[0];
- rmbutton.remove();
- title = col.getElementsByClassName("title")[0];
- title.getElementsByClassName("add")[0].style.display = "";
- editTitle = title.getElementsByClassName("colname")[0];
- titlep = document.createElement("p");
- titlep.innerText = editTitle.value;
- editTitle.remove();
- title.appendChild(titlep);
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);
+
}
- save();
+
+ saveConfig();
+
}
-function addCol() {
+function addColumn(event) {
+
+ // Create a new column from Edit mode
+
var ul = document.createElement("ul");
- ul.setAttribute("id", "new");
- ul.setAttribute('draggable', 'true');
- ul.addEventListener('dragstart', dragStart, false);
- ul.addEventListener('dragenter', dragEnter, false);
- ul.addEventListener('dragover', dragOver, false);
- ul.addEventListener('dragleave', dragLeave, false);
- ul.addEventListener('drop', drop, false);
- document.getElementById("links").appendChild(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);
- var title = document.createElement("div");
- title.setAttribute("class", "title");
- title.appendChild(grip)
- ul.appendChild(title);
-
- var p = document.createElement("p");
- p.innerText = "new";
- title.appendChild(p);
-
- title.insertAdjacentHTML("beforeend", "<span class='add' id='add-new'>+</span>");
-
- rmbutton = document.createElement("span");
- rmbutton.setAttribute("class", "rmcol");
- rmbutton.setAttribute("id", "rmcol-new");
- rmbutton.innerText = "-";
- rmbutton.addEventListener('click', function(event){
- console.log("Deleting column " + this.parentNode.parentNode);
- this.parentNode.parentNode.remove();
- var index = mainlist.indexOf(this.parentNode.parentNode.id);
- console.log("Found deleted node " + this.parentNode.parentNode.id + " at index " + index);
- if (index > -1) {
- mainlist.splice(index, 1);
- }
- save();
- });
- title.appendChild(rmbutton);
- title.getElementsByClassName("add")[0].style.display = "flex";
- titlep = title.getElementsByTagName("p")[0];
- editTitle = document.createElement("input");
- titlep.insertAdjacentHTML("afterend", "<input type='text' class='colname' placeholder='category'>");
- titlep.remove();
+ document.getElementById("links").appendChild(ul);
+ saveConfig();
+ updateListeners();
+ titleInput.focus();
+
+}
+
+
+function removeColumn(event) {
+
+ // Delete column in edit mode
- mainlist.push(["new"]);
- save();
- listen(title.getElementsByClassName("add")[0]);
+ this.parentNode.parentNode.remove();
+ saveConfig();
+
}
-function listen(li) {
- li.addEventListener('click', function(event){
- var r = event.target.id.split("-");
- if (r[0] == "delete") {
- var el = document.getElementById(r[2]+"-"+r[1]);
- el.outerHTML = "";
- delete el;
- save();
- } else {
- addItem(r, li);
+
+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");
}
- }, true);
+
+ }
+
}
-function addItem(caller, li) {
- if (ul == null) {
- var ul = li.parentNode.parentNode;
- var id = ul.id;
- }
- else {
- var ul = document.getElementById(caller[1]);
- var id = caller[1];
- }
-
- if (document.querySelectorAll("#"+id+" .new").length > 0) {
- fields = document.querySelector("#"+id+" .new .name");
- fields.focus();
- return false;
- }
- var li = document.createElement("li");
- li.setAttribute("class", "new");
- li.insertAdjacentHTML("beforeend", "<span class='save' tabindex='3' id='input-"+columnToArray(li).length.toString()+"'>"+tick+"</span><input type='text' class='name' value='' placeholder='name' tabindex='1'><br /><input type='url' spellcheck=false class='url' value='' placeholder='url' tabindex='2' id='form-"+columnToArray(li).length.toString()+"'>");
- ul.appendChild(li);
- var span = document.getElementById("input-"+columnToArray(li).length.toString());
- var form = document.getElementById("form-"+columnToArray(li).length.toString());
- span.addEventListener('click', function(event){
- console.log("Adding item to:");
- console.log(this);
- var li = document.getElementsByClassName("new")[0]
- var ul = li.parentNode;
- if (li.getElementsByClassName("name")[0].value != "" && li.getElementsByClassName("url")[0].value != "" && li.getElementsByClassName("url")[0].validity.typeMismatch== false) {
- var newli = document.createElement("li");
- newli.setAttribute("id",caller[1]+"-"+columnToArray(ul).length.toString());
- var siteurl = addhttp(li.getElementsByClassName("url")[0].value);
- var nme = li.getElementsByClassName("name")[0].value;
- li.remove()
- delete li;
-
- newli.insertAdjacentHTML("beforeend", "<a href="+siteurl+">"+nme+"</a>");
- newli.insertAdjacentHTML("beforeend", rmspan[0]+columnToArray(ul).length.toString()+"-"+caller[1]+rmspan[1]);
- document.getElementById(id).appendChild(newli);
- save();
- listen(newli);
- }
- else {
- if (li.getElementsByClassName("name")[0].value == "" && li.getElementsByClassName("url")[0].value == "") {
- console.log("No data supplied, deleting form");
- this.parentNode.remove();
- }
- else {
- console.log("Missing data, press Esc to delete form");
- }
- }
- });
- span.onmouseover = function() {
- nme = document.getElementsByClassName("name")[0];
- url = document.getElementsByClassName("url")[0];
- if (nme.value === '' || url.value === '' || url.validity.typeMismatch == true) {
- this.style.background = removebg;
- }
- else {
- this.style.background = hovergrn;
- }
- };
- span.onmouseout = function() {
- this.style.background = hoverbg2;
- };
- menu(); // TODO fix bug where form save button loses its eventlistener after generating form for another column twice
- fields = document.querySelector("#"+id+" .new .name");
- fields.focus();
+// --------------------------------
+//
+// 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 menu() {
- // Update event listeners for all items, their remove buttons, and the add button for each column
- var allUserLi = document.querySelectorAll('.remove, .add');
- allUserLi.forEach(function(li, p_index){
- listen(li);
- });
+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 save(l) {
- console.log(mainlist);
- var set = l || JSON.parse(JSON.stringify(mainlist));
- d = []
- d = set;
+
+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");
- for (var i = 0; i < set.length; ++i) {
- d[i] = listToArray(document.getElementById(set[i]));
+ data = []
+ for (let ul of document.getElementsByTagName("ul")) {
+ data.push(columnToArray(ul, true));
}
- chrome.storage.sync.set( {"lists": d} );
+ 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;
+
}