您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
searching notes!
// ==UserScript== // @name dev_note_search2 // @namespace dev_note_search2 // @description searching notes! // @match http://*.deviantart.com/notifications/notes/* // @match https://*.deviantart.com/notifications/notes/* // @version 1.1.18 // @author http://dediggefedde.deviantart.com // @grant none // ==/UserScript== function injected(){ var mapfolder=[]; var mapwords=[]; //speed up indexing notes! //Amount of notes requested on each index-cycle. //But: progressbar can only update once a cycle! //numbers for a 380 Notes Scan: //370: 4884 ms needed - 77,8 Notes/s //100: 6487 ms needed - 58,6 Notes/s <-standard //50: 7950 ms needed - 47,8 Notes/s //10: 17714 ms needed - 21,5 Notes/s //if you've got around 10.000 Notes (default: 2.8 min) you can reduce the time by settings this number higher! //Any Value above 100 will increase the update-speed and decrease how often the Progressbar is updated. //Any Value above your total amount of Notes won't make a difference. var note_index_steps=100; if (typeof uneval === "undefined") { uneval = function(a){ return (JSON.stringify(a))||''; }; } //remove the /* and */ and reload to remove all stored data! //Put them back to use the script afterwards! /* var keys = GM_listValues(); for (var i=0, key=null; key=keys[i]; i++) { GM_deleteValue(key); } */ // var $=unsafeWindow.jQuery,holder,query,offset,fPage,pPage,lPage; // var DiFi=unsafeWindow.DiFi; var noteauthor=[]; //list of authors var notetitle=[]; //list of titles var notetext=[]; //list of word -> list of index for other lists var notedata=[]; //note-id, folder, note-date var noteamount=[]; //count , updatedate var safheader=""; //old note-menu stored to be restored when leaving search var lastactfolder=""; //last active folder for continue indexing var aktfolder=""; //current selected folder (per dropdown) var aktindexfirstnoteid=""; //last note scanned in indexing -> used in updating index. var totalamm; //total amount of notes in current folder var newaddedli; // added notes used by checknewnotes var toindexnoteoffsets=[]; //note's offset that still needs to be scanned var resarr=[]; //array of note-indices that matches the current search var aktsort=4; // sorting of search results: up&down: 01 name|23 author|45 date var GM_setValue; //indexedDB: replace GM_functions! var transaction; //indexedDB var objectStore; //indexedDB //style var sty=document.createElement("style"); sty.innerHTML="h2.dev_note_search2_search input[type='text']{"+ "background-color: #BBCCBA;"+ "border: 1px inset #5E7264;"+ "border-radius: 7px;"+ "color: #3C4441;"+ "display: inline-block;"+ "margin-left: 10px;"+ "padding: 2px;"+ "padding-left:4px;"+ "width:70%;"+ "vertical-align: middle;}"+ "div.dev_note_header{"+ "background: linear-gradient(0deg, rgba(0,0,0,0.2) 0%, rgba(255,255, 255, 0.5) 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);"+ "padding: 0 0 0 6px!important;height:20px;}"+ "div.dev_note_header>div{"+ "height:20px;cursor:pointer;}"+ "li.dev_noteentry>span, div.dev_note_header>div{"+ "display:inline-block;"+ "width:33.33%;"+ "}"+ "#dev_note_search2_search_info{"+ "font-size:8pt;width:30%;margin:0;}"+ "li.dev_noteentry{"+ "min-height: 5px !important;"+ "cursor:pointer;"+ "padding:6px 0 6px 6px!important;"+ "}"+ "h2.dev_note_search2_search span{"+ "margin-left: 10px;"+ "width: 80px;"+ "display: inline-block;"+ "vertical-align: middle;"+ "font-size:10pt;}"+ "#dev_note_search2_search_index, #dev_note_search2_removeall_index{"+ "position:absolute;right:0;height:18px;font-size:8pt;padding:0;"+ "}"+ "#dev_note_search2_removeall_index{right:70px;}"+ "h2.dev_note_search2_search span.dev_note_search2_search_header{"+ "font-size:14pt;height:30px;display:inline-block;}"+ ".dev_aktsort_down{"+ // "background: linear-gradient(0deg, #afdbae 0%, #E4F4E3 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);}"+ "background: linear-gradient(0deg, rgba(175,155,40,0.2) 0%, rgba(72, 194, 27, 0.5) 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);}"+ ".dev_aktsort_up{"+ "background: linear-gradient(180deg, rgba(175,155,40,0.2) 0%, rgba(72, 194, 27, 0.5) 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);}"+ "h2.dev_note_search2_search input[type='submit'],h2.dev_note_search2_search select{"+ "border-radius: 7px;"+ "background: linear-gradient(0deg, #E2E9E3, #D3DFD5) repeat scroll 0 0 transparent;"+ "border: 1px solid #93A98F;"+ "padding: 3px;"+ "margin: 6px;"+ "float: left;"+ "cursor:pointer;"+ "color: #2C3635;}"+ "h2.dev_note_search2_search input[type='submit']:active{"+ "border:1px inset #93A98F;"+ "background: linear-gradient(180deg, #E2E9E3, #B5C9B8) repeat scroll 0 0 transparent;}"; document.body.appendChild(sty); //removes all elements of array subtrahend from array minuend with creating a new one. function arrsubstract(minuend, subtrahend){ var ruckarr=[]; for(var i=0;i<minuend.length;i++) if(subtrahend.indexOf(minuend[i])==-1)ruckarr.push(minuend[i]); return ruckarr; } //merges two array unique into a 3rd one. function arrmerge(arr1, arr2){ var ruckarr=getUnique(arr1); if(arr2==null)return arr1; if(arr1==null)return arr2; for(var i=0;i<arr2.length;i++) if(ruckarr.indexOf(arr2[i])==-1)ruckarr.push(arr2[i]); return ruckarr; } //makes an array unique function getUnique(arr){ var u = {}, a = []; if(arr==null)return arr; for(var i = 0, l = arr.length; i < l; ++i){ if(u.hasOwnProperty(arr[i])) { continue; } a.push(arr[i]); u[arr[i]] = 1; } return a; } //returns an array with all elements from two array that are in both. function getintersection(arr1,arr2){ var resarr=new Array(); if(arr1==null)return arr2; if(arr2==null)return arr1; for (var i = 0; i < arr1.length; i++) { if (arr2.indexOf(arr1[i]) != -1) { resarr.push(arr1[i]); } } return resarr; } //remove slashes from string function stripslashes(str) { str=str.replace(/\\'/g,'\''); str=str.replace(/\\"/g,'"'); str=str.replace(/\\0/g,'\0'); str=str.replace(/\\\\/g,'\\'); return str; } //takes a quary-string and returns a list of matched note-indices (regarding the script-lists) //"" and * are handled here, + and - on the click-event. function search(query,mode){ //mode: 0:author, 1: title, 2:text try{ var returnarr=[]; if(query==""||query=="*")return null; //empty searches query=query.toLowerCase(); //case insensitive var inquote=false; //this block replaces all spaces with $ within quotes. for(var i=0;i<query.length;i++){ if(inquote){ if(query[i]==" ")query=query.substr(0,i)+"$"+query.substr(i+1); if(query[i]=="\""||query[i]=="'")inquote=false; }else{ if(query[i]=="\""||query[i]=="'")inquote=true; } } query=query.replace(/["']/g,""); //remove quotes. protected spaces are now $ switch(mode){ case 0: //author search var searchwords=query.split(" "); for(var j=0;j<searchwords.length;j++){ //any of those words for(var i=0;i<noteauthor[aktfolder].length;i++){ //all found note-indices if(noteauthor[aktfolder][i].toLowerCase().indexOf(searchwords[j].replace(/\$/g," "))!=-1)returnarr.push(i); //add found note-index to return-array if not already part of } } break; case 1: //title search: like author var searchwords=query.split(" "); for(var j=0;j<searchwords.length;j++){ for(var i=0;i<notetitle[aktfolder].length;i++){ if(notetitle[aktfolder][i].toLowerCase().indexOf(searchwords[j].replace("$"," "))!=-1)returnarr.push(i); } } break; case 2: //text search: var searchwords=query.split(" "); for(var i=0;i<searchwords.length;i++){ if(searchwords[i].split("$").length==1){ //no protected spaces/quotes: if(searchwords[i][searchwords[i].length-1]=="*" && searchwords[i][0]=="*"){ //*-cases: *word* searchwords[i]=searchwords[i].substr(1,searchwords[i].length-2); //make *word* to word var indexF=mapfolder.indexOf(aktfolder);if(indexF<0)indexF=0; // for(var w in notetext[aktfolder]){ //go through all stored keywords for(var w =0;w<mapwords[indexF].length;++w){// in notetext[indexF]){ //go through all stored keywords if(mapwords[indexF][w].indexOf(searchwords[i])!=-1){ //a keyword contains "word" // for(var j=0;j<notetext[aktfolder][w].length;j++) //add all note-indices of this word to the returnlist (if not already there) for(var j=0;j<notetext[indexF][w].length;j++) //add all note-indices of this word to the returnlist (if not already there) // returnarr.push(parseInt(notetext[aktfolder][w][j])); returnarr.push(parseInt(notetext[indexF][w][j])); } } }else if(searchwords[i][searchwords[i].length-1]=="*"){ //*-cases: word* searchwords[i]=searchwords[i].substr(0,searchwords[i].length-1); //word* -> word var indexF=mapfolder.indexOf(aktfolder);if(indexF<0)indexF=0; for(var w =0;w<mapwords[indexF].length;++w){// in notetext[indexF]){ if(mapwords[indexF][w].indexOf(searchwords[i])==0){ //keyword beginns with "word" for(var j=0;j<notetext[indexF][w].length;j++) returnarr.push(parseInt(notetext[indexF][w][j])); } } }else if(searchwords[i][0]=="*"){ //*-cases: *word searchwords[i]=searchwords[i].substr(1); //*word -> word var indexF=mapfolder.indexOf(aktfolder);if(indexF<0)indexF=0; for(var w =0;w<mapwords[indexF].length;++w){// in notetext[indexF]){ if(mapwords[indexF][w].indexOf(searchwords[i])==mapwords[indexF][w].length-searchwords[i].length){ //keyword ends with "word" for(var j=0;j<notetext[indexF][w].length;j++) returnarr.push(parseInt(notetext[indexF][w][j])); } } }else{ //no * case var indexF=mapfolder.indexOf(aktfolder);if(indexF<0)indexF=0; var indexW=mapwords[indexF].indexOf(searchwords[i]); // console.log(indexW,notetext[indexF].length,typeof notetext[indexF][indexW],indexW >-1 , notetext[indexF].length<indexW , typeof notetext[indexF][indexW]!= "undefined"); if(indexW >-1 && notetext[indexF].length>indexW && typeof notetext[indexF][indexW]!= "undefined"){ for(var j=0;j<notetext[indexF][indexW].length;j++){//add all note-indices of this word to the returnlist (if not already there) indexW=mapwords[indexF].indexOf(searchwords[i]); returnarr.push(parseInt(notetext[indexF][indexW][j])); } } // console.log(returnarr); } }else{ //protected spaces/quotes -> $ returnarr=returnarr.concat(search(searchwords[i].replace(/\$/g," ").trim(),mode)); //make a normal search like there were no " var leerwords=searchwords[i].split("$"); //words within quotes var aktretarr=returnarr; //now make a difi-request: get the full text of the notes that matches the normal search and check if the originally search matches their text. //if yes, the note with the data-noteid-property will get removed. for(var j=0;j<aktretarr.length;j++){ DiFi.pushPost('Notes', 'display_note', [aktfolder,notedata[aktfolder][aktretarr[j]][0]],function(success,data){ var tnotetext=$(data.response.content.body).find("textarea.mcb-body").html(); var swords=/[^ \$]*\$([^ \$]*\$?)*/g var row=""; while(row=swords.exec(query)){ var spacedwords=row[0].replace("$"," "); if((tnotetext.indexOf(spacedwords)==-1&&tnotetext.indexOf("*")==-1)|| (spacedwords.indexOf("*")!=-1)&&tnotetext.match(new RegExp(spacedwords.replace(/\*/g,"[^ ]*?"),"i"))==null){ $("li.note[data-noteid="+data.response.content.noteid+"]").remove(); } } // tnotetext }); } // DiFi.timer(2000); //just for record: this will do send() after 2s. DiFi.send(); //bunch the pushpost before sending makes it into one request which is faster. } } break; } }catch(ex){ console.log("Search error",ex); return []; } return returnarr; } //load the data from indexedDB for this folder //will be called the number of folders times. function loaddata(folder){ transaction = db.transaction(["devnotesearch2"], "readwrite"); //new transaction for getting data var objectStore = transaction.objectStore("devnotesearch2"); transaction.onerror = function(event) { //in case of an error, something went wrong... console.log(event) }; //mozilla's homepage: defining onsuccess after calling get would be fine... //if not found, get will also succeed, but with event.target.result=undefined. objectStore.get("noteauthor_"+folder).onsuccess=function(event){ //load authorlist if(typeof event.target.result!="undefined")noteauthor[folder]=eval(event.target.result.value); }; objectStore.get("notetitle_"+folder).onsuccess=function(event){//load titlelist if(typeof event.target.result!="undefined")notetitle[folder]=eval(event.target.result.value); }; objectStore.get("notedata_"+folder).onsuccess=function(event){ //load data-list (see header-variables) if(typeof event.target.result!="undefined")notedata[folder]=eval(event.target.result.value); }; objectStore.get("noteamount_"+folder).onsuccess=function(event){ //load stored amount and last update if(typeof event.target.result!="undefined")noteamount[folder]=eval(event.target.result.value); }; objectStore.get("toindexnoteoffsets").onsuccess=function(event){ //load last indexed note. if(typeof event.target.result!="undefined")toindexnoteoffsets=eval(event.target.result.value); }; objectStore.get("lastindexfolder").onsuccess=function(event){ //load last indexed folder if(typeof event.target.result!="undefined")lastindexfolder=event.target.result.value; }; objectStore.get("notetext_"+folder).onsuccess=function(event){ //load all the content-data (word-lists) if(typeof event.target.result=="undefined")return; //word(18)noteid(19)wordpos(18)noteid(19)wordpos(17)word(18)noteid(19)wordpos var rawdata=event.target.result.value.split(String.fromCharCode(17)); var zrawdata1="", zrawdata2=""; var indexW,indexF; if(mapfolder.indexOf(folder)==-1){ mapfolder.push(folder); indexF=mapfolder.indexOf(folder); mapwords[indexF]=[]; }else indexF=mapfolder.indexOf(folder); notetext[indexF]=new Array(); // console.log(rawdata); for(var i=0;i<rawdata.length;i++){ zrawdata1=rawdata[i].split(String.fromCharCode(18)); //noteid(19)wordpos zrawdata2=zrawdata1.shift(); //word if(mapwords[indexF].indexOf(zrawdata2)==-1) mapwords[indexF].push(zrawdata2); indexW=mapwords[indexF].indexOf(zrawdata2); // notetext[folder][zrawdata2]=zrawdata1; notetext[indexF][indexW]=zrawdata1; } // console.log(mapwords,mapfolder); //display the info-text $("#dev_note_search2_search_folders").change(); }; } //convert the note's message into word-list entries function adddata(message, noteid, folder){ try{ if(message==null||message=="")return; var elements=message.replace(/[\W\s]/g," ").replace(/ {2,}/," ").split(" "); //only \w-character words are liked. numbers are part of \w for(var i =0;i<elements.length;i++){ //all new words if(typeof elements[i]=="undefined"||elements[i]==""||elements[i][0]==" ")continue; //empty words and strange accidents don't count. elements[i]=elements[i].toLowerCase(); //case insensitive var indexF=mapfolder.indexOf(folder); if(mapwords.length<=indexF||indexF<0||notetext.length<=indexF)continue; var indexW=mapwords[indexF].indexOf(elements[i]); if(typeof notetext[indexF]=="undefined"){ //word not yet listed notetext.push([[noteid]]); } else { //word already part of list if(indexW<0){ mapwords[indexF].push(elements[i]); notetext[indexF].push([]); } indexW=mapwords[indexF].indexOf(elements[i]); if(indexW<0||indexW>=notetext[indexF].length||typeof notetext[indexF][indexW]=="undefined")continue; if( $.inArray(noteid, notetext[indexF][indexW])==-1 //this note is not already added (e.g. 2 times word in a note) &¬etext[indexF][indexW].push) //and the array is legit notetext[indexF][indexW].push(noteid); //then add this note's index (pointing to other lists) } } }catch(ex){ console.log("MSG-convert error: ",ex); return; } } //this goes from newest to oldest note until it finds a note with the last indexed note id, stored in noteamount[folder][2] //this is actually how getnotes() also looked like before made pausable and turning the pushposts into bunches. function checknewnotes(folder,offset){ if(offset==40)return; //in case there is no last indexed id as there was no index, make a full index var indexF=mapfolder.indexOf(folder); // var indexW=mapwords[indexF].indexOf(elements[i]); // if(typeof notetext[folder]=="undefined"&&totalamm!=-1){getnotes(folder,Math.floor(totalamm/10)*10,true);return;} if((indexF<0 || typeof notetext[indexF]=="undefined")&&totalamm!=-1){getnotes(folder,Math.floor(totalamm/10)*10,true);return;} if(totalamm==-1){ //folder unknown full noteauthor[folder]=[]; //everywhere 0! notetitle[folder]=[]; notetext[indexF]=[]; notedata[folder]=[]; // mapfolder=[]; // mapwords=[]; noteamount[folder]=[0,(new Date).toLocaleString(),""]; lastindexfolder=folder; aktindexfirstnoteid=""; var intex=""; saveindexnotes(folder, intex); //save 0... $("#dev_note_search2_search_folders").change(); //display 0 Notes indexed } DiFi.pushPost('Notes', 'display_folder', [folder,offset,false],function(success,data){ var aktsite=$(data.response.content.body); //parse note-page (<10 notes) aktsite.find("li.note").each(function(){ //break when the last indexed note was found. All notes before that (newer) will be in newaddedli. if($(this).attr("data-noteid")!=noteamount[folder][2]){ newaddedli=newaddedli.add($(this)); }else return false; //false will break the each-loop }); if(newaddedli.length==0)return; //no new notes if(aktsite.find("li.note[data-noteid='"+noteamount[folder][2]+"']").length==0&&aktsite.find("li.note").length>0){ //the last indexed note is not on this site checknewnotes(folder,offset+10); //recursive call to scan the next page. }else{ //reverse order of found new notes (convert to oldes->newest) $(newaddedli.get().reverse()).each(function(){ if(NoteAlreadyScanned($(this).attr("data-noteid"),folder))return; //username is a must have. if($(this).find("span.sender a.username,span.sender span.username").html()==null){ return; } if(typeof $(this).find("div.note-preview").html()=="undefined"){ noteauthor[folder].push($(this).find("span.sender a.username,span.sender span.username").html()); notetitle[folder].push($(this).find("span.subject a").html()); var dstime=Date.parse($(this).find("span.ts").attr("title")); if(isNaN(dstime))dstime=Date.parse($(this).find("span.ts").html()); aktindexfirstnoteid=$(this).attr("data-noteid"); notedata[folder].push(new Array($(this).attr("data-noteid"), $(this).find("span.subject a").attr("data-folderid"), dstime)); return; } noteauthor[folder].push($(this).find("span.sender a.username,span.sender span.username").html()); //otherwise noteauthor has a problem notetitle[folder].push($(this).find("span.subject a").html()); //title just assumes, there is a note title //no convert and add the text into word-list. //note-preview contains the whole text, but without linebreaks(spaces inserted) and without html //notedata[folder].length is the new index after this entry is pushed into notedata! adddata($(this).find("div.note-preview").html(),notedata[folder].length,folder); //parse the time when the note was sent/recieved. var dtime=Date.parse($(this).find("span.ts").attr("title")); if(isNaN(dtime))dtime=Date.parse($(this).find("span.ts").html()); //the display switches: one says the date, one xx minutes ago. aktindexfirstnoteid=$(this).attr("data-noteid"); //last indexed note will be overwritten untill the newset index. //add note-id, folderid and recieved date to notedata. notedata[folder].push(new Array($(this).attr("data-noteid"), $(this).find("span.subject a").attr("data-folderid"), (new Date(dtime)).toLocaleString())); }); var intex=""; saveindexnotes(folder,intex); //progressbar and title $("#dev_note_search2_search_index").css("background-image","").attr("title","100%: "+noteauthor[folder].length+"/"+totalamm+", "+Math.round(100*(intex.length+uneval(noteauthor[folder]).length+uneval(notetitle[folder]).length+uneval(notedata[folder]).length)/1024/1024)/100+"MB storage used"); } // } }); DiFi.send(); } // var aktstartdat; //time measurement. //saves the values to indexedDB! function saveindexnotes(folder, intex){ try{ if(typeof intex=="undefined"||intex==null)intex=""; var indexF=mapfolder.indexOf(folder); // var indexW=mapwords[indexF].indexOf(elements[i]); // for(var el in notetext[folder]){//convert word-list into a string. saves some bytes in contrast to uneval(). // intex+=String.fromCharCode(17)+el+String.fromCharCode(18)+notetext[folder][el].join(String.fromCharCode(18)); // } for(var el =0;el<mapwords[indexF].length;++el){//in notetext[indexF]){//convert word-list into a string. saves some bytes in contrast to uneval(). intex+=String.fromCharCode(17)+mapwords[indexF][el]+String.fromCharCode(18)+notetext[indexF][el].join(String.fromCharCode(18)); } //noteamount, updatedate and last indexed note to be changed noteamount[folder]=[noteauthor[folder].length,(new Date).toLocaleString(),aktindexfirstnoteid]; //elements in folder... //this updates info-text during scan if(typeof noteamount[aktfolder]!="undefined"&¬eamount[aktfolder].length>1) $("#dev_note_search2_search_info").html(noteamount[aktfolder][0]+" Notes fetched<br/> Updated on"+noteamount[aktfolder][1]); // setTimeout(function(){ //neded for the original GM_setValue. Now IndexDb GM_setValue("notetext_"+folder,intex.substr(1)); GM_setValue("noteauthor_"+folder,uneval(noteauthor[folder])); GM_setValue("notetitle_"+folder,uneval(notetitle[folder])); GM_setValue("noteamount_"+folder,uneval(noteamount[folder])); GM_setValue("notedata_"+folder,uneval(notedata[folder])); GM_setValue("toindexnoteoffsets",uneval(toindexnoteoffsets)); GM_setValue("lastindexfolder",uneval(lastindexfolder)); // },0); }catch(ex){ console.log("indexDB-storage error: ",ex); return; } } function NoteAlreadyScanned(id,folder){ try{ for(var i=0;i<notedata[folder].length;i++) if(notedata[folder][i][0]==id)return true; return false; }catch(ex){ console.log("Note-Check error: ",ex); return; } } //index your notes anew or continue after break. function getnotes(folder,offset,neu){ try{ if(typeof folder=="undefined"||folder<0)return; if(totalamm==0){ //folder empty noteauthor[folder]=new Array(); //everywhere 0! notetitle[folder]=new Array(); notetext[folder]=[]; if(mapfolder.indexOf(folder)<0){ mapfolder.push(folder); mapwords.push([]); } notedata[folder]=new Array(); noteamount[folder]=[0,(new Date).toLocaleString(),""]; lastindexfolder=folder; aktindexfirstnoteid=""; var intex=""; saveindexnotes(folder, intex); //save 0... $("#dev_note_search2_search_folders").change(); //display 0 Notes indexed return; } if(neu){ //indexing started if(toindexnoteoffsets.length>0){return;} //already running! noteauthor[folder]=[]; notetitle[folder]=[]; if(mapfolder.indexOf(folder)<0){ mapfolder.push(folder); mapwords.push([]); } notedata[folder]=[]; noteamount[folder]=[]; lastindexfolder=folder; aktindexfirstnoteid=""; for(var i=offset;i>=0;i-=10) //create all note-offset I want to scan! offset=(page-1)*10. toindexnoteoffsets.push(i); //go from high to 0: old notes first! } if(offset==-10){ //finished: all notes scanned, toindexnoteoffsets empty. var intex=""; saveindexnotes(folder, intex); //save all data. //update progressbar if(typeof noteauthor[folder]=="undefined"||noteauthor[folder]==null)return; $("#dev_note_search2_search_index").css("background-image","").attr("title","100%: "+noteauthor[folder].length+"/"+totalamm+", "+Math.round(100*(intex.length+uneval(noteauthor[folder]).length+uneval(notetitle[folder]).length+uneval(notedata[folder]).length)/1024/1024)/100+"MB storage used"); //update info-text $("#dev_note_search2_search_folders").change(); }else{ var runter=note_index_steps; //number of offsets within a request. Is set at top. default 100 if(offset%note_index_steps!=0)runter=offset%note_index_steps; //360: first 6*10, then only 10*10. for(var i=0;i<toindexnoteoffsets.length&&i<runter/10;i++){ //bunch of difi-posts. DiFi.pushPost('Notes', 'display_folder', [folder,toindexnoteoffsets[i],false],function(success,data){ //remove offset from list toindexnoteoffsets.splice(toindexnoteoffsets.indexOf(parseInt(data.response.content.offset)),1); //update progressbar if(totalamm==0)totalamm=1; $("#dev_note_search2_search_index").css("background-image","linear-gradient(90deg, #9AD15F "+(Math.round((totalamm-toindexnoteoffsets.length*10)/totalamm*100))+"%, #D3DFD5 "+(Math.round((totalamm-toindexnoteoffsets.length*10)/totalamm*100)+10)+"%)").attr("title",Math.round((totalamm-toindexnoteoffsets.length*10)/totalamm*100)+"%: "+(totalamm-toindexnoteoffsets.length*10)+"/"+totalamm); //get jquery-object for notes page var aktsite=$(data.response.content.body); if(aktsite.find("li.note").length!=0){ //no empty pages //reverse order for oldes to newest notes! $(aktsite.find("li.note").get().reverse()).each(function(){ // see checknewnotes for this try{ if(NoteAlreadyScanned($(this).attr("data-noteid"),folder))return false; //true: next item if($(this).find("span.sender a.username,span.sender span.username").html()==null){ //no sender recognized return true; //true: next item; } if(typeof $(this).find("div.note-preview").html()=="undefined"){ noteauthor[folder].push($(this).find("span.sender a.username,span.sender span.username").html()); notetitle[folder].push($(this).find("span.subject a").html()); var dstime=Date.parse($(this).find("span.ts").attr("title")); if(isNaN(dstime))dstime=Date.parse($(this).find("span.ts").html()); if(isNaN(dstime))dstime=0; aktindexfirstnoteid=$(this).attr("data-noteid"); notedata[folder].push(new Array($(this).attr("data-noteid"), $(this).find("span.subject a").attr("data-folderid"), dstime)); return true; //no preview: next item } noteauthor[folder].push($(this).find("span.sender a.username,span.sender span.username").html()); notetitle[folder].push($(this).find("span.subject a").html()); adddata($(this).find("div.note-preview").html(),notedata[folder].length,folder); var dtime=Date.parse($(this).find("span.ts").attr("title")); if(isNaN(dtime))dtime=Date.parse($(this).find("span.ts").html()); aktindexfirstnoteid=$(this).attr("data-noteid"); notedata[folder].push(new Array($(this).attr("data-noteid"), $(this).find("span.subject a").attr("data-folderid"), dtime)); }catch(ex2){ console.log("Error checking Offset "+offset+":",ex2); return true; //error: next item; } }); saveindexnotes(folder); //all note's scanned: call the finish-feature of this functio //are note_index_steps note scanned at once, you can scan the next note_index_steps Notes! if(toindexnoteoffsets.length==0)getnotes(folder,-10,false); else if((toindexnoteoffsets.length*10-10)%note_index_steps==0)getnotes(folder,(toindexnoteoffsets.length*10-10),false); } }); } DiFi.send(); } }catch(ex){ console.log("Error in fetching notes: ",ex); return; } } function addlayout(){ if($("dev_note_search2_tab").length>0)return; aktfolder="1"; //standard is inbox. aktsort=4; //standard is sorting results with date resarr=[]; //show no notes at the beginning (index of notes to show) //search-entry on the left var tab=$('<a class="f folder-link dev_search_tab" title="Search" href="#" onclick="return false;" id="dev_note_search2_tab"><i class="icon i1"></i><span class="ttext">Search</span></a>'); //make the search-form undo-able $("div.messages-menu div.pager-holder div.pager2 div.page2").children().click(function(){ if(safheader!=""){ $("h2.mczone-title").empty(); $("h2.mczone-title").css("height",""); $("h2.mczone-title").first().append(safheader); } if(lastactfolder!=""){ //switch to last selected folder! lastactfolder.addClass("selected"); $("#dev_note_search2_tab").removeClass("selected"); } }); $("#notes a.folder-link").first().before(tab); //insert "search" // $("div.messages-menu div.pager-holder div.pager2 div.page2 div.header").first().after(tab); //insert "search" tab.click(function(event){//and click event event.preventDefault(); event.stopPropagation(); //no parent-clicks needed! $(".dev_note_header").remove(); //no double search forms! //folder where you came from lastactfolder=$("div.messages-menu div.pager-holder div.pager2 div.page2 a.selected").removeClass("selected").first(); $("#dev_note_search2_tab").addClass("selected"); //search is now selected if($("#dev_note_search2_search_title").length==0)safheader=$("h2.mczone-title").first().children(); var header1=$("td.notes-left h2.mczone-title").first().empty(); var header2=$("td.notes-right h2.mczone-title").first().empty(); //no double search forms! header1.addClass("dev_note_search2_search"); header2.addClass("dev_note_search2_search"); $( window ).resize(function(){ //adapt search form to window's site $("#dev_note_search2_search_info").width($("h2.dev_note_search2_search").eq(1).width()-320); $("h2.dev_note_search2_search input[type='text']").width($("h2.dev_note_search2_search").first().width()-130); }); //inset search form header1.append($("<span class='dev_note_search2_search_header'>Search:</span><div class='dev_search_formfield'><span>Username:</span><input id='dev_note_search2_search_name' type='text'/></div>"+ "<div class='dev_search_formfield'><span>Subject:</span><input id='dev_note_search2_search_title' type='text'/></div><div class='dev_search_formfield'><span>Text:</span><input id='dev_note_search2_search_text' type='text'/></div>")).css({"height":"110px","background-size":"contain","padding":"10px 0px"}); header1.find("input[type='text']").keydown(function(event){ //enter means search! if(event.which==13)$("#dev_note_search2_search_submit").click(); }); header2.append("<input type='submit' onclick='return false;' id='dev_note_search2_search_submit' value='Search'/>"+ "<input type='submit' onclick='return false;' id='dev_note_search2_search_addindex' value='Refresh'/>"+ "<select id='dev_note_search2_search_folders'></select><span id='dev_note_search2_search_info'></span>"); header1.prepend("<input type='submit' onclick='return false;' id='dev_note_search2_search_index' value='Index Notes'/>"); header1.prepend("<input type='submit' onclick='return false;' id='dev_note_search2_removeall_index' value='Reset to Default'/>"); $("#dev_note_search2_search_addindex").first().click(function(){ //refresh-button to update index //total amount of notes is displayed at each note-folder's rel-attribute totalamm=parseInt($("a.folder-link[data-folderid="+aktfolder+"]").attr("rel").replace(/,/g,"")); newaddedli=$([]); checknewnotes(aktfolder,0); }); //load data for each folder and generate the dropdown! $("div.messages-menu div.pager-holder div.pager2 div.page2 a.folder-link").not(".dev_search_tab").each(function(){ if($(this).html()=="Search")return; var wert=$(this).attr("data-folderid"); if(typeof(noteamount[wert])=="undefined"){ //only load first // setTimeout(function(){ loaddata(wert); // },0); } $("#dev_note_search2_search_folders").first().append("<option value='"+$(this).attr("data-folderid")+"'>"+$(this).attr("title")+"</option>"); }); $("#dev_note_search2_search_folders option").first().addClass("selected"); //select "inbox" $("#dev_note_search2_search_folders").change(function(){ //change will update the info-text and chooses aktfolder if($(this).prop("selectedIndex")==-1)$(this).prop("selectedIndex",0); //stange=first aktfolder=$(this).val(); if(toindexnoteoffsets.length>0){ //continue scan? if(confirm("You interrupted the last scan of your folder '"+lastindexfolder+"'.\n Do you want to continue indexing it?")){ totalamm=parseInt($("a.folder-link[data-folderid="+aktfolder+"]").attr("rel").replace(/,/g,"")); getnotes(aktfolder,0,false); }else{ //no... toindexnoteoffsets=[]; // GM_setValue("toindexnoteoffsets",uneval(toindexnoteoffsets)); } } if(typeof(noteamount[aktfolder])=="undefined") //no indexed notes! $("#dev_note_search2_search_info").html("No notes fetched so far!<br/>Press \"Index Notes\"!"); else //show the indexed note's amount and update-Date in the info-text-field! $("#dev_note_search2_search_info").html(noteamount[aktfolder][0]+" Notes fetched<br/> Updated on "+noteamount[aktfolder][1]); }).keyup(function() { //using dropdown with keyboard $(this).change(); }).change(); //and do it already once! $("#dev_note_search2_removeall_index").click(function(){ location.href="http://www.deviantart.com/notifications/notes/#1_0/#killoldindex"; location.reload(); }); $("#dev_note_search2_search_index").click(function(){ //index notes! //total amount of notes is displayed at each rel-attribute totalamm=parseInt($("a.folder-link[data-folderid="+aktfolder+"]").attr("rel").replace(/,/g,"")); if(totalamm==-1){ newaddedli=$([]); checknewnotes(aktfolder,0); }else{ getnotes(aktfolder,Math.floor(totalamm/10)*10,true); } }); //make a search! //here is also the actuall search and use of search() defined! header2.find("#dev_note_search2_search_submit").click(function(){ resarr=getUnique(search($("#dev_note_search2_search_name").val(),0)); //search authors resarr=getintersection(resarr,search($("#dev_note_search2_search_title").val(),1)); //search titles //use intersection to have notes that match author AND title var query=$("#dev_note_search2_search_text").val().trim(); //and now the text-search... var queryplus=query.match(/\+("[^"]*?"|[^ "]*)/g); //all words with a + before (also +"asd dsa") var queryminus=query.match(/-("[^"]*?"|[^ "]*)/g); //same with - var querynotplus=query.replace(/(\+|-)("[^"]*?"|[^ "]*)/g,""); //and words with neither if(queryplus==null) //no plus words? resarr=getintersection(resarr,search(querynotplus,2)); //normal search else{ for(var i=0;i<queryplus.length;i++){ //otherwise go through all + words //and connect their searches with ANDs! resarr=getintersection(resarr,search(queryplus[i].substr(1).trim(),2)); } //at last merge the result with the not-plus words for an stronger OR. resarr=arrmerge(resarr,search(querynotplus.trim(),2)); } if(queryminus!=null){ //there were - words. var notresarr=search(queryminus.join(" ").replace("-",""),2); //find notes with those words resarr=arrsubstract(resarr,notresarr); //and remove them from the list! } resarr=getUnique(resarr); //in case something got wrong: unique id. //WHY ARE THERE STILL DOUBLE ENTRIES? $("div.dev_aktsort_down,div.dev_aktsort_up").click().click(); //refresh sorting! displayresarr(); //show found notes! }); //note-headers for sorting! $("ul.notes").first().before($("<div class='dev_note_header'></div>").first().append($("<div class='dev_notetitle'>Subject</div>").click(function(){ $(".dev_aktsort_down").removeClass("dev_aktsort_down"); $(".dev_aktsort_up").removeClass("dev_aktsort_up"); if(resarr==null)return; //no notes to sort if(aktsort==0){ //toggle between 0 and 1 $(this).addClass("dev_aktsort_up"); aktsort=1; resarr=resarr.sort(function(a,b){return notetitle[aktfolder][a].toLowerCase()<=notetitle[aktfolder][b].toLowerCase();}); //sort subjects ascending }else{ $(this).addClass("dev_aktsort_down"); aktsort=0; resarr=resarr.sort(function(a,b){return notetitle[aktfolder][a].toLowerCase()>=notetitle[aktfolder][b].toLowerCase();}); //sort subjects descending } displayresarr(); //show sorted notes })).first().append($("<div class='dev_noteauthor'>Username</div>").click(function(){ $(".dev_aktsort_down").removeClass("dev_aktsort_down"); $(".dev_aktsort_up").removeClass("dev_aktsort_up"); if(resarr==null)return; if(aktsort==2){//toggle between 2 and 3 $(this).addClass("dev_aktsort_up"); aktsort=3; resarr=resarr.sort(function(a,b){return noteauthor[aktfolder][a].toLowerCase()<=noteauthor[aktfolder][b].toLowerCase();}); //sort usernames ascending }else{ $(this).addClass("dev_aktsort_down"); aktsort=2; resarr=resarr.sort(function(a,b){return noteauthor[aktfolder][a].toLowerCase()>=noteauthor[aktfolder][b].toLowerCase();}); //sort usernames descending } displayresarr(); })).first().append($("<div class='dev_notedata dev_aktsort_down'>Date</div>").click(function(){ $(".dev_aktsort_up").removeClass("dev_aktsort_up"); $(".dev_aktsort_down").removeClass("dev_aktsort_down"); if(resarr==null)return; if(aktsort==4){//toggle between 4 and 5 $(this).addClass("dev_aktsort_up"); aktsort=5; resarr=resarr.sort(function(a,b){return notedata[aktfolder][a][2]>=notedata[aktfolder][b][2];}); //sort dates ascending }else{ $(this).addClass("dev_aktsort_down"); aktsort=4; resarr=resarr.sort(function(a,b){return notedata[aktfolder][a][2]<=notedata[aktfolder][b][2];}); //sort dates descending } displayresarr(); }))); displayresarr(); //show no notes at the beginning }); } function displayresarr(){ //show the notes which indices are in resarr var body=$("ul.notes").first(); body.empty(); //empty the old displayed list if(resarr==null)return; //new list empty? for(var i=0;i<resarr.length;i++){ //append a new li for every note. info and style are also inserted. also note-id in ''. body.append($("<li class='dev_noteentry "+(i%2==0?"even":"odd")+" note ui-draggable' data-noteid='"+notedata[aktfolder][resarr[i]][0]+"' data-folderid='"+notedata[aktfolder][resarr[i]][1]+"' data-cached='false'>"+ "<span class='dev_notetitle'>"+notetitle[aktfolder][resarr[i]]+"</span>"+ "<span class='dev_noteauthor'>"+noteauthor[aktfolder][resarr[i]]+"</span>"+ "<span class='dev_notedata'>"+(new Date(notedata[aktfolder][resarr[i]][2])).toLocaleString()+"</span>"+ "</li>").click(function(){ //click on the li: $("li.current-note").removeClass("current-note"); $(this).addClass("current-note"); //note highlight location.href=location.href.replace(/\/\d+$/,"")+"/"+$(this).attr("data-noteid"); //adapt displayed url! DiFi.pushPost("Notes","display_note",[$(this).attr("data-folderid"),$(this).attr("data-noteid")],function(success,data){ //display the note via difi! $("div.push").first().html("<a id=\"note-body\" class=\"anchor\"></a>"+ stripslashes(data.response.content.body)); //difi slashes lot of things... $("div.note-controls.current-note-actions").css("display",""); //otherwise, the buttons are hidden... }); DiFi.send(); })); } } var db; function indexedDBinit(neu){ //indexedDB: if(location.href.substring(location.href.length-("#killoldindex").length)=="#killoldindex"){ indexedDB.deleteDatabase('devnotesearch2'); location.href="http://www.deviantart.com/notifications/notes/#1_0/"; } var request = indexedDB.open("devnotesearch2",1); request.onerror = function(event) { console.log(event); }; request.onupgradeneeded = function(event) { if(event!=null)db = event.target.result; var objectStore = db.createObjectStore("devnotesearch2",{keyPath:"name"}); objectStore.createIndex("name", "name", { unique: true }); } request.onsuccess = function(event) { db = request.result; db.onabort = function(e) { db.close(); db = null; } // db = event.target.result; // var objectStore = db.createObjectStore("devnotesearch2",{keyPath:"name"}); // objectStore.createIndex("name", "name", { unique: true }); try{ transaction = db.transaction(["devnotesearch2"], "readwrite"); }catch(e){ request.onupgradeneeded(null); return; } objectStore = transaction.objectStore("devnotesearch2"); var putter=objectStore.put({name:"test",value:"erfolgreich"}); putter.onerror=function(event){console.log("ERR:",event);}; putter.onsuccess=function(event){}; objectStore.get("test").onsuccess=function(event){ //load authorlist if(typeof event.target.result!="undefined")console.log(event.target.result.value); }; transaction.onerror = function(event) { console.log(event) }; GM_setValue=function(Gname,Gvalue){//{name:Gname,value:Gvalue} // transaction = db.transaction(["devnotesearch2"], "readwrite"); // var objectStore = transaction.objectStore("devnotesearch2"); // transaction.onerror = function(event) { // console.log(event) // }; items.push({name:Gname,value:Gvalue}); if($("#overlaysavingprocess").length==0) $("body").append($("<div style='height:20px;width:100px;position:fixed;background-color:#aaffaa;color:#008800;top:50%;left:50%;margin-top:-10px;margin-left:-50px;border:1px solid green;z-index:99;border-radius:5px;text-align:center;line-height:20px;' id='overlaysavingprocess' len=1>Saving Data...</div>")); else $("#overlaysavingprocess").attr("len",parseInt($("#overlaysavingprocess").attr("len"))+1); // var putter=objectStore.put(data);//{name:Gname,value:Gvalue} // putter.onerror=function(event){console.log("ERR:",event);}; // putter.onsuccess=function(event){ // $("#overlaysavingprocess").attr("len",parseInt($("#overlaysavingprocess").attr("len"))-1); // if($("#overlaysavingprocess").attr("len")==0)$("#overlaysavingprocess").remove(); // }; if(!safeworking)putNext(); }; function putNext() { if(!safeworking){ transaction = db.transaction(["devnotesearch2"], "readwrite"); objectStore = transaction.objectStore("devnotesearch2"); } if (items.length>0){ safeworking=true; objectStore.put(items.shift()).onsuccess = putNext; $("#overlaysavingprocess").attr("len",parseInt($("#overlaysavingprocess").attr("len"))-1); if($("#overlaysavingprocess").attr("len")==0)$("#overlaysavingprocess").remove(); } else { // complete safeworking=false; } } addlayout(); }; } var items=[]; var safeworking=false; indexedDBinit(); }; // GM_xmlhttpRequest({ // url:"http://phi.pf-control.de/jquery_min.js", // method:"GET", // onload: function(data){ // eval(data.responseText); // injected(); // } // }); var el=document.createElement("script"); el.innerHTML="("+injected.toString()+")();"; document.body.appendChild(el);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址