braiam

popup.js

Aug 6th, 2012
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var mirrors;
  2. var mangas;
  3. var parameters;
  4. var bookmarks;
  5.  
  6. //Opens an url in new tab
  7. function openTab(urlToOpen) {
  8.     chrome.extension.sendRequest({
  9.         action: "opentab",
  10.         url: urlToOpen
  11.     }, function (response) {});
  12. }
  13.  
  14. //Used to request background page action
  15. function sendExtRequest(request, button, callback, backsrc) {
  16.     //Prevent a second request
  17.     if (button.data("currentlyClicked")) return;
  18.     button.data("currentlyClicked", true);
  19.  
  20.     //Display a loading image
  21.     var _ancSrc;
  22.     if (button.is("img")) {
  23.         _ancSrc = button.attr("src");
  24.         button.attr("src", chrome.extension.getURL("img/load16.gif"));
  25.     } else {
  26.         if (button.is(".button")) {
  27.             _ancSrc = $("<img src='" + chrome.extension.getURL("img/ltload.gif") + "'></img>")
  28.             _ancSrc.appendTo(button);
  29.         }
  30.         if (button.is(".category") || button.is(".mgcategory")) {
  31.             _ancSrc = $("<img src='" + chrome.extension.getURL("img/load10.gif") + "'></img>")
  32.             _ancSrc.appendTo(button);
  33.         }
  34.     }
  35.     //Call the action
  36.     chrome.extension.sendRequest(request, function () {
  37.         //setTimeout(function() {
  38.         //Do the callback
  39.         callback();
  40.         //Removes the loading image
  41.         if (button.is("img")) {
  42.             if (backsrc) {
  43.                 button.attr("src", _ancSrc);
  44.             }
  45.         } else {
  46.             if (button.is(".button") || button.is(".category") || button.is(".mgcategory")) {
  47.                 _ancSrc.remove();
  48.             }
  49.         }
  50.         //Restore request
  51.         button.removeData("currentlyClicked");
  52.         //}, 1000);
  53.     });
  54. }
  55.  
  56. //Returns true if manga has new chapter
  57. function isNew(mg) {
  58.     var ret = false;
  59.     if (mg.read == 0) {
  60.         if (mg.listChaps.length > 0) {
  61.             if (mg.listChaps[0][1] != mg.lastChapterReadURL) {
  62.                 ret = true;
  63.             }
  64.         }
  65.     }
  66.     return ret;
  67. }
  68.  
  69. //When play button clicked
  70. function actionPlay() {
  71.     openTab(closestEltData($(this)).data("mgplay"));
  72. }
  73. //When back button clicked
  74. function actionBack() {
  75.     var opt = $(".mglist select option:selected", closestEltData($(this)));
  76.     openTab((opt.next().size() > 0) ? opt.next().val() : opt.val());
  77. }
  78. //When next button clicked
  79. function actionForward() {
  80.     var opt = $(".mglist select option:selected", closestEltData($(this)));
  81.     openTab((opt.prev().size() > 0) ? opt.prev().val() : opt.val());
  82. }
  83. //When end button clicked
  84. function actionEnd() {
  85.     var opt = $(".mglist select option:first", closestEltData($(this)));
  86.     openTab(opt.val());
  87. }
  88. //When read button clicked
  89. function actionRead() {
  90.     var obj = {
  91.         action: "readManga",
  92.         url: closestEltData($(this)).data("mgurl"),
  93.         lastChapterReadURL: closestEltData($(this)).data("mglatesturl")
  94.     };
  95.     var _self = this;
  96.     sendExtRequest(obj, $(this), function () {
  97.         $(_self).unbind("click");
  98.         $(_self).attr("src", chrome.extension.getURL("img/blank.png"));
  99.         closestEltData($(_self)).removeClass("new");
  100.         closestEltData($(_self)).data("mgplay", $(".mglist select option:first", closestEltData($(_self))).val());
  101.         $(".mglist select", closestEltData($(_self))).val($(".mglist select option:first", closestEltData($(_self))).val());
  102.         if (isInGroup($(_self))) {
  103.             if (groupHasNew($(_self))) {
  104.                 moveMangaElement($(".mgtitle", closestEltData($(_self))));
  105.             } else {
  106.                 //Move manga
  107.                 $(_self).closest(".manga").removeClass("new");
  108.                 $(".actreadall", $(_self).closest(".manga")).remove();
  109.                 moveMangaParent($(".mgtitle", closestEltData($(_self))));
  110.             }
  111.         } else {
  112.             moveMangaParent($(".mgtitle", closestEltData($(_self))));
  113.         }
  114.         updateProgression($(_self));
  115.     }, false);
  116. }
  117.  
  118. //Fill actions buttons
  119. function fillActions(mg, where, hasdown) {
  120.     var acts = "<img src='img/backward.png' class='actback' title='View previous chapter'/><img src='img/play.png' class='actplay' title='View latest chapter read'/><img src='img/foward.png' class='actfor' title='View next chapter'/><img src='img/toend.png' class='actend' title='View latest published chapter'/><img src='img/cancel.png' class='deletemg' title='Delete this manga from reading list'/>";
  121.     if (isNew(mg)) {
  122.         acts = "<img src='img/eye.png' class='actread' title='Mark latest published chapter as read' />" + acts;
  123.     } else {
  124.         acts = "<img src='img/blank.png' class='actblank' />" + acts;
  125.     }
  126.     if (hasdown) {
  127.         acts += "<img src='img/down_der.png' class='clipoths' title='View other informations and actions for this manga'/>";
  128.     }
  129.  
  130.     $(acts).appendTo(where);
  131. }
  132.  
  133. //Fills the list of chapters
  134. function fillChapters(mg, sel) {
  135.     //Timeout to display popup while loading selects...
  136.     setTimeout(function () {
  137.         var opt = $("<option value=''></option>");
  138.         if (mg.listChaps.length > 0) {
  139.             $.each(mg.listChaps, function (index, val) {
  140.                 opt.clone().val(val[1]).text(val[0]).attr("selected", ((val[1] == mg.lastChapterReadURL) ? "selected" : "")).appendTo(sel);
  141.             });
  142.             sel.attr("title", "Latest published chapter : " + mg.listChaps[0][0]);
  143.             //It's necessary to bind this event here because of the setTimeout...
  144.             sel.change(function () {
  145.                 openTab($(this).val());
  146.             });
  147.         } else {
  148.             $("<span>No chapters found yet...</span>").appendTo(sel.parent().parent());
  149.             sel.parent().remove();
  150.         }
  151.     }, 1);
  152. }
  153.  
  154. function fillCategories(mg, where) {
  155.     if (mg.length) {
  156.         var categs = [];
  157.         $.each(mg, function (index, manga) {
  158.             $.each(manga.cats, function (index, cat) {
  159.                 var found = false;
  160.                 $.each(categs, function (index, val) {
  161.                     if (cat == val) {
  162.                         found = true;
  163.                     }
  164.                 });
  165.                 if (!found) {
  166.                     if (categs.length == 0) {
  167.                         where.empty();
  168.                     }
  169.                     categs[categs.length] = cat;
  170.                     $("<div class='mgcategory'>" + cat + "<img class='actcatmgdel' src='img/delete10.png' title='Delete this category from this manga' /></div>").appendTo(where);
  171.                 }
  172.             });
  173.         });
  174.         bindCatsButtons();
  175.     } else {
  176.         if (mg.cats.length > 0) {
  177.             where.empty();
  178.         }
  179.         $.each(mg.cats, function (index, cat) {
  180.             $("<div class='mgcategory'>" + cat + "<img class='actcatmgdel' src='img/delete10.png' title='Delete this category from this manga' /></div>").appendTo(where);
  181.         });
  182.         bindCatsButtons();
  183.     }
  184. }
  185.  
  186. //Calculate reading progression from mangas object
  187. function progression(mg) {
  188.     if (mg.length) {
  189.         //Multiple manga
  190.         var min = 100;
  191.         $.each(mg, function (index, val) {
  192.             var ptmp = progression(val);
  193.             if (ptmp < min) min = ptmp;
  194.         });
  195.         return min;
  196.     } else {
  197.         //Single manga
  198.         var value = 0;
  199.         if (mg.listChaps.length > 0) {
  200.             $.each(mg.listChaps, function (index, val) {
  201.                 if (val[1] == mg.lastChapterReadURL) {
  202.                     if (mg.listChaps.length < 2) {
  203.                         value = 100;
  204.                     } else {
  205.                         value = Math.floor((mg.listChaps.length - 1 - index) * 100 / (mg.listChaps.length - 1));
  206.                     }
  207.                 }
  208.             });
  209.         }
  210.         return value;
  211.     }
  212. }
  213.  
  214. //Update reading progression from dom
  215. function updateProgression(elt) {
  216.     var par;
  217.     if (elt.is(".manga")) {
  218.         par = elt;
  219.     } else {
  220.         par = elt.closest(".manga");
  221.     }
  222.     var progBar = $(".mgprogress", par);
  223.     var progNum = $(".mgprogressnum", par);
  224.     var selects;
  225.     if (isInGroup($(".mgtitle:first", par))) {
  226.         if (isList()) {
  227.             selects = $(".mgline select", par);
  228.         } else {
  229.             selects = $(".mgelt select", par);
  230.         }
  231.     } else {
  232.         selects = $(".mglist select", par);
  233.     }
  234.  
  235.     var value = 0;
  236.     if (selects.size() > 0) {
  237.         var min = 100;
  238.         selects.each(function (index) {
  239.             var tmpval = 0;
  240.             var nbTot = $("option", $(this)).size();
  241.             $("option", $(this)).each(function (index) {
  242.                 if ($(this).is(":selected")) {
  243.                     if (nbTot < 2) {
  244.                         tmpVal = 100;
  245.                     } else {
  246.                         tmpval = Math.floor((nbTot - 1 - index) * 100 / (nbTot - 1));
  247.                     }
  248.                 }
  249.             });
  250.             if (tmpval < min) min = tmpval;
  251.         });
  252.         value = min;
  253.     }
  254.     progBar.progressbar({
  255.         "value": value
  256.     });
  257.     progNum.text(value + "%");
  258. }
  259.  
  260. //Add a bookmark entry in a select
  261. function addBookmarkInSel(bm, sel) {
  262.     var isGroup = isInGroup(sel);
  263.     var optgrp;
  264.     if (bm.type == "chapter") {
  265.         if ($("optgroup[label='Chapters']", sel).size() > 0) {
  266.             optgrp = $("optgroup[label='Chapters']", sel);
  267.         } else {
  268.             optgrp = $("<optgroup label='Chapters'></optgroup>")
  269.             optgrp.appendTo(sel);
  270.         }
  271.     } else {
  272.         if ($("optgroup[label='Scans']", sel).size() > 0) {
  273.             optgrp = $("optgroup[label='Scans']", sel);
  274.         } else {
  275.             optgrp = $("<optgroup label='Scans'></optgroup>")
  276.             optgrp.appendTo(sel);
  277.         }
  278.     }
  279.     var nt = bm.note;
  280.     var broken = false;
  281.     if (nt.length > 30) {
  282.         broken = true;
  283.         nt = nt.substring(0, 30) + "...";
  284.     }
  285.     var ch = bm.chapName;
  286.     if (ch.length > 20) nt = ch.substring(0, 20) + "...";
  287.     var txt = nt + " (" + ch + (isGroup ? " - " + bm.mirror : "") + ")";
  288.     //NOTE : title attribute is not rendered on option tags in WebKit --> bug --> will work someday ?
  289.     var opt = $("<option value='" + bm.chapUrl + "' title='" + (broken ? escape(bm.note) : "") + "'>" + txt + "</option>");
  290.     opt.data("bmmirror", bm.mirror);
  291.     opt.appendTo(optgrp);
  292. }
  293.  
  294. function addLastUpdate(mg, where, wheretit) {
  295.     var ts;
  296.     if (mg.length) {
  297.         ts = 0;
  298.         for (var i = 0; i < mg.length; i++) {
  299.             if (mg[i].upts > ts) {
  300.                 ts = mg[i].upts;
  301.             }
  302.         }
  303.     } else {
  304.         ts = mg.upts;
  305.     }
  306.  
  307.     if (ts != 0) {
  308.         if (parameters.displastup == 1) {
  309.             $("<img class=\"lastupdatedate\" src=\"" + chrome.extension.getURL(getPicTs(ts)) + "\" title=\"Last time new chapter : " + prettyDate(ts) + "\" />").appendTo(where);
  310.         } else {
  311.             wheretit && wheretit.attr("title", "Last time new chapter : " + prettyDate(ts));
  312.         }
  313.     } else {
  314.         wheretit && wheretit.attr("title", "Last time new chapter : never");
  315.     }
  316. }
  317.  
  318. function prettyDate(time) {
  319.     var diff = ((new Date().getTime() - time) / 1000);
  320.     var day_diff = Math.floor(diff / 86400);
  321.  
  322.     if (isNaN(day_diff) || day_diff < 0) {
  323.         return;
  324.     }
  325.  
  326.     return day_diff == 0 && (
  327.     diff < 60 && "just now" || diff < 120 && "1 minute ago" || diff < 3600 && Math.floor(diff / 60) + " minutes ago" || diff < 7200 && "1 hour ago" || diff < 86400 && Math.floor(diff / 3600) + " hours ago") || day_diff == 1 && "Yesterday" || day_diff < 7 && day_diff + " days ago" || day_diff < 31 && Math.ceil(day_diff / 7) + " weeks ago" || Math.ceil(day_diff / 30.43) + " month ago";
  328. }
  329.  
  330. function getPicTs(time) {
  331.     var diff = ((new Date().getTime() - time) / 1000);
  332.     var day_diff = Math.floor(diff / 86400);
  333.  
  334.     if (isNaN(day_diff) || day_diff < 0) {
  335.         return;
  336.     }
  337.  
  338.     return (diff < 86400 && "img/day.png") || (day_diff == 1 && "img/day.png") || (day_diff < 7 && "img/week.png") || (day_diff < 31 && "img/month.png") || "img/month.png";
  339. }
  340. //Fill the bookmarks select
  341. function fillBookmarks(mg, where) {
  342.     //Timeout to display popup while loading selects...
  343.     if (bookmarks.length > 0) {
  344.         var first = true;
  345.         setTimeout(function () {
  346.             var sel;
  347.             $.each(bookmarks, function (index, val) {
  348.                 if (mg.length) {
  349.                     $.each(mg, function (index, mang) {
  350.                         if ((mang.mirror == val.mirror && mang.url == val.url)) {
  351.                             if (first) {
  352.                                 where.empty();
  353.                                 $("<span class='custom-select'><select><option>Select a bookmark</option></select></span>").appendTo(where);
  354.                                 sel = $("select", where);
  355.                                 //It's necessary to bind this event here because of the setTimeout...
  356.                                 sel.change(function () {
  357.                                     if ($(this).val()) {
  358.                                         openTab($(this).val());
  359.                                     }
  360.                                 });
  361.                                 first = false;
  362.                             }
  363.                             addBookmarkInSel(val, sel);
  364.                         }
  365.                     });
  366.                 } else {
  367.                     if ((mg.mirror == val.mirror && mg.url == val.url)) {
  368.                         if (first) {
  369.                             where.empty();
  370.                             $("<span class='custom-select'><select><option>Select a bookmark</option></select></span>").appendTo(where);
  371.                             sel = $("select", where);
  372.                             //It's necessary to bind this event here because of the setTimeout...
  373.                             sel.change(function () {
  374.                                 if ($(this).val()) {
  375.                                     openTab($(this).val());
  376.                                 }
  377.                             });
  378.                             first = false;
  379.                         }
  380.                         addBookmarkInSel(val, sel);
  381.                     }
  382.                 }
  383.             });
  384.         }, 1);
  385.     }
  386. }
  387.  
  388. //Fill the informations of manga
  389. function fillOthers(mg, where) {
  390.     //return;
  391.  
  392.     var oths = $("<div class='mgothers hide buttons'></div>");
  393.     var prog = $("<div class='mgotherscont'><span>Progression : </span><div class='mgprogress'></div><span class='mgprogressnum'></span></div>");
  394.     var progval = progression(mg);
  395.     $(".mgprogress", prog).progressbar({
  396.         "value": progval
  397.     });
  398.     $(".mgprogressnum", prog).text(progval + "%");
  399.     prog.appendTo(oths);
  400.  
  401.     var infos = $("<div class='mgotherscont'></div>");
  402.     var infoTab = $("<table class='mginfos'><tr><td><span>Categories : </span><div class='mginfo cats'>No categories for this manga</div></td><td><span>Bookmarks : </span><div class='mginfo books'>No bookmarks for this manga</div></td></tr></table>");
  403.     infoTab.appendTo(infos);
  404.     infos.appendTo(oths);
  405.  
  406.     fillCategories(mg, $(".cats", infoTab));
  407.     //setTimeout(function() {
  408.     fillBookmarks(mg, $(".books", infoTab));
  409.  
  410.     //<div class='button actviewrandom'>View random page</div>
  411.     var buts = $("<div class='mgotherscont'><div class='button actsearchmg'>Search this mangas elsewhere</div><div class='button actresetreading'>Reset manga reading</div><div class='button actstopupdates' title='If a manga stops follow updates, AMR will check latest published chapters but won t notify you'>Stop following updates</div><div class='button actstopupdating' title='If a manga stops updating, AMR won t try to get updates from website.'>Stop updating</div></div>");
  412.     var isRead = false;
  413.     var isUpdate = true;
  414.     if (mg.length) {
  415.         $.each(mg, function (index, val) {
  416.             if (val.read == 1) {
  417.                 isRead = true;
  418.             }
  419.             if (val.update == 0) {
  420.                 isUpdate = false;
  421.             }
  422.         });
  423.     } else {
  424.         if (mg.read == 1) isRead = true;
  425.         if (mg.update == 0) isUpdate = false;
  426.     }
  427.     if (isRead) {
  428.         $(".actstopupdates", buts).text("Follow updates");
  429.     }
  430.     if (!isUpdate) {
  431.         $(".actstopupdating", buts).text("Continue update");
  432.     }
  433.     buts.appendTo(oths);
  434.  
  435.     oths.appendTo(where);
  436.  
  437.     //Delete manga question
  438.     var question = $("<div class='mgothers hide question'><span>Are you sure to delete this manga ?</span><div class='button yes'>Yes</div><div class='button no'>No</div></div>");
  439.     question.appendTo(where);
  440.  
  441.     //Reset manga reading question
  442.     var question2 = $("<div class='mgothers hide questionreset'><span>Are you sure reset reading for this manga ?</span><div class='button yes'>Yes</div><div class='button no'>No</div></div>");
  443.     question2.appendTo(where);
  444.     //bindActions();
  445.     //}, 1);
  446. }
  447.  
  448. //Get the closest parent of an element which has the data about the concerned manga
  449. function closestEltData(elt) {
  450.     if (isList()) {
  451.         if ($(".mgline", $(elt).closest(".manga")).size() >= 1) {
  452.             return $(elt).closest(".mgline");
  453.         } else {
  454.             return $(elt).closest(".manga");
  455.         }
  456.     } else {
  457.         if ($(".mgelt", $(elt).closest(".manga")).size() >= 1) {
  458.             return $(elt).closest(".mgelt");
  459.         } else {
  460.             return $(elt).closest(".manga");
  461.         }
  462.     }
  463. }
  464.  
  465. //True if list mode
  466. function isList() {
  467.     return ($("#main").is(".list"));
  468. }
  469.  
  470. //True if elt is in a grouped manga
  471. function isInGroup(elt) {
  472.     if (isList()) {
  473.         return ($(".mgline", $(elt).closest(".manga")).size() >= 1);
  474.     } else {
  475.         return ($(".mgelt", $(elt).closest(".manga")).size() >= 1);
  476.     }
  477. }
  478.  
  479. //True if elt is in a grouped manga which has new elements
  480. function groupHasNew(elt) {
  481.     if (isList()) {
  482.         return ($(".mgline.new", $(elt).closest(".manga")).size() >= 1);
  483.     } else {
  484.         return ($(".mgelt.new", $(elt).closest(".manga")).size() >= 1);
  485.     }
  486. }
  487.  
  488. //True if elt is the first in a grouped manga
  489. function isInFirstOfGroup(elt) {
  490.     if (isInGroup(elt)) {
  491.         if (isList()) {
  492.             return $(elt).closest(".mgline").is(":first-child");
  493.         } else {
  494.             return $(elt).closest(".mgelt").is(":first-child");
  495.         }
  496.     } else {
  497.         return true;
  498.     }
  499. }
  500.  
  501. //How many mangas are in a group
  502. function nbOfGroup(elt) {
  503.     if (isInGroup(elt)) {
  504.         if (isList()) {
  505.             return $(".mgline", $(elt).closest(".manga")).size();
  506.         } else {
  507.             return $(".mgelt", $(elt).closest(".manga")).size();
  508.         }
  509.     } else {
  510.         return 1;
  511.     }
  512. }
  513.  
  514. //Returns the first element of a grouped manga
  515. function getFirstElementOfGroup(elt) {
  516.     if (isInGroup(elt)) {
  517.         if (isList()) {
  518.             return $($(".mgline", $(elt).closest(".manga"))[0]);
  519.         } else {
  520.             return $($(".mgelt", $(elt).closest(".manga"))[0]);
  521.         }
  522.     } else {
  523.         return null;
  524.     }
  525. }
  526.  
  527. //Returns the second element of a grouped manga
  528. function getSecondElementOfGroup(elt) {
  529.     if (isInGroup(elt)) {
  530.         if (isList()) {
  531.             return $($(".mgline", $(elt).closest(".manga"))[1]);
  532.         } else {
  533.             return $($(".mgelt", $(elt).closest(".manga"))[1]);
  534.         }
  535.     } else {
  536.         return null;
  537.     }
  538. }
  539.  
  540. //first and second must be elements inside a group, switchHeader put + button, multiple actions, ...
  541. //on the second element and the first becomes a follower.
  542. function switchHeader(first, second) {
  543.     $(".clipoths", first).appendTo($(".mgactions", second));
  544.     if (isList()) {
  545.         $(".mgtitle", second).remove();
  546.         $(".mgtitle", first).prependTo(second);
  547.         $("<div class='mgtitle'></div>").prependTo(first);
  548.         second.css("display", "table-row");
  549.     } else {
  550.         $(".mgtitle", second).after($("<div class='mgfirstfloatimg'></div>"));
  551.         $(".mgtitlehead img", second).appendTo($(".mgfirstfloatimg", second));
  552.         $(".mgtitleheadpics", first).appendTo($(".mgtitle", second));
  553.         $("<img src='img/plus.png' class='multiplemgs' /><span class='mgname'></span>").appendTo($(".mgtitlehead", second));
  554.         bindMultipleMgs();
  555.         $(".mgname", second).text($(".mgtitle", first).text());
  556.         $(".mgname", second).click(function () {
  557.             openTab(closestEltData($(this)).data("mgurl"));
  558.         });
  559.         $(".mgname", first).remove();
  560.         second.css("display", "block");
  561.         $(".mgfirstfloatimg img", first).prependTo($(".mgtitlehead", first));
  562.         $(".multiplemgs", first).remove();
  563.     }
  564.     second.removeClass("next");
  565.     first.addClass("next");
  566. }
  567.  
  568. //Remove the manga parent (whithin a group or not)
  569. function removeMangaParent(elt) {
  570.     if (isInGroup(elt)) {
  571.         //Manga to remove is in a group
  572.         if (nbOfGroup(elt) == 1) {
  573.             //Only one manga remaining in group --> delete the group
  574.             elt.closest(".manga").toggle("blind", {}, 500, function () {
  575.                 $(this).remove();
  576.                 firstLastMg();
  577.             });
  578.         } else {
  579.             if (isInFirstOfGroup(elt)) {
  580.                 //Manga to remove is the first in the group --> Switch header
  581.                 var first = closestEltData(elt);
  582.                 var second = getSecondElementOfGroup(elt);
  583.                 switchHeader(first, second);
  584.                 if (!second.hasClass("new") && second.closest(".manga").hasClass("new")) {
  585.                     second.closest(".manga").removeClass("new");
  586.                     moveMangaParent($(".mgtitle", second));
  587.                 }
  588.             }
  589.             //Remove plus button... when there is only two mangas in a group and one is removed...
  590.             if (nbOfGroup(elt) == 2) {
  591.                 var stayingElt = closestEltData($(".mgtitleheadpics", elt.closest(".manga")));
  592.                 if (isList()) {
  593.                     $(".mglist img", stayingElt).prependTo($(".mgtitlehead", stayingElt));
  594.                 } else {
  595.                     $(".mgfirstfloatimg img", stayingElt).prependTo($(".mgtitlehead", stayingElt));
  596.                 }
  597.                 $(".multiplemgs", stayingElt).remove();
  598.                 $(".mgtitleheadpics", stayingElt).remove();
  599.             }
  600.             //Remove manga element
  601.             if (isList()) {
  602.                 var _mg = elt.closest(".manga");
  603.                 updateProgression(_mg);
  604.                 closestEltData(elt).remove();
  605.                 firstLastMg();
  606.             } else {
  607.                 closestEltData(elt).toggle("blind", {}, 500, function () {
  608.                     var _mg = $(this).closest(".manga");
  609.                     updateProgression(_mg);
  610.                     $(this).remove();
  611.                     firstLastMg();
  612.                 });
  613.             }
  614.         }
  615.     } else {
  616.         //Manga to remove is single
  617.         closestEltData(elt).toggle("blind", {}, 500, function () {
  618.             $(this).remove();
  619.             firstLastMg();
  620.         });
  621.     }
  622. }
  623.  
  624. //Moves manga parent a its place...
  625. function moveMangaParent(elt) {
  626.     var eltAfter = findPlaceAfter(elt);
  627.     var toMove = elt.closest(".manga");
  628.     if (eltAfter == null) {
  629.         //Move end
  630.         toMove.toggle("blind", {}, 250, function () {
  631.             toMove.appendTo($("#main"));
  632.             toMove.toggle("blind", {}, 250);
  633.             firstLastMg();
  634.         });
  635.     } else {
  636.         //Move before eltAfter
  637.         toMove.toggle("blind", {}, 250, function () {
  638.             eltAfter.before(toMove);
  639.             toMove.toggle("blind", {}, 250);
  640.             firstLastMg();
  641.         });
  642.     }
  643. }
  644.  
  645. //Moves manga parent a its place...
  646. function moveMangaParentNew(elt) {
  647.     var eltAfter = findPlaceAfterNew(elt);
  648.     var toMove = elt.closest(".manga");
  649.     if (eltAfter == null) {
  650.         //Move end
  651.         toMove.toggle("blind", {}, 250, function () {
  652.             toMove.appendTo($("#main"));
  653.             toMove.toggle("blind", {}, 250);
  654.             firstLastMg();
  655.         });
  656.     } else {
  657.         //Move before eltAfter
  658.         toMove.toggle("blind", {}, 250, function () {
  659.             eltAfter.before(toMove);
  660.             toMove.toggle("blind", {}, 250);
  661.             firstLastMg();
  662.         });
  663.     }
  664. }
  665.  
  666. //Moves manga element a its place in a group...
  667. function moveMangaElement(elt) {
  668.     var eltAfter = null;
  669.     var toMove;
  670.     var isplaceOk = true;
  671.     //Get element to move and element which will be after
  672.     if (isList()) {
  673.         if ($(".mgline:not(.new)", elt.closest(".manga")).size() > 1) {
  674.             eltAfter = $($(".mgline:not(.new)", elt.closest(".manga"))[1]);
  675.         }
  676.         toMove = elt.closest(".mgline");
  677.     } else {
  678.         if ($(".mgelt:not(.new)", elt.closest(".manga")).size() > 1) {
  679.             eltAfter = $($(".mgelt:not(.new)", elt.closest(".manga"))[1]);
  680.         }
  681.         toMove = elt.closest(".mgelt");
  682.     }
  683.     //Check if element must move
  684.     if (closestEltData(toMove).next().is(".new") || closestEltData(toMove).is(":last")) {
  685.         isplaceOk = false;
  686.     }
  687.  
  688.     if (!isplaceOk) {
  689.         //If first to move, switch headers and keep visibility
  690.         if (isInFirstOfGroup(elt)) {
  691.             var first = closestEltData(elt);
  692.             var second = getSecondElementOfGroup(elt);
  693.             var wasVisible = second.is(":visible");
  694.             switchHeader(first, second);
  695.             if (!wasVisible) {
  696.                 first.toggle();
  697.             }
  698.         }
  699.         //Move element
  700.         if (isList()) {
  701.             if (eltAfter == null) {
  702.                 //Move end
  703.                 $(toMove).appendTo($(".mgtable", elt.closest(".manga")));
  704.             } else {
  705.                 //Move before eltAfter
  706.                 eltAfter.before($(toMove));
  707.             }
  708.         } else {
  709.             if (eltAfter == null) {
  710.                 //Move end
  711.                 toMove.toggle("blind", {}, 250, function () {
  712.                     $(".mgelt:last", elt.closest(".manga")).after($(this));
  713.                     $(this).toggle("blind", {}, 250);
  714.                 });
  715.             } else {
  716.                 //Move before eltAfter
  717.                 toMove.toggle("blind", {}, 250, function () {
  718.                     eltAfter.before($(this));
  719.                     $(this).toggle("blind", {}, 250);
  720.                 });
  721.             }
  722.         }
  723.     }
  724. }
  725.  
  726. //Returns the next element of the supposed place of the manga parent of elt (null if last)
  727. function findPlaceAfter(elt) {
  728.     var tit = $(".mgname", elt.closest(".manga")).text();
  729.     tit = formatMgName(tit.trim());
  730.     var eltNext = null;
  731.     $(".manga:not(.new)").each(function (index) {
  732.         if (eltNext == null) {
  733.             var titTmp = $(".mgname", $(this)).text();
  734.             titTmp = formatMgName(titTmp);
  735.             if (titTmp > tit) {
  736.                 eltNext = $(this);
  737.             }
  738.         }
  739.     });
  740.     return eltNext;
  741. }
  742.  
  743. //Returns the next element of the supposed place of the manga new parent of elt (null if last)
  744. function findPlaceAfterNew(elt) {
  745.     var tit = $(".mgname", elt.closest(".manga")).text();
  746.     tit = formatMgName(tit);
  747.     var eltNext = null;
  748.     $(".manga.new").each(function (index) {
  749.         if (eltNext == null) {
  750.             var titTmp = $(".mgname", $(this)).text();
  751.             titTmp = formatMgName(titTmp);
  752.             if (titTmp > tit) {
  753.                 eltNext = $(this);
  754.             }
  755.         }
  756.     });
  757.     if (eltNext == null) {
  758.         if ($(".manga:not(.new)").size() > 0) {
  759.             eltNext = $(".manga:not(.new):first");
  760.         }
  761.     }
  762.     return eltNext;
  763. }
  764. //Set information about manga on the main manga element
  765. function setData(elt, mg) {
  766.     elt.data("mgname", mg.name);
  767.     elt.data("mgurl", mg.url);
  768.     elt.data("mgmirror", mg.mirror);
  769.     elt.data("mgplay", mg.lastChapterReadURL);
  770.     if (mg.listChaps.length > 0) {
  771.         elt.data("mglatesturl", mg.listChaps[0][1]);
  772.     } else {
  773.         elt.data("mglatesturl", "");
  774.     }
  775.     if (mg.listChaps.length == 1) {
  776.         elt.data("mgoneshot", true);
  777.     } else {
  778.         elt.data("mgoneshot", false);
  779.     }
  780. }
  781.  
  782. //Create a manga entry in list mode
  783. function createMangaEntryList(mangas, where) {
  784.     var isRead = false;
  785.     var isUpdate = true;
  786.  
  787.     if (mangas.length) {
  788.         $.each(mangas, function (index, val) {
  789.             if (val.read == 1) {
  790.                 isRead = true;
  791.             }
  792.             if (val.update == 0) {
  793.                 isUpdate = false;
  794.             }
  795.         });
  796.     } else {
  797.         if (mangas.read == 1) isRead = true;
  798.         if (mangas.update == 0) isUpdate = false;
  799.     }
  800.  
  801.     if (mangas.length) {
  802.         //Multiple entries
  803.         var mg = $("<div class='manga'><div class='mgtable'></div></div>");
  804.         var line = "<div class='mgline'><div class='mgtitle'><div class='mgtitlehead'><img src='img/plus.png' class='multiplemgs' /><span class='mgname'></span></div><div class='mgtitleheadpics'><img src='img/eyes.png' class='actreadall' title='Mark all manga from this group as read' /><img src='img/cancel.png' class='actdeleteall' title='Delete all manga from this group' /></div></div><div class='mglist'><img src='' class='mgmirroricon' /><span class='custom-select'><select></select></span></div><div class='mgactions'></div></div>";
  805.         var linenext = "<div class='mgline next' style='display:none'><div class='mgtitle'></div><div class='mglist'><img src='' class='mgmirroricon' /><span class='custom-select'><select></select></span></div><div class='mgactions'></div></div>";
  806.  
  807.         $.each(mangas, function (index, val) {
  808.             var mgunit;
  809.             if (index == 0) {
  810.                 mgunit = $(line);
  811.             } else {
  812.                 mgunit = $(linenext);
  813.             }
  814.             mgunit.appendTo($(".mgtable", mg));
  815.             setData(mgunit, val);
  816.  
  817.             if (isRead) {
  818.                 if (index == 0) {
  819.                     mg.addClass("read");
  820.                 }
  821.                 mgunit.addClass("read");
  822.             } else {
  823.                 if (isNew(val)) {
  824.                     if (index == 0) {
  825.                         mg.addClass("new");
  826.                     }
  827.                     mgunit.addClass("new");
  828.                 }
  829.             }
  830.             if (!isUpdate) {
  831.                 if (index == 0) {
  832.                     mg.addClass("stopupdate");
  833.                 }
  834.                 //mgunit.addClass("stopupdate");
  835.             }
  836.  
  837.             var img = $(".mgmirroricon", mgunit);
  838.             var mir = getMangaMirror(val.mirror);
  839.             if (mir != null) {
  840.                 img.attr("src", mir.mirrorIcon);
  841.             } else {
  842.                 img.attr("src", chrome.extension.getURL("img/unknown.png"));
  843.             }
  844.             img.attr("title", val.mirror);
  845.             img.click(function () {
  846.                 openTab(closestEltData($(this)).data("mgurl"));
  847.             });
  848.  
  849.             $(".mgname", mgunit).text(val.name);
  850.             $(".mgname", mgunit).click(function () {
  851.                 openTab(closestEltData($(this)).data("mgurl"));
  852.             });
  853.  
  854.             var sel = $(".mglist select", mgunit);
  855.             fillChapters(val, sel);
  856.  
  857.  
  858.             //Fill actions
  859.             fillActions(val, $(".mgactions", mgunit), (index == 0));
  860.         });
  861.         if (!mg.hasClass("new")) {
  862.             $(".actreadall", mg).remove();
  863.         }
  864.         //Last chap update
  865.         addLastUpdate(mangas, $(".mgtitlehead", mg), $(".mgname", mg));
  866.  
  867.         //Add others
  868.         fillOthers(mangas, mg);
  869.         if (!isMangaDisplayable(mg)) {
  870.             mg.hide();
  871.         }
  872.         mg.appendTo(where);
  873.     } else {
  874.         //Simple entry
  875.         var mg = $("<div class='manga'><div class='mgtable'><div class='mgtitle'><div class='mgtitlehead'><img src='' class='mgmirroricon' /><span class='mgname'></span></div></div><div class='mglist'><span class='custom-select'><select></select></span></div><div class='mgactions'></div></div></div>");
  876.         setData(mg, mangas);
  877.  
  878.         if (isRead) {
  879.             mg.addClass("read");
  880.         } else {
  881.             if (isNew(mangas)) {
  882.                 mg.addClass("new");
  883.             }
  884.         }
  885.         if (!isUpdate) {
  886.             mg.addClass("stopupdate");
  887.         }
  888.         var img = $(".mgmirroricon", mg);
  889.         var mir = getMangaMirror(mangas.mirror);
  890.         if (mir != null) {
  891.             img.attr("src", mir.mirrorIcon);
  892.         } else {
  893.             img.attr("src", chrome.extension.getURL("img/unknown.png"));
  894.         }
  895.         img.attr("title", mangas.mirror);
  896.  
  897.         $(".mgname", mg).text(mangas.name);
  898.         $(".mgname", mg).click(function () {
  899.             openTab(closestEltData($(this)).data("mgurl"));
  900.         });
  901.  
  902.         var sel = $(".mglist select", mg);
  903.         fillChapters(mangas, sel);
  904.  
  905.         //Last chap update
  906.         addLastUpdate(mangas, $(".mgtitlehead", mg), $(".mgname", mg));
  907.  
  908.         //Fill actions
  909.         fillActions(mangas, $(".mgactions", mg), true);
  910.         //Add others
  911.         fillOthers(mangas, mg);
  912.         if (!isMangaDisplayable(mg)) {
  913.             mg.hide();
  914.         }
  915.         mg.appendTo(where);
  916.     }
  917. }
  918. //Create a manga entry in block mode
  919. function createMangaEntryBlock(mangas, where) {
  920.     var isRead = false;
  921.     var isUpdate = true;
  922.  
  923.     if (mangas.length) {
  924.         $.each(mangas, function (index, val) {
  925.             if (val.read == 1) {
  926.                 isRead = true;
  927.             }
  928.             if (val.update == 0) {
  929.                 isUpdate = false;
  930.             }
  931.         });
  932.     } else {
  933.         if (mangas.read == 1) isRead = true;
  934.         if (mangas.update == 0) isUpdate = false;
  935.     }
  936.  
  937.     if (mangas.length) {
  938.         //Multiple entries
  939.         var mg = $("<div class='manga'></div>");
  940.         var line = "<div class='mgelt'><div class='mgactions'></div><div class='mgtitle'><div class='mgtitlehead'><img src='img/plus.png' class='multiplemgs' /><span class='mgname'></span></div><div class='mgtitleheadpics'><img src='img/eyes.png' class='actreadall' title='Mark all manga from this group as read' /><img src='img/cancel.png' class='actdeleteall' title='Delete all manga from this group' /></div></div><div class='mgfirstfloatimg'><img src='' class='mgmirroricon'/></div><div class='mgtable'><div class='mgline'><div class='label'>Latest chapter read :</div><div class='mglist'><span class='value latestread'></span></div></div><div class='mgline'><div class='label'>Latest chapter published :</div><div class='mglist'><span class='value latestpub'></span></div></div><div class='mgline'><div class='label'>Chapters :</div><div class='mglist'><span class='custom-select'><select></select></span></div></div></div></div>";
  941.         var linenext = "<div class='mgelt next' style='display: none'><div class='mgactions'></div><div class='mgtitle'><div class='mgtitlehead'><img src='' class='mgmirroricon' /></div></div><div class='mgtable'><div class='mgline'><div class='label'>Latest chapter read :</div><div class='mglist'><span class='value latestread'></span></div></div><div class='mgline'><div class='label'>Latest chapter published :</div><div class='mglist'><span class='value latestpub'></span></div></div><div class='mgline'><div class='label'>Chapters :</div><div class='mglist'><span class='custom-select'><select></select></span></div></div></div></div>";
  942.  
  943.         $.each(mangas, function (index, val) {
  944.             var mgunit;
  945.             if (index == 0) {
  946.                 mgunit = $(line);
  947.             } else {
  948.                 mgunit = $(linenext);
  949.             }
  950.             mgunit.appendTo(mg);
  951.             setData(mgunit, val);
  952.  
  953.             if (isRead) {
  954.                 if (index == 0) {
  955.                     mg.addClass("read");
  956.                 }
  957.                 mgunit.addClass("read");
  958.             } else {
  959.                 if (isNew(val)) {
  960.                     if (index == 0) {
  961.                         mg.addClass("new");
  962.                     }
  963.                     mgunit.addClass("new");
  964.                 }
  965.             }
  966.             if (!isUpdate) {
  967.                 if (index == 0) {
  968.                     mg.addClass("stopupdate");
  969.                 }
  970.                 //mgunit.addClass("stopupdate");
  971.             }
  972.  
  973.             var img = $(".mgmirroricon", mgunit);
  974.             var mir = getMangaMirror(val.mirror);
  975.             if (mir != null) {
  976.                 img.attr("src", mir.mirrorIcon);
  977.             } else {
  978.                 img.attr("src", chrome.extension.getURL("img/unknown.png"));
  979.             }
  980.             img.attr("title", val.mirror);
  981.             img.click(function () {
  982.                 openTab(closestEltData($(this)).data("mgurl"));
  983.             });
  984.  
  985.             $(".mgname", mgunit).text(val.name);
  986.             $(".mgname", mgunit).click(function () {
  987.                 openTab(closestEltData($(this)).data("mgurl"));
  988.             });
  989.  
  990.             if (val.listChaps.length > 0) {
  991.                 $.each(val.listChaps, function (index, valch) {
  992.                     if (valch[1] == val.lastChapterReadURL) {
  993.                         $(".latestread", mgunit).text(valch[0]);
  994.                     }
  995.                 });
  996.             }
  997.             $(".latestread", mgunit).click(function () {
  998.                 openTab(closestEltData($(this)).data("mgplay"));
  999.             });
  1000.             if (val.listChaps != undefined && val.listChaps.length > 0) {
  1001.                 $(".latestpub", mgunit).text(val.listChaps[0][0]);
  1002.                 $(".latestpub", mgunit).click(function () {
  1003.                     openTab(closestEltData($(this)).data("mglatesturl"));
  1004.                 });
  1005.             }
  1006.  
  1007.             var sel = $(".mglist select", mgunit);
  1008.             fillChapters(val, sel);
  1009.  
  1010.             //Fill actions
  1011.             fillActions(val, $(".mgactions", mgunit), (index == 0));
  1012.         });
  1013.         if (!mg.hasClass("new")) {
  1014.             $(".actreadall", mg).remove();
  1015.         }
  1016.  
  1017.         //Last chap update
  1018.         addLastUpdate(mangas, $(".mgtitlehead", mg), $(".mgname", mg));
  1019.  
  1020.         //Add others
  1021.         fillOthers(mangas, mg);
  1022.         if (!isMangaDisplayable(mg)) {
  1023.             mg.hide();
  1024.         }
  1025.         mg.appendTo(where);
  1026.     } else {
  1027.         //Simple entry
  1028.         var mg = $("<div class='manga'><div class='mgactions'></div><div class='mgtitle'><div class='mgtitlehead'><img src='' class='mgmirroricon' /><span class='mgname'></span></div></div><div class='mgtable'><div class='mgline'><div class='label'>Latest chapter read :</div><div class='mglist'><span class='value latestread'></span></div></div><div class='mgline'><div class='label'>Latest chapter published :</div><div class='mglist'><span class='value latestpub'></span></div></div><div class='mgline'><div class='label'>Chapters :</div><div class='mglist'><span class='custom-select'><select></select></span></div></div></div></div>");
  1029.         setData(mg, mangas);
  1030.  
  1031.         if (isRead) {
  1032.             mg.addClass("read");
  1033.         } else {
  1034.             if (isNew(mangas)) {
  1035.                 mg.addClass("new");
  1036.             }
  1037.         }
  1038.         if (!isUpdate) {
  1039.             mg.addClass("stopupdate");
  1040.         }
  1041.  
  1042.         var img = $(".mgmirroricon", mg);
  1043.         var mir = getMangaMirror(mangas.mirror);
  1044.         if (mir != null) {
  1045.             img.attr("src", mir.mirrorIcon);
  1046.         } else {
  1047.             img.attr("src", chrome.extension.getURL("img/unknown.png"));
  1048.         }
  1049.         img.attr("title", mangas.mirror);
  1050.  
  1051.         $(".mgname", mg).text(mangas.name);
  1052.         $(".mgname", mg).click(function () {
  1053.             openTab(closestEltData($(this)).data("mgurl"));
  1054.         });
  1055.  
  1056.         if (mangas.listChaps.length > 0) {
  1057.             $.each(mangas.listChaps, function (index, val) {
  1058.                 if (val[1] == mangas.lastChapterReadURL) {
  1059.                     $(".latestread", mg).text(val[0]);
  1060.                 }
  1061.             });
  1062.         }
  1063.         $(".latestread", mg).click(function () {
  1064.             openTab(closestEltData($(this)).data("mgplay"));
  1065.         });
  1066.         if (mangas.listChaps.length > 0) {
  1067.             $(".latestpub", mg).text(mangas.listChaps[0][0]);
  1068.             $(".latestpub", mg).click(function () {
  1069.                 openTab(closestEltData($(this)).data("mglatesturl"));
  1070.             });
  1071.         }
  1072.  
  1073.         var sel = $(".mglist select", mg);
  1074.         fillChapters(mangas, sel);
  1075.  
  1076.         //Last chap update
  1077.         addLastUpdate(mangas, $(".mgtitlehead", mg), $(".mgname", mg));
  1078.  
  1079.         //Fill actions
  1080.         fillActions(mangas, $(".mgactions", mg), true);
  1081.  
  1082.         //Add others
  1083.         fillOthers(mangas, mg);
  1084.         if (!isMangaDisplayable(mg)) {
  1085.             mg.hide();
  1086.         }
  1087.         mg.appendTo(where);
  1088.     }
  1089. }
  1090. //Create a manga entry
  1091. function createMangaEntry(mangas, where) {
  1092.     if (parameters.popupMode == 1) {
  1093.         createMangaEntryBlock(mangas, where);
  1094.     } else {
  1095.         createMangaEntryList(mangas, where);
  1096.     }
  1097. }
  1098.  
  1099. //Sort a list of manga (or group of mangas) by new and then by name
  1100. function sortByNewShortName(lst) {
  1101.     lst.sort(function (aG, bG) {
  1102.         var a, b;
  1103.         if (aG.length) {
  1104.             a = aG[0];
  1105.         } else {
  1106.             a = aG;
  1107.         }
  1108.         if (bG.length) {
  1109.             b = bG[0];
  1110.         } else {
  1111.             b = bG;
  1112.         }
  1113.  
  1114.         var isNewA = isNew(a);
  1115.         var isNewB = isNew(b);
  1116.  
  1117.         if (isNewA && !isNewB) return -1;
  1118.         if (!isNewA && isNewB) return 1;
  1119.  
  1120.         if (!a.shortName) a.shortName = formatMgName(a.name);
  1121.         if (!b.shortName) b.shortName = formatMgName(b.name);
  1122.  
  1123.         if (a.shortName == b.shortName) {
  1124.             if (a.mirror == b.mirror) return 0;
  1125.             else if (a.mirror > b.mirror) return 1;
  1126.             else return -1;
  1127.         } else {
  1128.             if (a.shortName > b.shortName) return 1;
  1129.             else return -1;
  1130.         }
  1131.     });
  1132. }
  1133. //Sort a list of manga by name
  1134. function sortByShortName(lst) {
  1135.     lst.sort(function (a, b) {
  1136.         if (!a.shortName) a.shortName = formatMgName(a.name);
  1137.         if (!b.shortName) b.shortName = formatMgName(b.name);
  1138.  
  1139.         if (a.shortName == b.shortName) {
  1140.             if (a.mirror == b.mirror) return 0;
  1141.             else if (a.mirror > b.mirror) return 1;
  1142.             else return -1;
  1143.         } else {
  1144.             if (a.shortName > b.shortName) return 1;
  1145.             else return -1;
  1146.         }
  1147.     });
  1148. }
  1149. //Sort a list of manga by new and then by mirror name
  1150. function sortByNewMirror(lst) {
  1151.     lst.sort(function (a, b) {
  1152.         var isNewA = isNew(a);
  1153.         var isNewB = isNew(b);
  1154.  
  1155.         if (isNewA && !isNewB) return -1;
  1156.         if (!isNewA && isNewB) return 1;
  1157.  
  1158.         return (a.mirror < b.mirror) ? -1 : ((a.mirror == b.mirror) ? 0 : 1);
  1159.     });
  1160. }
  1161.  
  1162. //Loads the list of mangas...
  1163. function loadMangas() {
  1164.     //Set list mode
  1165.     var main = $("#main");
  1166.     if (parameters.popupMode == 1) {
  1167.         main.addClass("block");
  1168.     } else {
  1169.         main.addClass("list");
  1170.     }
  1171.  
  1172.     if (mangas.length == 0) {
  1173.         $("#nomangas").show();
  1174.         return;
  1175.     } else {
  1176.         $("#nomangas").hide();
  1177.     }
  1178.  
  1179.     //No manga grouping
  1180.     if (parameters.groupmgs == 0) {
  1181.         sortByNewShortName(mangas);
  1182.         $.each(mangas, function (index, val) {
  1183.             try {
  1184.                 createMangaEntry(val, main);
  1185.             } catch (e) {}
  1186.         });
  1187.  
  1188.         //Manga Grouping
  1189.     } else {
  1190.         //Sort by name
  1191.         sortByShortName(mangas);
  1192.  
  1193.         //Build groups
  1194.         var mangasGrps = [];
  1195.         var ancShName;
  1196.         var mgTemp = [];
  1197.         for (var i = 0; i < mangas.length; i++) {
  1198.             if (!(!ancShName || mangas[i].shortName == ancShName)) {
  1199.                 if (mgTemp.length == 1) {
  1200.                     mangasGrps[mangasGrps.length] = mgTemp[0];
  1201.                 } else {
  1202.                     //Sort by new inside group
  1203.                     sortByNewMirror(mgTemp);
  1204.                     var pos = mangasGrps.length;
  1205.                     mangasGrps[pos] = [];
  1206.                     $.each(mgTemp, function (index, val) {
  1207.                         mangasGrps[pos][index] = val;
  1208.                     });
  1209.                 }
  1210.                 mgTemp = [];
  1211.             }
  1212.             mgTemp[mgTemp.length] = mangas[i];
  1213.             ancShName = mangas[i].shortName;
  1214.         }
  1215.  
  1216.         //Treat last group
  1217.         if (mgTemp.length == 1) {
  1218.             mangasGrps[mangasGrps.length] = mgTemp[0];
  1219.         } else {
  1220.             //Sort by new inside group
  1221.             sortByNewMirror(mgTemp);
  1222.             var pos = mangasGrps.length;
  1223.             mangasGrps[pos] = [];
  1224.             $.each(mgTemp, function (index, val) {
  1225.                 mangasGrps[pos][index] = val;
  1226.             });
  1227.         }
  1228.  
  1229.         //Sort group by new
  1230.         sortByNewShortName(mangasGrps);
  1231.  
  1232.         $.each(mangasGrps, function (index, val) {
  1233.             //var starter = (new Date).getTime();
  1234.             try {
  1235.                 createMangaEntry(val, main);
  1236.             } catch (e) {}
  1237.             //var diff = (new Date).getTime() - starter;
  1238.             //console.log(index + " --> " + diff);
  1239.         });
  1240.     }
  1241. }
  1242.  
  1243. //Put first and last class to round them...
  1244. function firstLastMg() {
  1245.     $(".manga:visible").removeClass("first");
  1246.     $(".manga:visible").removeClass("last");
  1247.     $(".manga:visible:first").addClass("first");
  1248.     $(".manga:visible:last").addClass("last");
  1249.     if ($(".manga:visible").size() == 0) {
  1250.         $("#nomangas").show();
  1251.         return;
  1252.     } else {
  1253.         $("#nomangas").hide();
  1254.     }
  1255. }
  1256.  
  1257. function setColor() {
  1258.     parameters = chrome.extension.getBackgroundPage().getParameters()
  1259.     if (parameters.color === 0) {
  1260.         $("body").css("background-color", "white");
  1261.     }
  1262.     if (parameters.color === 1) {
  1263.         $("body").css("background-color", "black");
  1264.         $("#header h3").css("color", "white");
  1265.         $("#nomangas").css("color", "white");
  1266.         $("#firstSearch").css("color", "white");
  1267.         $("#search").css("color", "white");
  1268.  
  1269.     }
  1270.     if (parameters.color === 2) {
  1271.         $("body").css("background-color", "#DDDDDD");
  1272.     }
  1273.     if (parameters.color === 3) {
  1274.         $("body").css("background-color", "#F0DDDD");
  1275.     }
  1276.     if (parameters.color === 4) {
  1277.         $("body").css("background-color", "#EEEEFF");
  1278.     }
  1279. }
  1280.  
  1281. //Main function
  1282. $(function () {
  1283.     var parameters = chrome.extension.getBackgroundPage().getParameters();
  1284.     if (parameters.size == 2) {
  1285.         $("body").addClass("medium");
  1286.     }
  1287.     if (parameters.size == 3) {
  1288.         $("body").addClass("big");
  1289.     }
  1290.     var url = window.location.href;
  1291.     if (url.indexOf("?mode=normal") != -1) {
  1292.         //Change css
  1293.         $("body").children().wrapAll("<div id='tabCont'></div>");
  1294.         $("#tabCont").css("margin-left", "auto");
  1295.         $("#tabCont").css("margin-right", "auto");
  1296.         $("#tabCont").css("max-width", "800px");
  1297.         $("body").css("max-width", "none");
  1298.         $("#search #allres").css("overflow", "hidden");
  1299.         $("#search #allres").css("max-height", "none");
  1300.         //$("#main").css("overflow", "hidden");
  1301.         $("#main").css("max-height", "none");
  1302.         //$("body").css("overflow", "auto");
  1303.         $("#external").hide();
  1304.         $("#header").addClass("externHeader");
  1305.         $("#mangaList").addClass("externMangaList");
  1306.         $("#footer").addClass("externFooter");
  1307.         $("#main").addClass("externMain");
  1308.         $("#footact").addClass("externFootact");
  1309.         $("#search").addClass("externSearch");
  1310.         init();
  1311.     } else {
  1312.         if (parameters.newTab == 0) {
  1313.             init();
  1314.         } else {
  1315.             openTab("/popup.html?mode=normal");
  1316.         }
  1317.     }
  1318. });
  1319.  
  1320. function init() {
  1321.     //Timeout to display popup while loading
  1322.     setTimeout(function () {
  1323.         wssql.init();
  1324.         //console.log(localStorage["mangas"]);
  1325.         //Get settings from background page
  1326.         mirrors = chrome.extension.getBackgroundPage().actMirrors;
  1327.         mangas = chrome.extension.getBackgroundPage().mangaList;
  1328.         bookmarks = chrome.extension.getBackgroundPage().bookmarks;
  1329.  
  1330.         //Set popup color
  1331.         setColor();
  1332.  
  1333.         //Load categories
  1334.         loadCategories();
  1335.         //Load mangas list
  1336.         loadMangas();
  1337.         //Load search tool
  1338.         setTimeout(function () {
  1339.             loadSearch();
  1340.         }, 10);
  1341.  
  1342.         //Round first last manga in list
  1343.         firstLastMg();
  1344.  
  1345.         //Bind categories events
  1346.         bindCategories();
  1347.         displayMangasByCat();
  1348.         saveCategories();
  1349.  
  1350.         //Parameterized top buttons
  1351.         if (!localStorage["versionViewRelease"] || localStorage["versionViewRelease"] != localStorage["version"]) {
  1352.             $("#release").css("display", "inline-block");
  1353.         }
  1354.         if (parameters.dev == 1) {
  1355.             $("#dev").css("display", "inline-block");
  1356.         }
  1357.  
  1358.         //Bind footer actions
  1359.         bindFoot();
  1360.  
  1361.         //Bind action buttons
  1362.         bindActions();
  1363.  
  1364.     }, 5);
  1365. }
  1366.  
  1367. //True if a manga must be displayed regarding selected categories filters
  1368. function isMangaDisplayable(mg) {
  1369.     var isInclude = false;
  1370.     var isExclude = false;
  1371.  
  1372.     var isNew = $(mg).hasClass("new");
  1373.     var isRead = $(mg).hasClass("read");
  1374.     var elts;
  1375.     if (isInGroup($(".mgtitle:first", $(mg)))) {
  1376.         if (isList()) {
  1377.             elts = $(".mgline", $(mg));
  1378.         } else {
  1379.             elts = $(".mgelt", $(mg));
  1380.         }
  1381.     } else {
  1382.         elts = $(mg);
  1383.     }
  1384.     var isOneShot = true;
  1385.     elts.each(function (index) {
  1386.         if (!$(this).data("mgoneshot")) {
  1387.             isOneShot = false;
  1388.         }
  1389.     });
  1390.  
  1391.     //Manage native categories
  1392.     $(".category.native").each(function (index) {
  1393.         if ($(this).text() == "New" && $(this).hasClass("include")) {
  1394.             if (isNew) isInclude = true;
  1395.         }
  1396.         if ($(this).text() == "Read" && $(this).hasClass("include")) {
  1397.             if (!isRead && !isNew) isInclude = true;
  1398.         }
  1399.         if ($(this).text() == "Unread" && $(this).hasClass("include")) {
  1400.             if (isRead || isNew) isInclude = true;
  1401.         }
  1402.         if ($(this).text() == "One Shots" && $(this).hasClass("include")) {
  1403.             if (isOneShot) isInclude = true;
  1404.         }
  1405.         if ($(this).text() == "New" && $(this).hasClass("exclude")) {
  1406.             if (isNew) isExclude = true;
  1407.         }
  1408.         if ($(this).text() == "Read" && $(this).hasClass("exclude")) {
  1409.             if (!isRead && !isNew) isExclude = true;
  1410.         }
  1411.         if ($(this).text() == "Unread" && $(this).hasClass("exclude")) {
  1412.             if (isRead || isNew) isExclude = true;
  1413.         }
  1414.         if ($(this).text() == "One Shots" && $(this).hasClass("exclude")) {
  1415.             if (isOneShot) isExclude = true;
  1416.         }
  1417.     });
  1418.     //Manage user categories;
  1419.     $(".category.user").each(function (index) {
  1420.         var _selfCat = this;
  1421.         var found = false;
  1422.         $(".mginfos .cats .mgcategory", $(mg)).each(function (index) {
  1423.             if ($(this).text() == $(_selfCat).text()) {
  1424.                 //console.log($(_selfCat).text());
  1425.                 found = true;
  1426.             }
  1427.         });
  1428.         if (found) {
  1429.             if ($(this).hasClass("include")) {
  1430.                 isInclude = true;
  1431.             }
  1432.             if ($(this).hasClass("exclude")) {
  1433.                 isExclude = true;
  1434.             }
  1435.         }
  1436.     });
  1437.     if (isInclude && !isExclude) {
  1438.         return true;
  1439.     } else {
  1440.         return false;
  1441.     }
  1442. }
  1443. //Display / Hide mangas by categories
  1444. function displayMangasByCat() {
  1445.     $(".manga").each(function (index) {
  1446.         if (isMangaDisplayable($(this))) {
  1447.             if (!$(this).is(":visible")) {
  1448.                 $(this).toggle("blind", {}, 250);
  1449.             }
  1450.         } else {
  1451.             if ($(this).is(":visible")) {
  1452.                 $(this).toggle("blind", {}, 250);
  1453.             }
  1454.         }
  1455.     });
  1456.  
  1457.     if ($(".manga:visible").size() == 0) {
  1458.         $("#nomangas").show();
  1459.         return;
  1460.     } else {
  1461.         $("#nomangas").hide();
  1462.     }
  1463.  
  1464.     setTimeout(function () {
  1465.         if ($(".manga:visible").size() == 0) {
  1466.             $("#nomangas").show();
  1467.             return;
  1468.         } else {
  1469.             $("#nomangas").hide();
  1470.         }
  1471.     }, 300);
  1472. }
  1473.  
  1474. function dragCatManga(mg, _cat) {
  1475.     if (isInGroup(mg)) {
  1476.         var obj = {
  1477.             action: "addCategories",
  1478.             list: []
  1479.         };
  1480.  
  1481.         if (isList()) {
  1482.             $(".mgline", mg.closest(".manga")).each(function (index) {
  1483.                 obj.list[obj.list.length] = {
  1484.                     url: $(this).data("mgurl"),
  1485.                     cat: $(_cat).text()
  1486.                 };
  1487.             });
  1488.         } else {
  1489.             $(".mgelt", mg.closest(".manga")).each(function (index) {
  1490.                 obj.list[obj.list.length] = {
  1491.                     url: $(this).data("mgurl"),
  1492.                     cat: $(_cat).text()
  1493.                 };
  1494.             });
  1495.         }
  1496.         sendExtRequest(obj, $(_cat), function () {
  1497.             //Add category to manga
  1498.             var isFound = false;
  1499.             $(".mginfos .cats .mgcategory", $(mg).closest(".manga")).each(function (index) {
  1500.                 if ($(this).text() == $(_cat).text()) {
  1501.                     isFound = true;
  1502.                 }
  1503.             });
  1504.             if (!isFound) {
  1505.                 if ($(".mginfos .cats .mgcategory", $(mg).closest(".manga")).size() == 0) {
  1506.                     $(".mginfos .cats", $(mg).closest(".manga")).empty();
  1507.                 }
  1508.                 $("<div class='mgcategory'>" + $(_cat).text() + "<img class='actcatmgdel' src='img/delete10.png' title='Delete this category from this manga' /></div>").appendTo($(".mginfos .cats", $(mg).closest(".manga")));
  1509.                 bindCatsButtons();
  1510.             }
  1511.  
  1512.             //Hide / Display manga
  1513.             if (isMangaDisplayable($(mg).closest(".manga"))) {
  1514.                 if (!$(mg).closest(".manga").is(":visible")) {
  1515.                     $(mg).closest(".manga").toggle("blind", {}, 250);
  1516.                 }
  1517.             } else {
  1518.                 if ($(mg).closest(".manga").is(":visible")) {
  1519.                     $(mg).closest(".manga").toggle("blind", {}, 250);
  1520.                 }
  1521.             }
  1522.         });
  1523.     } else {
  1524.         var obj = {
  1525.             action: "addCategory",
  1526.             cat: $(_cat).text(),
  1527.             url: mg.closest(".manga").data("mgurl")
  1528.         };
  1529.         sendExtRequest(obj, $(_cat), function () {
  1530.             //Add category to manga
  1531.             var isFound = false;
  1532.             $(".mginfos .cats .mgcategory", $(mg).closest(".manga")).each(function (index) {
  1533.                 if ($(this).text() == $(_cat).text()) {
  1534.                     isFound = true;
  1535.                 }
  1536.             });
  1537.             if (!isFound) {
  1538.                 if ($(".mginfos .cats .mgcategory", $(mg).closest(".manga")).size() == 0) {
  1539.                     $(".mginfos .cats", $(mg).closest(".manga")).empty();
  1540.                 }
  1541.                 $("<div class='mgcategory'>" + $(_cat).text() + "<img class='actcatmgdel' src='img/delete10.png' title='Delete this category from this manga' /></div>").appendTo($(".mginfos .cats", $(mg).closest(".manga")));
  1542.                 bindCatsButtons();
  1543.             }
  1544.  
  1545.             //Hide / Display manga
  1546.             if (isMangaDisplayable($(mg).closest(".manga"))) {
  1547.                 if (!$(mg).closest(".manga").is(":visible")) {
  1548.                     $(mg).closest(".manga").toggle("blind", {}, 250);
  1549.                 }
  1550.             } else {
  1551.                 if ($(mg).closest(".manga").is(":visible")) {
  1552.                     $(mg).closest(".manga").toggle("blind", {}, 250);
  1553.                 }
  1554.             }
  1555.         });
  1556.     }
  1557. }
  1558.  
  1559. //Bind categories actions
  1560. function bindCategories() {
  1561.     $(".category.include").each(function (ind) {
  1562.         $(this).attr("title", "All mangas in category " + $(this).text() + " are included in the list.");
  1563.     });
  1564.     $(".category.exclude").each(function (ind) {
  1565.         $(this).attr("title", "All mangas in category " + $(this).text() + " are excluded from the list.");
  1566.     });
  1567.     $(".category:not(.addcategory):not(.newcat):not(.include):not(.exclude)").each(function (ind) {
  1568.         $(this).attr("title", "Click here to exlude / include mangas from this category.");
  1569.     });
  1570.  
  1571.     /*$("#cats").sortable({placeholder: 'category empty', dropOnEmpty: true});*/
  1572.     $(".category:not(.addcategory)").unbind();
  1573.     $(".category:not(.addcategory)").click(function () {
  1574.         if ($(this).hasClass("include")) {
  1575.             $(this).removeClass("include");
  1576.             $(this).addClass("exclude");
  1577.             $(this).attr("title", "All mangas in category " + $(this).text() + " are excluded from the list.");
  1578.         } else if ($(this).hasClass("exclude")) {
  1579.             $(this).removeClass("include");
  1580.             $(this).removeClass("exclude");
  1581.             $(this).attr("title", "Click here to exlude / include mangas from this category.");
  1582.         } else {
  1583.             $(this).addClass("include");
  1584.             $(this).removeClass("exclude");
  1585.             $(this).attr("title", "All mangas in category " + $(this).text() + " are included in the list.");
  1586.         }
  1587.         displayMangasByCat();
  1588.         saveCategories();
  1589.     });
  1590.  
  1591.     $(".addcategory").unbind();
  1592.     $(".addcategory").click(function () {
  1593.         var newCat = $("<li class='category newcat'><input type='text' value='New Category'/></li>");
  1594.         $(this).before(newCat);
  1595.         $("input", newCat).focus();
  1596.         $("input", newCat).keydown(function (event) {
  1597.             if (event.which == 13) {
  1598.                 var _par = $(this).parent();
  1599.                 _par.removeClass("newcat").addClass("user").text($(this).val());
  1600.                 var imgs = $("<img src='img/list10.gif' class='actcatview' title='View only mangas from this category'/><img src='img/edit10.png' class='actcatedit' title='Edit this category'/><img src='img/delete10.png' class='actcatdelete' title='Delete this category'/>");
  1601.                 imgs.appendTo(_par);
  1602.                 bindCatsButtons();
  1603.  
  1604.                 $(this).remove();
  1605.                 bindCategories();
  1606.                 saveCategories();
  1607.             }
  1608.         });
  1609.         $("input", newCat).blur(function () {
  1610.             $(this).parent().remove();
  1611.         });
  1612.     });
  1613.  
  1614.     $(".mgtitlehead").draggable({
  1615.         revert: true,
  1616.         revertDuration: 0,
  1617.         opacity: 0.5,
  1618.         helper: 'clone',
  1619.         handle: 'img',
  1620.         scroll: false
  1621.     });
  1622.  
  1623.     $(".category.user").droppable({
  1624.         accept: '.mgtitlehead',
  1625.         hoverClass: 'drop',
  1626.         tolerance: 'pointer',
  1627.         drop: function (event, ui) {
  1628.             dragCatManga($(ui.draggable), $(this));
  1629.         }
  1630.     });
  1631.  
  1632.     $(".category.user").draggable({
  1633.         revert: true,
  1634.         revertDuration: 0,
  1635.         opacity: 0.5,
  1636.         helper: 'clone',
  1637.         scroll: false
  1638.     });
  1639.     $(".manga").droppable({
  1640.         accept: '.category.user',
  1641.         hoverClass: 'drop',
  1642.         tolerance: 'pointer',
  1643.         drop: function (event, ui) {
  1644.             console.log($(".mgtitlehead:first", $(this)));
  1645.             console.log($(ui.draggable));
  1646.             dragCatManga($(".mgtitlehead:first", $(this)), $(ui.draggable));
  1647.         }
  1648.     });
  1649. }
  1650.  
  1651. //Bind action buttons
  1652. function bindActions() {
  1653.     //Manga List and Search List top buttons
  1654.     $("#mgSearchBtn").unbind();
  1655.     $("#mgSearchBtn").add($("#mgListBtn")).click(function () {
  1656.         if (!$(this).hasClass("checked")) {
  1657.             $("#mgListBtn").toggleClass("checked");
  1658.             $("#mgSearchBtn").toggleClass("checked");
  1659.             $("#mangaList").toggle("blind", {}, 500);
  1660.             $("#search").toggle("blind", {}, 500);
  1661.         }
  1662.     });
  1663.  
  1664.     $("#firstSearch").unbind();
  1665.     $("#firstSearch").click(function () {
  1666.         $("#mgListBtn").removeClass("checked");
  1667.         $("#mgSearchBtn").addClass("checked");
  1668.         $("#mangaList").toggle("blind", {}, 500);
  1669.         $("#search").toggle("blind", {}, 500);
  1670.     });
  1671.  
  1672.     // Buttons top right
  1673.     $("#dev").unbind();
  1674.     $("#dev").click(function () {
  1675.         openTab("lab.html");
  1676.     });
  1677.     $("#searchLnk").unbind();
  1678.     $("#searchLnk").click(function () {
  1679.         openTab("search.html");
  1680.     });
  1681.     $("#bookmarks").unbind();
  1682.     $("#bookmarks").click(function () {
  1683.         openTab("bookmarks.html");
  1684.     });
  1685.     $("#infos").unbind();
  1686.     $("#infos").click(function () {
  1687.         openTab("faq.html");
  1688.     });
  1689.     $("#home").unbind();
  1690.     $("#home").click(function () {
  1691.         chrome.extension.sendRequest({
  1692.             action: "openExtensionMainPage"
  1693.         }, function (response) {});
  1694.     });
  1695.     $("#options").unbind();
  1696.     $("#options").click(function () {
  1697.         openTab("options.html");
  1698.     });
  1699.     $("#release").unbind();
  1700.     $("#release").click(function () {
  1701.         chrome.extension.sendRequest({
  1702.             action: "opentab",
  1703.             url: "/release.html"
  1704.         }, function (response) {
  1705.             localStorage["versionViewRelease"] = localStorage["version"];
  1706.         });
  1707.     });
  1708.  
  1709.     //Show hide sub mangas in a group
  1710.     bindMultipleMgs();
  1711.  
  1712.     //Show / Hide "Others"
  1713.     $(".clipoths").unbind();
  1714.     $(".clipoths").click(function () {
  1715.         if ($(this).attr("src") == chrome.extension.getURL("img/up_der.png")) {
  1716.             $(this).attr("src", chrome.extension.getURL("img/down_der.png"));
  1717.         } else {
  1718.             $(this).attr("src", chrome.extension.getURL("img/up_der.png"));
  1719.         }
  1720.         $(this).closest(".manga").children(".mgothers").each(function (index) {
  1721.             if ($(this).is(":visible") && !$(this).hasClass(".buttons")) {
  1722.                 $(this).toggle("blind", {}, 500);
  1723.             }
  1724.         });
  1725.         $(this).closest(".manga").children(".buttons").toggle("blind", {}, 500);
  1726.     });
  1727.  
  1728.     //Show / Hide delete question
  1729.     $(".deletemg").unbind();
  1730.     $(".deletemg").click(function () {
  1731.         var quest = "Are you sure to delete this manga (" + closestEltData($(this)).data("mgname") + " on " + closestEltData($(this)).data("mgmirror") + ") ?";
  1732.         $("span:first", $(this).closest(".manga").children(".question")).text(quest);
  1733.  
  1734.         $(this).closest(".manga").children(".mgothers").each(function (index) {
  1735.             if ($(this).is(":visible") && !$(this).hasClass(".question")) {
  1736.                 $(this).toggle("blind", {}, 500);
  1737.                 if ($(this).is(".buttons")) {
  1738.                     $(".clipoths", $(this).closest(".manga")).attr("src", chrome.extension.getURL("img/down_der.png"));
  1739.                 }
  1740.             }
  1741.         });
  1742.         $(".yes", $(this).closest(".manga").children(".question")).data("mgsingle", true);
  1743.         $(".yes", $(this).closest(".manga").children(".question")).data("mgurl", closestEltData($(this)).data("mgurl"));
  1744.         $(".yes", $(this).closest(".manga").children(".question")).data("mgmirror", closestEltData($(this)).data("mgmirror"));
  1745.         $(".yes", $(this).closest(".manga").children(".question")).data("mgname", closestEltData($(this)).data("mgname"));
  1746.         $(".yes", $(this).closest(".manga").children(".question")).data("btnDel", $(this));
  1747.         $(this).closest(".manga").children(".question").toggle("blind", {}, 500);
  1748.     });
  1749.     $(".actdeleteall").unbind();
  1750.     $(".actdeleteall").click(function () {
  1751.         var quest = "Are you sure to delete all these manga (" + getFirstElementOfGroup($(this)).data("mgname") + ", " + nbOfGroup($(this)) + " mangas to delete) ?";
  1752.         $("span:first", $(this).closest(".manga").children(".question")).text(quest);
  1753.  
  1754.         $(this).closest(".manga").children(".mgothers").each(function (index) {
  1755.             if ($(this).is(":visible") && !$(this).hasClass(".question")) {
  1756.                 $(this).toggle("blind", {}, 500);
  1757.             }
  1758.         });
  1759.         $(".yes", $(this).closest(".manga").children(".question")).data("mgsingle", false);
  1760.         $(".yes", $(this).closest(".manga").children(".question")).data("btnDel", $(this));
  1761.         $(this).closest(".manga").children(".question").toggle("blind", {}, 500);
  1762.     });
  1763.  
  1764.     // Action buttons
  1765.     $(".actplay").unbind();
  1766.     $(".actplay").click(actionPlay);
  1767.     $(".actback").unbind();
  1768.     $(".actback").click(actionBack);
  1769.     $(".actfor").unbind();
  1770.     $(".actfor").click(actionForward);
  1771.     $(".actend").unbind();
  1772.     $(".actend").click(actionEnd);
  1773.     //Read actions
  1774.     bindRead();
  1775.     //Read All actions
  1776.     bindReadAll();
  1777.  
  1778.     //Yes No question for deleting a manga
  1779.     $(".question .yes").unbind();
  1780.     $(".question .yes").click(function () {
  1781.         if ($(this).data("mgsingle")) {
  1782.             var obj = {
  1783.                 action: "killManga",
  1784.                 url: $(this).data("mgurl"),
  1785.                 name: $(this).data("mgname")
  1786.             };
  1787.             var _self = this;
  1788.             sendExtRequest(obj, $(this), function () {
  1789.                 if ($(_self).data("mgmirror")) {
  1790.                     $(".books select option", $(_self).closest(".manga")).each(function (index) {
  1791.                         if ($(this).data("bmmirror") == $(_self).data("mgmirror")) {
  1792.                             $(this).remove();
  1793.                         }
  1794.                     });
  1795.                     $(".books select optgroup", $(_self).closest(".manga")).each(function (index) {
  1796.                         if ($(this).is(":empty")) {
  1797.                             $(this).remove();
  1798.                         }
  1799.                     });
  1800.                     if ($(".books select optgroup", $(_self).closest(".manga")).size() == 0) {
  1801.                         $(".books", $(_self).closest(".manga")).html("No bookmarks for this manga");
  1802.                     }
  1803.                 }
  1804.                 removeMangaParent($($(_self).data("btnDel")));
  1805.                 $(_self).closest(".manga").children(".question").toggle("blind", {}, 500);
  1806.             });
  1807.         } else {
  1808.             var obj = {
  1809.                 action: "killMangas",
  1810.                 list: []
  1811.             };
  1812.             if (isList()) {
  1813.                 $(".mgline", $(this).closest(".manga")).each(function (index) {
  1814.                     obj.list[obj.list.length] = {
  1815.                         url: $(this).data("mgurl"),
  1816.                         name: $(this).data("mgname")
  1817.                     };
  1818.                 });
  1819.             } else {
  1820.                 $(".mgelt", $(this).closest(".manga")).each(function (index) {
  1821.                     obj.list[obj.list.length] = {
  1822.                         url: $(this).data("mgurl"),
  1823.                         name: $(this).data("mgname")
  1824.                     };
  1825.                 });
  1826.             }
  1827.             var _self = this;
  1828.             sendExtRequest(obj, $(this), function () {
  1829.                 $(_self).closest(".manga").toggle("blind", {}, 500, function () {
  1830.                     $(this).remove();
  1831.                     firstLastMg();
  1832.                 });
  1833.             });
  1834.         }
  1835.     });
  1836.     $(".question .no").unbind();
  1837.     $(".question .no").click(function () {
  1838.         $(this).closest(".manga").children(".question").toggle("blind", {}, 500);
  1839.     });
  1840.  
  1841.     //Action buttons in sub menu
  1842.     //Search same manga on other sites.
  1843.     $(".actsearchmg").unbind();
  1844.     $(".actsearchmg").click(function () {
  1845.         $("#searchBoxInput").val($(".mgname", $(this).closest(".manga")).text());
  1846.         $("#mgListBtn").toggleClass("checked");
  1847.         $("#mgSearchBtn").toggleClass("checked");
  1848.         $("#mangaList").toggle("blind", {}, 500);
  1849.         $("#search").toggle("blind", {}, 500);
  1850.         search();
  1851.     });
  1852.     /*$(".actviewrandom").click(function() {
  1853.  
  1854. });*/
  1855.     //Reset manga reading
  1856.     $(".actresetreading").unbind();
  1857.     $(".actresetreading").click(function () {
  1858.         var quest = "Are you sure to reset your reading state for this manga (" + closestEltData($(this)).data("mgname") + ") ?";
  1859.         $("span:first", $(this).closest(".manga").children(".questionreset")).text(quest);
  1860.  
  1861.         $(this).closest(".manga").children(".mgothers").each(function (index) {
  1862.             if ($(this).is(":visible") && !$(this).hasClass(".questionreset")) {
  1863.                 $(this).toggle("blind", {}, 500);
  1864.                 if ($(this).is(".buttons")) {
  1865.                     $(".clipoths", $(this).closest(".manga")).attr("src", chrome.extension.getURL("img/down_der.png"));
  1866.                 }
  1867.             }
  1868.         });
  1869.         $(".yes", $(this).closest(".manga").children(".questionreset")).data("btnReset", $(this));
  1870.         $(this).closest(".manga").children(".questionreset").toggle("blind", {}, 500);
  1871.     });
  1872.     //Yes No question for reset reading for a manga
  1873.     $(".questionreset .yes").unbind();
  1874.     $(".questionreset .yes").click(function () {
  1875.         var _btn = $($(this).data("btnReset"));
  1876.         if (!isInGroup(_btn)) {
  1877.             var obj = {
  1878.                 action: "resetManga",
  1879.                 url: closestEltData($(this)).data("mgurl"),
  1880.                 name: closestEltData($(this)).data("mgname")
  1881.             };
  1882.             var _self = this;
  1883.             //console.log(obj);
  1884.             sendExtRequest(obj, $(this), function () {
  1885.                 var isNew = false;
  1886.                 $(".mglist select", $(_self).closest(".manga")).each(function (index) {
  1887.                     closestEltData($(this)).data("mgplay", $("option:last", $(this)).val());
  1888.                     $(this).val($("option:last", $(this)).val());
  1889.                     if ($("option", $(this)).size() > 1) {
  1890.                         isNew = true;
  1891.                         if (!closestEltData($(this)).hasClass("read")) {
  1892.                             closestEltData($(this)).addClass("new");
  1893.                             $(".actblank", closestEltData($(this))).removeClass("actblank").addClass("actread");
  1894.                             $(".actread", closestEltData($(this))).attr("src", chrome.extension.getURL("img/eye.png"));
  1895.                         }
  1896.                     }
  1897.                 });
  1898.                 bindRead();
  1899.  
  1900.                 if (!$(_self).closest(".manga").hasClass("read")) {
  1901.                     if (isNew) {
  1902.                         $(_self).closest(".manga").addClass("new");
  1903.                         moveMangaParentNew($(_self));
  1904.                     }
  1905.                 }
  1906.                 updateProgression($(_self));
  1907.  
  1908.                 $(_self).closest(".manga").children(".questionreset").toggle("blind", {}, 500);
  1909.             });
  1910.         } else {
  1911.             var obj = {
  1912.                 action: "resetMangas",
  1913.                 list: []
  1914.             };
  1915.             if (isList()) {
  1916.                 $(".mgline", $(this).closest(".manga")).each(function (index) {
  1917.                     obj.list[obj.list.length] = {
  1918.                         url: $(this).data("mgurl"),
  1919.                         name: $(this).data("mgname")
  1920.                     };
  1921.                 });
  1922.             } else {
  1923.                 $(".mgelt", $(this).closest(".manga")).each(function (index) {
  1924.                     obj.list[obj.list.length] = {
  1925.                         url: $(this).data("mgurl"),
  1926.                         name: $(this).data("mgname")
  1927.                     };
  1928.                 });
  1929.             }
  1930.             //console.log(obj);
  1931.             var _self = this;
  1932.             sendExtRequest(obj, $(this), function () {
  1933.                 var isNew = false;
  1934.                 $(".mglist select", $(_self).closest(".manga")).each(function (index) {
  1935.                     closestEltData($(this)).data("mgplay", $("option:last", $(this)).val());
  1936.                     $(this).val($("option:last", $(this)).val());
  1937.                     if ($("option", $(this)).size() > 1) {
  1938.                         isNew = true;
  1939.                         if (!closestEltData($(this)).hasClass("read")) {
  1940.                             closestEltData($(this)).addClass("new");
  1941.                             $(".actblank", closestEltData($(this))).removeClass("actblank").addClass("actread");
  1942.                             $(".actread", closestEltData($(this))).attr("src", chrome.extension.getURL("img/eye.png"));
  1943.                         }
  1944.                     }
  1945.                 });
  1946.                 bindRead();
  1947.  
  1948.                 if (!$(_self).closest(".manga").hasClass("read")) {
  1949.                     if (isNew) {
  1950.                         $(_self).closest(".manga").addClass("new");
  1951.                         moveMangaParentNew($(_self));
  1952.                         //add mark all as read button...
  1953.                         $(".mgtitleheadpics", $(_self).closest(".manga")).prepend($("<img src='img/eyes.png' class='actreadall' title='Mark all manga from this group as read' />"));
  1954.                         bindReadAll();
  1955.                     }
  1956.                 }
  1957.                 updateProgression($(_self));
  1958.  
  1959.                 $(_self).closest(".manga").children(".questionreset").toggle("blind", {}, 500);
  1960.             });
  1961.         }
  1962.     });
  1963.     $(".questionreset .no").unbind();
  1964.     $(".questionreset .no").click(function () {
  1965.         $(this).closest(".manga").children(".questionreset").toggle("blind", {}, 500);
  1966.     });
  1967.  
  1968.     //Stop Following updates / Follow updates buttons...
  1969.     $(".actstopupdates").unbind();
  1970.     $(".actstopupdates").click(function () {
  1971.         var readToSend = 1;
  1972.         if ($(this).closest(".manga").is(".read")) {
  1973.             readToSend = 0;
  1974.             $(this).text("Stop following updates");
  1975.         } else {
  1976.             $(this).text("Follow updates");
  1977.         }
  1978.  
  1979.         if (isInGroup($(this))) {
  1980.             var obj = {
  1981.                 action: "markReadTops",
  1982.                 list: []
  1983.             };
  1984.             if (isList()) {
  1985.                 $(".mgline", $(this).closest(".manga")).each(function (index) {
  1986.                     obj.list[obj.list.length] = {
  1987.                         read: readToSend,
  1988.                         url: $(this).data("mgurl")
  1989.                     };
  1990.                 });
  1991.             } else {
  1992.                 $(".mgelt", $(this).closest(".manga")).each(function (index) {
  1993.                     obj.list[obj.list.length] = {
  1994.                         read: readToSend,
  1995.                         url: $(this).data("mgurl")
  1996.                     };
  1997.                 });
  1998.             }
  1999.             var _self = this;
  2000.             sendExtRequest(obj, $(this), function () {
  2001.                 if (readToSend == 0) {
  2002.                     //Remove read class
  2003.                     $(_self).closest(".manga").removeClass("read");
  2004.                     var isNew = false;
  2005.                     if (isList()) {
  2006.                         $(".mgline", $(_self).closest(".manga")).each(function (index) {
  2007.                             $(this).removeClass("read");
  2008.                             if ($(this).data("mglatesturl") != $(this).data("mgplay")) {
  2009.                                 isNew = true;
  2010.                                 $(this).addClass("new");
  2011.                                 //add mark as read button...
  2012.                                 $(".actblank", $(this)).removeClass("actblank").addClass("actread");
  2013.                                 $(".actread", $(this)).attr("src", chrome.extension.getURL("img/eye.png"));
  2014.                                 if ($(this).prev().size() != 0) {
  2015.                                     var wasVisible = $(this).is(":visible");
  2016.                                     var _first = $(".mgline:first", $(_self).closest(".manga"));
  2017.                                     switchHeader(_first, $(this));
  2018.                                     $(this).after(_first);
  2019.                                     if (!wasVisible) {
  2020.                                         _first.hide();
  2021.                                     }
  2022.                                 }
  2023.                             }
  2024.                         });
  2025.                         bindRead();
  2026.                     } else {
  2027.                         $(".mgelt", $(_self).closest(".manga")).each(function (index) {
  2028.                             $(this).removeClass("read");
  2029.                             if ($(this).data("mglatesturl") != $(this).data("mgplay")) {
  2030.                                 isNew = true;
  2031.                                 $(this).addClass("new");
  2032.                                 //add mark as read button...
  2033.                                 $(".actblank", $(this)).removeClass("actblank").addClass("actread");
  2034.                                 $(".actread", $(this)).attr("src", chrome.extension.getURL("img/eye.png"));
  2035.                                 if ($(this).prev().size() != 0) {
  2036.                                     var wasVisible = $(this).is(":visible");
  2037.                                     var _first = $(".mgelt:first", $(_self).closest(".manga"));
  2038.                                     switchHeader(_first, $(this));
  2039.                                     $(this).after(_first);
  2040.                                     if (!wasVisible) {
  2041.                                         _first.hide();
  2042.                                     }
  2043.                                 }
  2044.                             }
  2045.                         });
  2046.                         bindRead();
  2047.                     }
  2048.                     //Set new if needed
  2049.                     if (isNew) {
  2050.                         $(_self).closest(".manga").addClass("new");
  2051.                         //move manga to top if new
  2052.                         moveMangaParentNew($(_self));
  2053.                         //add mark all as read button...
  2054.                         $(".mgtitleheadpics", $(_self).closest(".manga")).prepend($("<img src='img/eyes.png' class='actreadall' title='Mark all manga from this group as read' />"));
  2055.                         bindReadAll();
  2056.                     }
  2057.                 } else {
  2058.                     //remove new if needed
  2059.                     if (isList()) {
  2060.                         $(".mgline", $(_self).closest(".manga")).each(function (index) {
  2061.                             if ($(this).is(".new")) {
  2062.                                 $(this).removeClass("new");
  2063.                                 //remove mark as read button...
  2064.                                 $(".actread", $(this)).attr("src", chrome.extension.getURL("img/blank.png"));
  2065.                                 $(".actread", $(this)).unbind("click");
  2066.                             }
  2067.                             $(this).addClass("read");
  2068.                         });
  2069.                     } else {
  2070.                         $(".mgelt", $(_self).closest(".manga")).each(function (index) {
  2071.                             if ($(this).is(".new")) {
  2072.                                 $(this).removeClass("new");
  2073.                                 //remove mark as read button...
  2074.                                 $(".actread", $(this)).attr("src", chrome.extension.getURL("img/blank.png"));
  2075.                                 $(".actread", $(this)).unbind("click");
  2076.                             }
  2077.                             $(this).addClass("read");
  2078.                         });
  2079.                     }
  2080.                     if ($(_self).closest(".manga").is(".new")) {
  2081.                         $(_self).closest(".manga").removeClass("new");
  2082.                         //move manga to bottom if was new
  2083.                         moveMangaParent($(_self));
  2084.                         //remove mark all as read button...
  2085.                         $(".actreadall", $(_self).closest(".manga")).remove();
  2086.                     }
  2087.                     //add read class
  2088.                     $(_self).closest(".manga").addClass("read");
  2089.                 }
  2090.             });
  2091.         } else {
  2092.             var obj = {
  2093.                 action: "markReadTop",
  2094.                 read: readToSend,
  2095.                 url: closestEltData($(this)).data("mgurl")
  2096.             };
  2097.             var _self = this;
  2098.             sendExtRequest(obj, $(this), function () {
  2099.                 if (readToSend == 0) {
  2100.                     //Remove read class
  2101.                     $(_self).closest(".manga").removeClass("read");
  2102.                     //Set new if needed
  2103.                     if ($(_self).closest(".manga").data("mglatesturl") != $(_self).closest(".manga").data("mgplay")) {
  2104.                         $(_self).closest(".manga").addClass("new");
  2105.                         //move manga to top if new
  2106.                         moveMangaParentNew($(_self));
  2107.                         //add mark as read button...
  2108.                         $(".actread", $(_self).closest(".manga")).attr("src", chrome.extension.getURL("img/eye.png"));
  2109.                         bindRead();
  2110.                     }
  2111.                 } else {
  2112.                     //remove new if needed
  2113.                     if ($(_self).closest(".manga").is(".new")) {
  2114.                         $(_self).closest(".manga").removeClass("new");
  2115.                         //move manga to bottom if was new
  2116.                         moveMangaParent($(_self));
  2117.                         //remove mark as read button...
  2118.                         $(".actread", $(_self).closest(".manga")).attr("src", chrome.extension.getURL("img/blank.png"));
  2119.                         $(".actread", $(_self).closest(".manga")).unbind("click");
  2120.                     }
  2121.                     //add read class
  2122.                     $(_self).closest(".manga").addClass("read");
  2123.                 }
  2124.             });
  2125.         }
  2126.     });
  2127.  
  2128.     //Stop updating / Continue updates button...
  2129.     $(".actstopupdating").unbind();
  2130.     $(".actstopupdating").click(function () {
  2131.         var updateToSend = 0;
  2132.         if ($(this).closest(".manga").is(".stopupdate")) {
  2133.             updateToSend = 1;
  2134.             $(this).text("Stop updating");
  2135.         } else {
  2136.             $(this).text("Continue updates");
  2137.         }
  2138.  
  2139.         if (isInGroup($(this))) {
  2140.             var obj = {
  2141.                 action: "markUpdateTops",
  2142.                 list: []
  2143.             };
  2144.             if (isList()) {
  2145.                 $(".mgline", $(this).closest(".manga")).each(function (index) {
  2146.                     obj.list[obj.list.length] = {
  2147.                         update: updateToSend,
  2148.                         url: $(this).data("mgurl")
  2149.                     };
  2150.                 });
  2151.             } else {
  2152.                 $(".mgelt", $(this).closest(".manga")).each(function (index) {
  2153.                     obj.list[obj.list.length] = {
  2154.                         update: updateToSend,
  2155.                         url: $(this).data("mgurl")
  2156.                     };
  2157.                 });
  2158.             }
  2159.             var _self = this;
  2160.             sendExtRequest(obj, $(this), function () {
  2161.                 if (updateToSend == 0) {
  2162.                     $(_self).closest(".manga").addClass("stopupdate");
  2163.                     /*if (isList()) {
  2164.           $(".mgline", $(_self).closest(".manga")).each(function(index) {
  2165.             $(this).addClass("stopupdate");
  2166.           });
  2167.         } else {
  2168.           $(".mgelt", $(_self).closest(".manga")).each(function(index) {
  2169.             $(this).addClass("stopupdate");
  2170.           });
  2171.         }*/
  2172.                 } else {
  2173.                     $(_self).closest(".manga").removeClass("stopupdate");
  2174.                     /*if (isList()) {
  2175.           $(".mgline", $(_self).closest(".manga")).each(function(index) {
  2176.             $(this).removeClass("stopupdate");
  2177.           });
  2178.         } else {
  2179.           $(".mgelt", $(_self).closest(".manga")).each(function(index) {
  2180.             $(this).removeClass("stopupdate");
  2181.           });
  2182.         }*/
  2183.                 }
  2184.             });
  2185.         } else {
  2186.             var obj = {
  2187.                 action: "markUpdateTop",
  2188.                 update: updateToSend,
  2189.                 url: closestEltData($(this)).data("mgurl")
  2190.             };
  2191.             var _self = this;
  2192.             sendExtRequest(obj, $(this), function () {
  2193.                 if (updateToSend == 0) {
  2194.                     $(_self).closest(".manga").addClass("stopupdate");
  2195.                 } else {
  2196.                     $(_self).closest(".manga").removeClass("stopupdate");
  2197.                 }
  2198.             });
  2199.         }
  2200.     });
  2201. }
  2202.  
  2203. //Bind event on grouped mangas
  2204. function bindMultipleMgs() {
  2205.     //Show hide sub mangas in a group
  2206.     $(".multiplemgs").unbind();
  2207.     $(".multiplemgs").click(function () {
  2208.         if (isList()) {
  2209.             $(".mgline.next", $(this).closest(".manga")).toggle();
  2210.             if ($(".mgline.next:first", $(this).closest(".manga")).is(":visible")) {
  2211.                 $(this).attr("src", chrome.extension.getURL("img/minus.png"));
  2212.             } else {
  2213.                 $(this).attr("src", chrome.extension.getURL("img/plus.png"));
  2214.             }
  2215.         } else {
  2216.             var _self = this;
  2217.             $(".mgelt.next", $(this).closest(".manga")).toggle("blind", {}, 250, function () {
  2218.                 if ($(".mgelt.next:first", $(_self).closest(".manga")).is(":visible")) {
  2219.                     $(_self).attr("src", chrome.extension.getURL("img/minus.png"));
  2220.                 } else {
  2221.                     $(_self).attr("src", chrome.extension.getURL("img/plus.png"));
  2222.                 }
  2223.             });
  2224.         }
  2225.     });
  2226. }
  2227.  
  2228. // bind read button (eye)
  2229. function bindRead() {
  2230.     $(".actread").unbind();
  2231.     $(".actread").click(actionRead);
  2232. }
  2233.  
  2234. // bind read all button (eyes)
  2235. function bindReadAll() {
  2236.     $(".actreadall").unbind();
  2237.     $(".actreadall").click(function () {
  2238.         var obj = {
  2239.             action: "readMangas",
  2240.             list: []
  2241.         };
  2242.         if (isList()) {
  2243.             $(".mgline", $(this).closest(".manga")).each(function (index) {
  2244.                 obj.list[obj.list.length] = {
  2245.                     url: $(this).data("mgurl"),
  2246.                     lastChapterReadURL: $(this).data("mglatesturl")
  2247.                 };
  2248.             });
  2249.         } else {
  2250.             $(".mgelt", $(this).closest(".manga")).each(function (index) {
  2251.                 obj.list[obj.list.length] = {
  2252.                     url: $(this).data("mgurl"),
  2253.                     lastChapterReadURL: $(this).data("mglatesturl")
  2254.                 };
  2255.             });
  2256.         }
  2257.  
  2258.         var _self = this;
  2259.         sendExtRequest(obj, $(this), function () {
  2260.             $(_self).closest(".manga").removeClass("new");
  2261.             $(".actread", $(_self).closest(".manga")).unbind("click");
  2262.             $(".actread", $(_self).closest(".manga")).attr("src", chrome.extension.getURL("img/blank.png"));
  2263.             if (isList()) {
  2264.                 $(".mgline", $(_self).closest(".manga")).removeClass("new");
  2265.             } else {
  2266.                 $(".mgelt", $(_self).closest(".manga")).removeClass("new");
  2267.             }
  2268.  
  2269.             $(".mglist select", $(_self).closest(".manga")).each(function (index) {
  2270.                 closestEltData($(this)).data("mgplay", $("option:first", $(this)).val());
  2271.                 $(this).val($("option:first", $(this)).val());
  2272.             });
  2273.             moveMangaParent($(_self));
  2274.             updateProgression($(_self));
  2275.             $(_self).remove();
  2276.         }, false);
  2277.     });
  2278. }
  2279.  
  2280. //Load categories list
  2281. function loadCategories() {
  2282.     var categs = [];
  2283.     if (localStorage["categoriesStates"] != undefined) {
  2284.         try {
  2285.             var catsStates = JSON.parse(localStorage["categoriesStates"]);
  2286.             $.each(catsStates, function (index, catSt) {
  2287.                 var isfound = false;
  2288.                 $.each(categs, function (index, cat) {
  2289.                     if (catSt.name == cat.name) {
  2290.                         cat.state = catSt.state;
  2291.                         isfound = true;
  2292.                     }
  2293.                 });
  2294.                 if (!isfound) {
  2295.                     if (catSt.type == "user") {
  2296.                         categs[categs.length] = {
  2297.                             name: catSt.name,
  2298.                             state: catSt.state
  2299.                         };
  2300.                     } else {
  2301.                         $(".category.native").each(function (index) {
  2302.                             if ($(this).text() == catSt.name) {
  2303.                                 $(this).removeClass("include");
  2304.                                 $(this).removeClass("exclude");
  2305.                                 $(this).addClass(catSt.state);
  2306.                             }
  2307.                         });
  2308.                     }
  2309.                 }
  2310.             });
  2311.         } catch (e) {
  2312.  
  2313.         }
  2314.     }
  2315.     $.each(mangas, function (index, val) {
  2316.         $.each(val.cats, function (index, catmg) {
  2317.             var isfound = false;
  2318.             $.each(categs, function (index, cat) {
  2319.                 if (catmg == cat.name) {
  2320.                     isfound = true;
  2321.                 }
  2322.             });
  2323.             if (!isfound) {
  2324.                 categs[categs.length] = {
  2325.                     name: catmg,
  2326.                     state: ""
  2327.                 };
  2328.             }
  2329.         });
  2330.     });
  2331.  
  2332.     $.each(categs, function (index, cat) {
  2333.         $(".addcategory").before($("<li class='category user " + cat.state + "'>" + cat.name + "<img src='img/list10.gif' class='actcatview' title='View only mangas from this category'/><img src='img/edit10.png' class='actcatedit' title='Edit this category'/><img src='img/delete10.png' class='actcatdelete' title='Delete this category'/></li>"));
  2334.     });
  2335.     bindCatsButtons();
  2336. }
  2337.  
  2338. //Bind little actions buttons on categories
  2339. function bindCatsButtons() {
  2340.     $(".actcatview").unbind();
  2341.     $(".actcatview").click(function (event) {
  2342.         $(".category:not(.addcategory):not(.newcat)").removeClass("include").removeClass("exclude");
  2343.         $(this).parent().addClass("include");
  2344.         displayMangasByCat();
  2345.         saveCategories();
  2346.         event.stopImmediatePropagation();
  2347.     });
  2348.     $(".actcatedit").unbind();
  2349.     $(".actcatedit").click(function (event) {
  2350.         var _par = $(this).parent();
  2351.         var cat = _par.text();
  2352.         _par.data("anccat", cat);
  2353.         _par.empty();
  2354.         _par.unbind();
  2355.         var inp = $("<input type='text' value='" + cat + "'/>");
  2356.         inp.appendTo(_par);
  2357.         inp.focus();
  2358.         inp.blur(function () {
  2359.             var _par = $(this).parent();
  2360.             _par.text(_par.data("anccat"));
  2361.             var imgs = $("<img src='img/list10.gif' class='actcatview' title='View only mangas from this category'/><img src='img/edit10.png' class='actcatedit' title='Edit this category'/><img src='img/delete10.png' class='actcatdelete' title='Delete this category'/>");
  2362.             imgs.appendTo(_par);
  2363.             bindCatsButtons();
  2364.             $(this).remove();
  2365.             bindCategories();
  2366.         });
  2367.         inp.keydown(function (event) {
  2368.             if (event.which == 13) {
  2369.                 var obj = {
  2370.                     action: "editCategory",
  2371.                     cat: $(this).parent().data("anccat"),
  2372.                     newcat: $(this).val()
  2373.                 };
  2374.                 //console.log(obj);
  2375.                 var _par = $(this).parent();
  2376.                 var _self = this;
  2377.                 sendExtRequest(obj, _par, function () {
  2378.                     var newcat = $(_self).val();
  2379.                     var anccat = $(_par).data("anccat");
  2380.                     _par.text(newcat);
  2381.                     var imgs = $("<img src='img/list10.gif' class='actcatview' title='View only mangas from this category'/><img src='img/edit10.png' class='actcatedit' title='Edit this category'/><img src='img/delete10.png' class='actcatdelete' title='Delete this category'/>");
  2382.                     imgs.appendTo(_par);
  2383.  
  2384.                     $(_self).remove();
  2385.                     $(".mgcategory").each(function (index) {
  2386.                         if ($(this).text() == anccat) {
  2387.                             $(this).text(newcat);
  2388.                             $("<img class='actcatmgdel' src='img/delete10.png' title='Delete this category from this manga' />").appendTo($(this));
  2389.                         }
  2390.                     });
  2391.  
  2392.                     bindCatsButtons();
  2393.                     bindCategories();
  2394.                     saveCategories();
  2395.                 });
  2396.             }
  2397.         });
  2398.         event.stopImmediatePropagation();
  2399.     });
  2400.     $(".actcatdelete").unbind();
  2401.     $(".actcatdelete").click(function () {
  2402.         var catTxt = $(this).parent().text();
  2403.  
  2404.         var nbmgs = 0;
  2405.         $(".mgcategory").each(function (index) {
  2406.             if ($(this).text() == catTxt) nbmgs++;
  2407.         });
  2408.  
  2409.         $(".actdeleteglobcat span").text("Are you sure to delete this category (" + catTxt + ", " + nbmgs + " mangas affected) ?");
  2410.         $(".actdeleteglobcat .yes").data("catdel", catTxt);
  2411.         $(".actdeleteglobcat .yes").data("catbtn", $(this));
  2412.         $(".actdeleteglobcat").toggle("blind", {}, 250);
  2413.         event.stopImmediatePropagation();
  2414.     });
  2415.     $(".actdeleteglobcat .yes").unbind();
  2416.     $(".actdeleteglobcat .yes").click(function () {
  2417.         var catTxt = $(this).data("catdel");
  2418.         var obj = {
  2419.             action: "removeCategory",
  2420.             cat: catTxt
  2421.         };
  2422.         var _btn = $($(this).data("catbtn"));
  2423.         var _par = $(_btn).parent();
  2424.         sendExtRequest(obj, _par, function () {
  2425.             $(".mgcategory").each(function (index) {
  2426.                 if ($(this).text() == catTxt) {
  2427.                     var _mg = $(this).closest(".manga");
  2428.                     $(this).remove();
  2429.                     if ($(".mgcategory", _mg).size() == 0) {
  2430.                         $(".mginfos .cats", _mg).text("No category for this manga");
  2431.                     }
  2432.                 }
  2433.             });
  2434.             _par.remove();
  2435.             displayMangasByCat();
  2436.             saveCategories();
  2437.             $(".actdeleteglobcat").toggle("blind", {}, 250);
  2438.         });
  2439.     });
  2440.     $(".actdeleteglobcat .no").unbind();
  2441.     $(".actdeleteglobcat .no").click(function () {
  2442.         $(".actdeleteglobcat").toggle("blind", {}, 250);
  2443.     });
  2444.  
  2445.     $(".actcatmgdel").unbind();
  2446.     $(".actcatmgdel").click(function (event) {
  2447.         var catToDel = $(this).parent().text();
  2448.         if (isInGroup($(this))) {
  2449.             var obj = {
  2450.                 action: "removeCatMangas",
  2451.                 list: []
  2452.             };
  2453.             if (isList()) {
  2454.                 $(".mgline", $(this).closest(".manga")).each(function (index) {
  2455.                     obj.list[obj.list.length] = {
  2456.                         cat: catToDel,
  2457.                         url: $(this).data("mgurl")
  2458.                     };
  2459.                 });
  2460.             } else {
  2461.                 $(".mgelt", $(this).closest(".manga")).each(function (index) {
  2462.                     obj.list[obj.list.length] = {
  2463.                         cat: catToDel,
  2464.                         url: $(this).data("mgurl")
  2465.                     };
  2466.                 });
  2467.             }
  2468.             var _par = $(this).parent();
  2469.             sendExtRequest(obj, _par, function () {
  2470.                 var _cats = $(".mginfos .cats", $(_par).closest(".manga"));
  2471.                 $(_par).remove();
  2472.                 if ($(".mgcategory", _cats).size() == 0) {
  2473.                     _cats.text("No category for this manga");
  2474.                 }
  2475.                 displayMangasByCat();
  2476.             });
  2477.         } else {
  2478.             var obj = {
  2479.                 action: "removeCatManga",
  2480.                 cat: catToDel,
  2481.                 url: closestEltData($(this)).data("mgurl")
  2482.             };
  2483.             var _par = $(this).parent();
  2484.             sendExtRequest(obj, _par, function () {
  2485.                 var _cats = $(".mginfos .cats", $(_par).closest(".manga"));
  2486.                 $(_par).remove();
  2487.                 if ($(".mgcategory", _cats).size() == 0) {
  2488.                     _cats.text("No category for this manga");
  2489.                 }
  2490.                 displayMangasByCat();
  2491.             });
  2492.         }
  2493.     });
  2494. }
  2495.  
  2496. //Saves current categories
  2497. function saveCategories() {
  2498.     var cats = [];
  2499.     $(".category:not(.addcategory):not(.newcat)").each(function (index) {
  2500.         var cat = {
  2501.             name: $(this).text(),
  2502.             state: "",
  2503.             type: ""
  2504.         };
  2505.         if ($(this).hasClass("user")) {
  2506.             cat.type = "user";
  2507.         } else if ($(this).hasClass("native")) {
  2508.             cat.type = "native";
  2509.         }
  2510.         if ($(this).hasClass("include")) {
  2511.             cat.state = "include";
  2512.         } else if ($(this).hasClass("exclude")) {
  2513.             cat.state = "exclude";
  2514.         }
  2515.         cats[cats.length] = cat;
  2516.     });
  2517.     localStorage["categoriesStates"] = JSON.stringify(cats);
  2518. }
  2519.  
  2520. function bindFoot() {
  2521.     $("#time").click(function () {
  2522.         $(".bottomdiv").each(function (index) {
  2523.             if ($(this).is(":visible") && !$(this).hasClass("timers")) {
  2524.                 $(this).toggle("blind", {}, 500);
  2525.             }
  2526.         });
  2527.         $(".bottomdiv.timers").toggle("blind", {}, 500);
  2528.         var html = "<span>Chapters lists have been updated <b>" + getTimeSince(localStorage["lastChaptersUpdate"]) + "</b></span><div class='button refreshmgchapnow' style='margin-left:5px;'>Refresh</div><br />";
  2529.         html += "<span>Manga lists have been updated <b>" + getTimeSince(localStorage["lastMangasUpdate"]) + "</b></span>";
  2530.         if (parameters.sync == 1) {
  2531.             html += "<br /><span>All Mangas Reader has been sychronized <b>" + getTimeSince(parameters.lastsync) + "</b></span>";
  2532.         }
  2533.         $(".bottomdiv.timers").html(html);
  2534.         $(".refreshmgchapnow").click(function () {
  2535.             $(this).remove();
  2536.             var html = "<span>Chapters lists have been updated <b>" + getTimeSince(localStorage["lastChaptersUpdate"]) + "</b>. Chapters refresh has been launched, you must reload the popup to see changes.</span><br />";
  2537.             html += "<span>Manga lists have been updated <b>" + getTimeSince(localStorage["lastMangasUpdate"]) + "</b></span>";
  2538.             if (parameters.sync == 1) {
  2539.                 html += "<br /><span>All Mangas Reader has been sychronized <b>" + getTimeSince(parameters.lastsync) + "</b></span>";
  2540.             }
  2541.             $(".bottomdiv.timers").html(html);
  2542.  
  2543.             chrome.extension.getBackgroundPage().refreshAllLasts(true, true);
  2544.  
  2545.             var html = "<span>Chapters lists have been updated <b>" + getTimeSince(localStorage["lastChaptersUpdate"]) + "</b>. Chapters refresh has been launched, you must reload the popup to see changes.</span><br />";
  2546.             html += "<span>Manga lists have been updated <b>" + getTimeSince(localStorage["lastMangasUpdate"]) + "</b></span>";
  2547.             if (parameters.sync == 1) {
  2548.                 html += "<br /><span>All Mangas Reader has been sychronized <b>" + getTimeSince(parameters.lastsync) + "</b></span>";
  2549.             }
  2550.             $(".bottomdiv.timers").html(html);
  2551.  
  2552.         });
  2553.     });
  2554.     $("#donate").click(function () {
  2555.         $(".bottomdiv").each(function (index) {
  2556.             if ($(this).is(":visible") && !$(this).hasClass("donate")) {
  2557.                 $(this).toggle("blind", {}, 500);
  2558.             }
  2559.         });
  2560.         $(".bottomdiv.donate").toggle("blind", {}, 500);
  2561.     });
  2562.     $("#paypalus").click(function () {
  2563.         openTab("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MPJ2DWQP67FHJ");
  2564.     });
  2565.     $("#paypaleuro").click(function () {
  2566.         openTab("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PTFDEMDFNKQAG");
  2567.     });
  2568.     $("#fblike").click(function () {
  2569.         openTab("http://www.facebook.com/pages/All-Mangas-Reader/214541438575022");
  2570.     });
  2571.     $("#gplike").click(function () {
  2572.         openTab("https://plus.google.com/112854960469526703676/");
  2573.     });
  2574.     $("#external").click(function () {
  2575.         openTab("/popup.html?mode=normal");
  2576.     });
  2577.     $("#forum").click(function () {
  2578.         openTab("http://www.allmangasreader.com/forum/");
  2579.     });
  2580.     $("#impexp").click(function () {
  2581.         openTab("importexport.html");
  2582.     });
  2583.     $("#stats").click(function () {
  2584.         openTab("http://www.allmangasreader.com/stats.php?stat=manga");
  2585.     });
  2586.     $("#pstats").click(function () {
  2587.         openTab("pstat.html");
  2588.     });
  2589.     $("#readallmg").click(function () {
  2590.         $(".bottomdiv").each(function (index) {
  2591.             if ($(this).is(":visible") && !$(this).hasClass("actreadallmg")) {
  2592.                 $(this).toggle("blind", {}, 500);
  2593.             }
  2594.         });
  2595.         $(".bottomdiv.actreadallmg").toggle("blind", {}, 500);
  2596.         $(".bottomdiv.actreadallmg span").text("Are you sure to mark all currently viewable mangas as read (" + $(".manga.new:visible").size() + " mangas) ?");
  2597.     });
  2598.     $("#deleteallmg").click(function () {
  2599.         $(".bottomdiv").each(function (index) {
  2600.             if ($(this).is(":visible") && !$(this).hasClass("actdeleteallmg")) {
  2601.                 $(this).toggle("blind", {}, 500);
  2602.             }
  2603.         });
  2604.         $(".bottomdiv.actdeleteallmg").toggle("blind", {}, 500);
  2605.         $(".bottomdiv.actdeleteallmg span").text("Are you sure to delete all currently viewable mangas from the list (" + $(".manga:visible").size() + " mangas) ?");
  2606.     });
  2607.  
  2608.     $(".bottomdiv.actreadallmg .no").click(function () {
  2609.         $(this).closest(".actreadallmg").toggle("blind", {}, 500);
  2610.     });
  2611.     $(".bottomdiv.actdeleteallmg .no").click(function () {
  2612.         $(this).closest(".actdeleteallmg").toggle("blind", {}, 500);
  2613.     });
  2614.  
  2615.     $(".bottomdiv.actreadallmg .yes").click(function () {
  2616.         var obj = {
  2617.             action: "readMangas",
  2618.             list: []
  2619.         };
  2620.         $(".manga.new:visible").each(function (index) {
  2621.             if (isList()) {
  2622.                 if ($(".mgline", $(this)).size() > 0) {
  2623.                     $(".mgline", $(this)).each(function (index) {
  2624.                         obj.list[obj.list.length] = {
  2625.                             url: $(this).data("mgurl"),
  2626.                             lastChapterReadURL: $(this).data("mglatesturl")
  2627.                         };
  2628.                     });
  2629.                 } else {
  2630.                     obj.list[obj.list.length] = {
  2631.                         url: $(this).data("mgurl"),
  2632.                         lastChapterReadURL: $(this).data("mglatesturl")
  2633.                     };
  2634.                 }
  2635.             } else {
  2636.                 if ($(".mgelt", $(this)).size() > 0) {
  2637.                     $(".mgelt", $(this)).each(function (index) {
  2638.                         obj.list[obj.list.length] = {
  2639.                             url: $(this).data("mgurl"),
  2640.                             lastChapterReadURL: $(this).data("mglatesturl")
  2641.                         };
  2642.                     });
  2643.                 } else {
  2644.                     obj.list[obj.list.length] = {
  2645.                         url: $(this).data("mgurl"),
  2646.                         lastChapterReadURL: $(this).data("mglatesturl")
  2647.                     };
  2648.                 }
  2649.             }
  2650.         });
  2651.  
  2652.         var _self = this;
  2653.         sendExtRequest(obj, $(this), function () {
  2654.             $(".manga.new:visible").each(function (index) {
  2655.                 $(this).closest(".manga").removeClass("new");
  2656.                 $(".actread", $(this)).unbind("click");
  2657.                 $(".actread", $(this)).attr("src", chrome.extension.getURL("img/blank.png"));
  2658.                 if (isList()) {
  2659.                     $(".mgline", $(this)).removeClass("new");
  2660.                 } else {
  2661.                     $(".mgelt", $(this)).removeClass("new");
  2662.                 }
  2663.  
  2664.                 $(".mglist select", $(this)).each(function (index) {
  2665.                     closestEltData($(this)).data("mgplay", $("option:first", $(this)).val());
  2666.                     $(this).val($("option:first", $(this)).val());
  2667.                 });
  2668.                 moveMangaParent($(".actread", $(this)));
  2669.                 updateProgression($(".actread", $(this)));
  2670.                 $(".actreadall", $(this)).remove();
  2671.             });
  2672.             $(_self).closest(".actreadallmg").toggle("blind", {}, 500);
  2673.         }, true);
  2674.     });
  2675.     $(".bottomdiv.actdeleteallmg .yes").click(function () {
  2676.         var obj = {
  2677.             action: "killMangas",
  2678.             list: []
  2679.         };
  2680.         $(".manga:visible").each(function (index) {
  2681.             if (isList()) {
  2682.                 if ($(".mgline", $(this)).size() > 0) {
  2683.                     $(".mgline", $(this)).each(function (index) {
  2684.                         obj.list[obj.list.length] = {
  2685.                             url: $(this).data("mgurl"),
  2686.                             name: $(this).data("mgname")
  2687.                         };
  2688.                     });
  2689.                 } else {
  2690.                     obj.list[obj.list.length] = {
  2691.                         url: $(this).data("mgurl"),
  2692.                         name: $(this).data("mgname")
  2693.                     };
  2694.                 }
  2695.             } else {
  2696.                 if ($(".mgelt", $(this)).size() > 0) {
  2697.                     $(".mgelt", $(".manga:visible")).each(function (index) {
  2698.                         obj.list[obj.list.length] = {
  2699.                             url: $(this).data("mgurl"),
  2700.                             name: $(this).data("mgname")
  2701.                         };
  2702.                     });
  2703.                 } else {
  2704.                     obj.list[obj.list.length] = {
  2705.                         url: $(this).data("mgurl"),
  2706.                         name: $(this).data("mgname")
  2707.                     };
  2708.                 }
  2709.             }
  2710.         });
  2711.         var _self = this;
  2712.         sendExtRequest(obj, $(this), function () {
  2713.             $(".manga:visible").toggle("blind", {}, 500, function () {
  2714.                 $(this).remove();
  2715.                 firstLastMg();
  2716.             });
  2717.             $(_self).closest(".actdeleteallmg").toggle("blind", {}, 500);
  2718.         });
  2719.     });
  2720.     /*if (!chrome.extension.getBackgroundPage().hasDesactivatedOnce()) {
  2721.   $(".desactivate").show();
  2722. }*/
  2723.     $("#desactivateLink").click(function () {
  2724.         openTab("options.html?tab=sites");
  2725.     });
  2726. }
  2727.  
  2728. function getTimeSince(timeDif) {
  2729.     var txt = "";
  2730.     if (timeDif != undefined) {
  2731.         var tmpDif = (new Date().getTime() - timeDif) / 1000;
  2732.         if (tmpDif < 60) {
  2733.             txt += Math.floor(tmpDif) + " seconds ago";
  2734.         } else if (tmpDif / 60 < 60) {
  2735.             txt += Math.floor((tmpDif / 60)) + " minutes ago";
  2736.         } else if (tmpDif / 3600 < 60) {
  2737.             txt += Math.floor((tmpDif / 3600)) + " hours ago";
  2738.         } else {
  2739.             txt += Math.floor((tmpDif / 3600 / 24)) + " days ago";
  2740.         }
  2741.     } else {
  2742.         txt += "Never";
  2743.     }
  2744.     return txt;
  2745. }
  2746.  
  2747.  
  2748. document.addEventListener('DOMContentLoaded', function () {
  2749.     document.getElementById("searchBoxInput").addEventListener('keypress', function(e) {
  2750.     if ((e.keyCode || e.which) == 13) {
  2751.         search();
  2752.         }
  2753.         });
  2754.  
  2755.     document.getElementById("butFind").addEventListener('click', search);
  2756. });
Advertisement
Add Comment
Please, Sign In to add comment