96e4d4609d0e7ea66e44272ace0b05f9ffcb41ea
   1var mainlist;
   2var rmspan = ["<span class='remove' id='delete-", "'>–</span>"]
   3var tick = "✔";
   4var removebg = "#bf616a";
   5var hovergrn = "#a3be8c";
   6var hoverbg = "#434c5e";
   7var hoverbg2 = "#848ead";
   8document.addEventListener("DOMContentLoaded", function() {
   9  chrome.storage.sync.get(
  10    {"lists": [
  11      ["General",
  12        ["Github", "https://github.com"],
  13        ["Wikipedia", "https://en.wikipedia.org"],
  14        ["Gmail", "https://mail.google.com"]
  15      ],
  16      ["Productivity",
  17        ["Desmos", "https://www.desmos.com/calculator"],
  18        ["Wolfram", "https://wolframalpha.com"],
  19        ["Hacker News", "https://news.ycombinator.com"]
  20      ],
  21      ["Social",
  22        ["Reddit", "https://www.reddit.com"],
  23        ["YouTube", "https://youtube.com"],
  24        ["Instagram", "https://instagram.com"]
  25      ]
  26    ]
  27},
  28    userListsCallback);
  29});
  30
  31function columnToArray(list) {
  32  var l = [];
  33  var elem = list.getElementsByClassName("item");
  34  for (var i = 0; i < elem.length; ++i) {
  35    l[i] = [elem[i].innerText, elem[i].getAttribute("href")];
  36  }
  37  return l;
  38}
  39
  40function listToArray(list) {
  41  var l = [];
  42  console.log(list.getElementsByClassName('title')[0].getElementsByTagName("p")[0].textContent);
  43  l[0] = list.getElementsByClassName('title')[0].getElementsByTagName("p")[0].textContent;
  44  var elem = list.getElementsByTagName("li");
  45  for (var i = 0; i < elem.length; ++i) {
  46    l[i+1] = [elem[i].getElementsByTagName("a")[0].innerText, elem[i].getElementsByTagName("a")[0].getAttribute("href")];
  47  }
  48  return l;
  49}
  50
  51var userListsCallback = function(lists) {
  52  mainlist = []
  53  for (let x of lists['lists']) {
  54    mainlist.push(x[0]);
  55  }
  56  for(var i=0;i<lists["lists"].length;i++) {
  57    document.getElementById('edit').addEventListener('click', edit, false);
  58    document.getElementById('addcol').addEventListener('click', addCol, false);
  59    var ul = document.createElement("ul");
  60    ul.setAttribute("id", mainlist[i]);
  61    ul.setAttribute('draggable', 'true');
  62    ul.addEventListener('dragstart', dragStart, false);
  63    ul.addEventListener('dragenter', dragEnter, false);
  64    ul.addEventListener('dragover', dragOver, false);
  65    ul.addEventListener('dragleave', dragLeave, false);
  66    ul.addEventListener('drop', drop, false);
  67    document.getElementById("links").appendChild(ul);
  68
  69    var grip = document.createElement("span");
  70    grip.setAttribute("class", "grip");
  71
  72    var title = document.createElement("div");
  73    title.setAttribute("class", "title");
  74    ul.appendChild(grip)
  75    ul.appendChild(title);
  76
  77    var p = document.createElement("p");
  78    p.innerText = mainlist[i];
  79    title.appendChild(p);
  80
  81    title.insertAdjacentHTML("beforeend", "<span class='add' id='add-"+mainlist[i]+"'>+</span>");
  82
  83    var list = lists["lists"][i];
  84    for(var j=1;j<lists["lists"][i].length;j++) {
  85      var li = document.createElement("li");
  86      li.setAttribute("id", mainlist[i]+"-"+j);
  87      var siteurl = list[j][1];
  88      var nme = list[j][0];
  89      var img = document.createElement("img");
  90      img.className = "icon";
  91      img.src = "https://www.google.com/s2/favicons?domain="+siteurl+"";
  92      li.insertAdjacentHTML("beforeend", "<a class='item' href="+siteurl+"><img src="+img.src+" alt="+extractDomain(siteurl,1)+"/> "+nme+"</a>");
  93      li.insertAdjacentHTML("beforeend", rmspan[0] + j + "-" + mainlist[i] + rmspan[1]);
  94      ul.appendChild(li);
  95    }
  96
  97    new Sortable(ul, {
  98      group: "userlists",
  99      animation: 150,
 100      onUpdate: function (evt) {
 101        save();
 102      }
 103    });
 104  }
 105
 106  menu();
 107
 108};
 109
 110function dragStart(e) {
 111  dragSrcEl = this;
 112  e.dataTransfer.effectAllowed = 'move';
 113  e.dataTransfer.setData('text/html', this.innerHTML);
 114}
 115
 116function dragOver(e) {
 117  if (e.preventDefault) {
 118    e.preventDefault();
 119  }
 120  e.dataTransfer.dropEffect = 'move';
 121  return false;
 122}
 123
 124function dragEnter(e) {
 125  this.classList.add('over');
 126}
 127
 128function dragLeave(e) {
 129  this.classList.remove('over');
 130}
 131
 132function drop(e) {
 133  if (e.stopPropagation); {
 134    e.stopPropagation();
 135  }
 136  if (dragSrcEl != this) {
 137    dragSrcEl.innerHTML = this.innerHTML;
 138    this.innerHTML = e.dataTransfer.getData('text/html');
 139    save();
 140  }
 141  return false;
 142}
 143
 144var dragSrcEl = null;
 145
 146document.onkeyup=function(e){
 147  var e = e || window.event; // for IE to cover IEs window event-object
 148  fields = document.getElementsByClassName("new");
 149  if(e.which == 27 && fields != null) {
 150    fields[fields.length-1].remove();
 151    return false;
 152  }
 153  if(e.which == 13 && fields.length > 0) {
 154    fields[fields.length-1].getElementsByClassName("save")[0].click();
 155    return false;
 156  }
 157}
 158
 159var editMode = false;
 160
 161function edit() {
 162  if (editMode == true) {
 163    console.log("Exited edit mode");
 164    closeEdit(this);
 165    return 0;
 166  }
 167  console.log("Entered edit mode");
 168  this.style.background = hovergrn;
 169  this.innerText = tick;
 170  addbtn = document.getElementById("addcol");
 171  addbtn.style.display = "flex";
 172  var cols = document.getElementsByTagName("ul");
 173  for (let col of cols) {
 174    col.style.bottom = "26px";
 175    title = col.getElementsByClassName("title")[0];
 176    rmbutton = document.createElement("span"); 
 177    rmbutton.setAttribute("class", "rmcol");
 178    rmbutton.setAttribute("id", "rmcol-"+col.id);
 179    rmbutton.innerText = "-";
 180    rmbutton.addEventListener('click', function(event){
 181      console.log("Deleting column " + this.parentNode.parentNode);
 182      this.parentNode.parentNode.remove();
 183      var index = mainlist.indexOf(this.parentNode.parentNode.id);
 184      console.log("Found deleted node " + this.parentNode.parentNode.id + " at index " + index);
 185      if (index > -1) {
 186        mainlist.splice(index, 1);
 187      }
 188      save();
 189    });
 190    title.appendChild(rmbutton);
 191    title.getElementsByClassName("add")[0].style.display = "flex";
 192    titlep = title.getElementsByTagName("p")[0];
 193    editTitle = document.createElement("input");
 194    titlep.insertAdjacentHTML("afterend", "<input type='text' class='colname' placeholder='category' value='" + titlep.innerText + "'>");
 195    titlep.remove();
 196    col.getElementsByClassName("grip")[0].style.display = "inline-block";
 197  }
 198  editMode = true;
 199}
 200
 201function closeEdit(editbtn) {
 202  editbtn.style.background = "";
 203  editbtn.innerText = "e";
 204  addbtn = document.getElementById("addcol");
 205  addbtn.style.display = "none";
 206  var cols = document.getElementsByTagName("ul");
 207  for (let col of cols) {
 208    col.style.bottom = "0";
 209    rmbutton = col.getElementsByClassName("title")[0].getElementsByClassName("rmcol")[0];
 210    rmbutton.remove();
 211    title = col.getElementsByClassName("title")[0];
 212    title.getElementsByClassName("add")[0].style.display = "";
 213    editTitle = title.getElementsByClassName("colname")[0];
 214    titlep = document.createElement("p");
 215    titlep.innerText = editTitle.value;
 216    editTitle.remove();
 217    title.appendChild(titlep);
 218    col.getElementsByClassName("grip")[0].style.display = "none";
 219  }
 220  save();
 221  editMode = false;
 222}
 223
 224function addCol() {
 225  var ul = document.createElement("ul");
 226  ul.setAttribute("id", "new");
 227  ul.setAttribute('draggable', 'true');
 228  ul.addEventListener('dragstart', dragStart, false);
 229  ul.addEventListener('dragenter', dragEnter, false);
 230  ul.addEventListener('dragover', dragOver, false);
 231  ul.addEventListener('dragleave', dragLeave, false);
 232  ul.addEventListener('drop', drop, false);
 233  document.getElementById("links").appendChild(ul);
 234
 235  var grip = document.createElement("span");
 236  grip.setAttribute("class", "grip");
 237
 238  var title = document.createElement("div");
 239  title.setAttribute("class", "title");
 240  title.appendChild(grip)
 241  ul.appendChild(title);
 242
 243  var p = document.createElement("p");
 244  p.innerText = "new";
 245  title.appendChild(p);
 246
 247  title.insertAdjacentHTML("beforeend", "<span class='add' id='add-new'>+</span>");
 248
 249  rmbutton = document.createElement("span"); 
 250  rmbutton.setAttribute("class", "rmcol");
 251  rmbutton.setAttribute("id", "rmcol-new");
 252  rmbutton.innerText = "-";
 253  rmbutton.addEventListener('click', function(event){
 254    console.log("Deleting column " + this.parentNode.parentNode);
 255    this.parentNode.parentNode.remove();
 256    var index = mainlist.indexOf(this.parentNode.parentNode.id);
 257    console.log("Found deleted node " + this.parentNode.parentNode.id + " at index " + index);
 258    if (index > -1) {
 259      mainlist.splice(index, 1);
 260    }
 261    save();
 262  });
 263  title.appendChild(rmbutton);
 264  title.getElementsByClassName("add")[0].style.display = "flex";
 265  titlep = title.getElementsByTagName("p")[0];
 266  editTitle = document.createElement("input");
 267  titlep.insertAdjacentHTML("afterend", "<input type='text' class='colname' placeholder='category'>");
 268  titlep.remove();
 269  
 270  mainlist.push(["new"]);
 271  save();
 272  listen(title.getElementsByClassName("add")[0]);
 273}
 274
 275function listen(li) {
 276  li.addEventListener('click', function(event){
 277    var r = event.target.id.split("-");
 278    if (r[0] == "delete") {
 279      var el = document.getElementById(r[2]+"-"+r[1]);
 280      el.outerHTML = "";
 281      delete el;
 282      save();
 283    } else {
 284      addItem(r, li);
 285    }
 286  }, false);
 287}
 288
 289function addItem(caller, li) {
 290      if (ul == null) {
 291        var ul = li.parentNode.parentNode;
 292        var id = ul.id;
 293      }
 294      else {
 295        var ul = document.getElementById(caller[1]);
 296        var id = caller[1];
 297      }
 298      
 299      if (document.querySelectorAll("#"+id+" .new").length > 0) {
 300        fields = document.querySelector("#"+id+" .new .name");
 301        fields.focus(); 
 302        return false;
 303      }
 304      var li = document.createElement("li");
 305      li.setAttribute("class", "new");
 306      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()+"'>");
 307      ul.appendChild(li);
 308      var span = document.getElementById("input-"+columnToArray(li).length.toString());
 309      var form = document.getElementById("form-"+columnToArray(li).length.toString());
 310      span.addEventListener('click', function(event){
 311        var li = document.getElementsByClassName("new")[0]
 312        var ul = li.parentNode;
 313        if (li.getElementsByClassName("name")[0].value != "" && li.getElementsByClassName("url")[0].value != "" && li.getElementsByClassName("url")[0].validity.typeMismatch== false) {
 314          var newli = document.createElement("li");
 315          newli.setAttribute("id",caller[1]+"-"+columnToArray(ul).length.toString());
 316          var siteurl = addhttp(li.getElementsByClassName("url")[0].value);
 317          var nme = li.getElementsByClassName("name")[0].value;
 318          li.remove()
 319          delete li;
 320
 321          newli.insertAdjacentHTML("beforeend", "<a href="+siteurl+">"+nme+"</a>");
 322          newli.insertAdjacentHTML("beforeend", rmspan[0]+columnToArray(ul).length.toString()+"-"+caller[1]+rmspan[1]);
 323          document.getElementById(id).appendChild(newli);
 324          save();
 325          listen(newli);
 326        }
 327        else {
 328          if (li.getElementsByClassName("name")[0].value == "" && li.getElementsByClassName("url")[0].value == "") {
 329            console.log("No data supplied, deleting form");
 330            this.parentNode.remove();
 331          }
 332          else {
 333            console.log("Missing data, press Esc to delete form");
 334          }
 335        }
 336      });
 337      span.onmouseover = function() {
 338        nme = document.getElementsByClassName("name")[0];
 339        url = document.getElementsByClassName("url")[0];
 340        if (nme.value === ''  || url.value === '' || url.validity.typeMismatch == true) {
 341          this.style.background = removebg;
 342        }
 343        else {
 344          this.style.background = hovergrn; 
 345        }
 346      };
 347      span.onmouseout = function() {
 348        this.style.background = hoverbg2;
 349      };
 350      fields = document.querySelector("#"+id+" .new .name");
 351      fields.focus(); 
 352
 353}
 354
 355function menu() {
 356  var allUserLi = document.querySelectorAll('.remove, .add');
 357
 358  allUserLi.forEach(function(li, p_index){
 359    listen(li);
 360  });
 361}
 362
 363function save(l) {
 364  console.log(mainlist);
 365  var set = l || JSON.parse(JSON.stringify(mainlist));
 366  d = []
 367  d = set;
 368  console.log("Saving settings");
 369  for (var i = 0; i < set.length; ++i) {
 370    d[i] = listToArray(document.getElementById(set[i]));
 371  }
 372  chrome.storage.sync.set( {"lists": d} );
 373}