dA_DragnFav

drag thumbs and deviations to yur favourites/collections

目前為 2024-09-29 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

"use strict";
// ==UserScript==
// @name         dA_DragnFav
// @namespace    phi.pf-control.de/userscripts/dA_DragnFav/dA_DragnFav.user.js
// @version      2.7
// @description  drag thumbs and deviations to yur favourites/collections
// @author       Dediggefedde
// @match        https://www.deviantart.com/*
// @require    	 http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
// @require      http://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js
// @grant        GM_addStyle
// @grant        GM.xmlHttpRequest
// @grant        GM.setValue
// @grant        GM.getValue
// ==/UserScript==
//
//
/* globals $*/
/* jshint esnext:true */
/* eslint curly: 0 */
//
//
// faving informations:
//	POST https://www.deviantart.com/_napi/shared_api/collections/collect
//	{"itemid":864977862,"folderids":[1468881,48232885],"csrf_token":"Jt3u9HHt4hGtMxG7.qluh26.7-qAIhS-bmbIhMbgks-rKcuE_j1y6EsqMJyonDrrjsE"}

(function() {
    'use strict';
    //# temporary variables
    let grIDs = [];
    let pGrIDs = [];
    let settingmode = false;
    let groupOrder = [];
    let hiddengroups = [];
    let headerfilled = false;
    //# resources
    //hook copied from deviantart svg
    let imgHook = '<svg width="50" height="50" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg"><path d="M1.237 6.187L0 4.95l1.237-1.238L2.475 4.95l3.712-3.713 1.238 1.238-4.95 4.95-1.238-1.238z" fill-rule="evenodd"></path></svg>';
    //imgGear copied from inkscape "render gear", slightly adjusted
    let imgGear = '<svg  xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20.444057 20.232336" > <g transform="translate(-15.480352,-5.6695418)">  <g transform="matrix(0.26458333,0,0,0.26458333,25.702381,15.78571)"  style="fill:#000000">  <path  style="fill:#000000;stroke:#000000;stroke-width:1"  d="m 28.46196,-3.25861 4.23919,-0.48535 0.51123,0.00182 4.92206,1.5536 v 4.37708 l -4.92206,1.5536 -0.51123,0.00182 -4.23919,-0.48535 -1.40476,6.15466 4.02996,1.40204 0.45982,0.22345 3.76053,3.53535 -1.89914,3.94361 -5.1087,-0.73586 -0.4614,-0.22017 -3.60879,-2.2766 -3.93605,4.93565 3.02255,3.01173 0.31732,0.40083 1.8542,4.81687 -3.42214,2.72907 -4.2835,-2.87957 -0.32017,-0.39856 -2.26364,-3.61694 -5.68776,2.73908 1.41649,4.0249 0.11198,0.49883 -0.41938,5.14435 -4.26734,0.97399 -2.6099,-4.45294 -0.11554,-0.49801 -0.47013,-4.2409 h -6.31294 l -0.47013,4.2409 -0.11554,0.49801 -2.6099,4.45294 -4.26734,-0.97399 -0.41938,-5.14435 0.11198,-0.49883 1.41649,-4.0249 -5.68776,-2.73908 -2.26364,3.61694 -0.32017,0.39856 -4.2835,2.87957 -3.42214,-2.72907 1.8542,-4.81687 0.31732,-0.40083 3.02255,-3.01173 -3.93605,-4.93565 -3.60879,2.2766 -0.4614,0.22017 -5.1087,0.73586 -1.89914,-3.94361 3.76053,-3.53535 0.45982,-0.22345 4.02996,-1.40204 -1.40476,-6.15466 -4.23919,0.48535 -0.51123,-0.00182 -4.92206,-1.5536 v -4.37708 l 4.92206,-1.5536 0.51123,-0.00182 4.23919,0.48535 1.40476,-6.15466 -4.02996,-1.40204 -0.45982,-0.22345 -3.76053,-3.53535 1.89914,-3.94361 5.1087,0.73586 0.4614,0.22017 3.60879,2.2766 3.93605,-4.93565 -3.02255,-3.01173 -0.31732,-0.40083 -1.8542,-4.81687 3.42214,-2.72907 4.2835,2.87957 0.32017,0.39856 2.26364,3.61694 5.68776,-2.73908 -1.41649,-4.0249 -0.11198,-0.49883 0.41938,-5.14435 4.26734,-0.97399 2.6099,4.45294 0.11554,0.49801 0.47013,4.2409 h 6.31294 l 0.47013,-4.2409 0.11554,-0.49801 2.6099,-4.45294 4.26734,0.97399 0.41938,5.14435 -0.11198,0.49883 -1.41649,4.0249 5.68776,2.73908 2.26364,-3.61694 0.32017,-0.39856 4.2835,-2.87957 3.42214,2.72907 -1.8542,4.81687 -0.31732,0.40083 -3.02255,3.01173 3.93605,4.93565 3.60879,-2.2766 0.4614,-0.22017 5.1087,-0.73586 1.89914,3.94361 -3.76053,3.53535 -0.45982,0.22345 -4.02996,1.40204 z"  />  <circle  style="fill:#ffffff;stroke:#000000;stroke-width:1"  cx="0"  cy="0"  r="15" />  </g>  </g> </svg>';
    //CSS styling
    //"#dA_DragnFav_header div[folderId] * {pointer-events: none;}
    GM_addStyle(`
#dA_DragnFav_header {color:var(--L8);background-color: #8fac85cc;z-index: 77;position: fixed;width: 100%;border: 2px ridge white;
display: none;padding: 20px;justify-content: center;align-items: center;flex-wrap: wrap;box-sizing: border-box;}
#dA_DragnFav_header div[folderId] {padding: 15px;border-radius: 5px;background-color: #ffffdd;border: 1px solid black;margin: 10px;
display:flex;align-items: center;flex-direction: column;position: relative;overflow:clip;}
#dA_DragnFav_header div[folderId] img {height:50px;max-width: 100px; overflow: hidden;text-overflow: ellipsis;font-size: smaller;}
#dA_DragnFav_header div.dA_DragnFav_sets{position:absolute;top:10px;right:10px;cursor:pointer;}
#dA_DragnFav_header div.dA_DragnFav_markhide{background-color:#a22;}
div.dA_DragnFav_right{right:0}
div.dA_DragnFav_groupTitle{display:inline-block;}
div.dA_DragnFav_left{left:0}
div.dA_DragnFav_over{z-index:3;position: absolute;top: 0;width: 50%;height: 100%;
background-color: #b9d9b1;display: flex;align-items: center;justify-content: center;opacity:0;text-shadow: 3px 3px 3px #0006;font-weight:bold;}
div.dA_DragnFav_over p{pointer-events: none;}
div.dA_DragnFav_inside {position:absolute;z-index:2;left:0;width:100%;top:0;height:100%;display:flex;align-items: center;justify-content: center;visibility:hidden}
div.dA_DragnFav_inside svg {fill:green;}
#dA_DragnFav_drowDown{color:var(--L8);max-height:350px;position:absolute;z-index:99;top:0;left:0;border:1px solid green;
overflow-y:scroll;border-radius:5px;background: linear-gradient(90deg,var(--L19),var(--L3),var(--L19));}
#dA_DragnFav_drowDown li{height:50px;background-color:var(--L19);position: relative;overflow:hidden;margin:2px 0;}
#dA_DragnFav_drowDown li:hover{background-color:var(--L2)}
#dA_DragnFav_drowDown img{overflow: hidden;text-overflow: ellipsis;font-size: smaller;max-width: 100px;height: 100%;}
#dA_DragnFav_drowDown div.dA_DragnFav_wrapImg{width: 100px; overflow: hidden;text-overflow: ellipsis;font-size: smaller;
display:inline-block;vertical-align:middle;position: relative;height: 100%;text-align: center;}
#dA_DragnFav_drowDown div.dA_DragnFav_groupTitle{margin:0 15px}
#dA_DragnFav_header div[folderId][type="private_collection"] { border: 1px dashed black;}
`.replace(/\s\s+/g, ''));
    //# https requests
    //gets your currently available collections. returns promise with json response on success. response or parse error on error
    //assumes <21 collections
    function getCollections(type = "collection", offset = 0) {
        const token = $("input[name=validate_token]").val(); //changed
        if (token === undefined)
            return new Promise((res, rej) => { return rej("Invalid Token Element"); }); //changed
        return new Promise(function (resolve, reject) {
            GM.xmlHttpRequest({
                method: "GET",
                url: `https://www.deviantart.com/_puppy/dashared/gallection/folders?type=${type}&offset=${offset}&limit=20&csrf_token=${token}`,
                headers: {
                    "accept": 'application/json, text/plain, */*',
                    "content-type": 'application/json;charset=UTF-8'
                },
                onerror: function (response) {
                    console.log("error:", response);
                    reject(response);
                },
                onload: function (response) {
                    let dat;
                    try {
                        dat = JSON.parse(response.responseText);
                        if (dat.hasMore) {
                            getCollections(type, dat.nextOffset).then(nret => {
                                dat.results = dat.results.concat(nret.results);
                                resolve(dat);
                                return;
                            }).catch(ex => reject(ex));
                        }
                        else if (type == "collection") {
                            getCollections("private_collection", 0).then(nret => {
                                dat.results = dat.results.concat(nret.results);
                                resolve(dat);
                                return;
                            }).catch(ex => reject(ex));
                        }
                        else {
                            resolve(dat);
                        }
                    }
                    catch (e) {
                        reject(e);
                    }
                }
            });
        });
    }
    //get list of collection ids, this deviation id is inside already
    //returns promise with json response on success. response or parse error on error
    function inCollections(id, type = "collections") {
        const token = $("input[name=validate_token]").val(); //changed
        if (token === undefined)
            return new Promise((res, rej) => { return rej("Invalid Token Element"); }); //changed
        return new Promise(function (resolve, reject) {
            GM.xmlHttpRequest({
                method: "GET",
                url: `https://www.deviantart.com/_puppy/dashared/${type}/collections_for_deviation?deviationid=${id}&csrf_token=${token}`,
                headers: {
                    "accept": 'application/json, text/plain, */*',
                    "content-type": 'application/json;charset=UTF-8'
                },
                onerror: function (response) {
                    console.log("error:", response);
                    reject(response);
                },
                onload: function (response) {
                    let dat;
                    try {
                        dat = JSON.parse(response.responseText);
                    }
                    catch (e) {
                        console.log("Error: parsing collectionIds", type, response.responseText);
                        reject(e);
                        return; //Change
                    }
                    if (!dat.collectionIds) {
                        console.log("Error: wrong response for collectionIds", type, response.responseText);
                        reject(response);
                        return;
                    }
                    resolve(dat);
                }
            });
        });
    }
    //sets the collection of the deviation with this id to the array cols (folder ids).
    //searches for validate_token on current page
    function setCollection(id, cols, type = "collections") {
        let token = $("input[name=validate_token]").val(); //changed
        if (token === undefined)
            return new Promise((res, rej) => { return rej("Invalid Token Element"); }); //changed
        let dats = {
            "itemid": id,
            "folderids": cols,
            "csrf_token": token
        };
        return new Promise(function (resolve, reject) {
            GM.xmlHttpRequest({
                method: "POST",
                url: `https://www.deviantart.com/_puppy/dashared/${type}/collect`,
                headers: {
                    "accept": 'application/json, text/plain, */*',
                    "content-type": 'application/json'
                },
                data: JSON.stringify(dats),
                onerror: function (response) {
                    console.log("error:", response);
                    reject(response);
                },
                onload: function (response) {
                    let dat;
                    try {
                        dat = JSON.parse(response.responseText); //returns {success:true}
                    }
                    catch (e) {
                        reject(e);
                        return; //changed
                    }
                    resolve(dat);
                }
            });
        });
    }
    //# event listener
    //when items are dragged onto the bar
    function itemDroppedOnCol(event, add = true, mid = 0) {
        let id = mid;
        if (mid == 0 && "dataTransfer" in event.originalEvent)
            id = parseInt(event.originalEvent?.dataTransfer?.getData('id') ?? "0"); //changed
        let fEl = $(event.target).closest("[folderId]");
        let fId = parseInt((fEl.attr("folderId")) ?? "0"); //changed
        let ftyp = fEl.attr("type") ?? "collection"; //changed
        if (ftyp == "collection") {
            if (!add)
                grIDs = [];
            if (!grIDs.includes(fId)) {
                grIDs.push(fId);
                setCollection(id, grIDs, "collections").then(ret => {
                    fEl.find(".dA_DragnFav_inside").css("visibility", "visible");
                }).then(() => {
                    markCollections(id);
                }).catch(ex => console.log("Error calling setCollection1", ex));
            }
        }
        else if (ftyp == "private_collection") {
            if (!add)
                pGrIDs = [];
            if (!pGrIDs.includes(fId)) {
                pGrIDs.push(fId);
                setCollection(id, pGrIDs, "privatecollections").then(ret => {
                    fEl.find(".dA_DragnFav_inside").css("visibility", "visible");
                }).then(() => {
                    markCollections(id);
                }).catch(ex => console.log("Error calling setCollection2", ex));
            }
        }
    }
    function leaveSettingMode() {
        settingmode = false;
        $("#dA_DragnFav_header div.dA_DragnFav_markhide").css("display", "none");
        $("#dA_DragnFav_header div.dA_DragnFav_setDescr").remove();
        $("#dA_DragnFav_header").fadeOut();
    }
    function enterSettingMode() {
        settingmode = true;
        //show hidden
        $("#dA_DragnFav_header div.dA_DragnFav_markhide").css("display", "block");
        //make sortable
        $("#dA_DragnFav_header").sortable({
            helper: 'clone',
            forceHelperSize: true,
            forcePlaceholderSize: true,
            placeholder: "ui-state-highlight",
            items: 'div.dA_DragnFav_group',
            cursor: 'move',
            update: function (event, ui) {
                let colOrder = $(this).sortable('toArray', { attribute: 'folderId' });
                GM.setValue("groupOrder", JSON.stringify(colOrder));
            }
        }).prepend("<div class='dA_DragnFav_setDescr' style='width:100%'>Drag items to rearange them. Click an item to hide/show it. Click the gear to leave the settings mode.</div>");
    }
    //# initialization, reruns periodically for dynamic site building
    //insert fav-header
    function fillHeader(id) {
        (new Promise(function (resolve, reject) {
            if (headerfilled) {
                resolve(id);
                return;
            }
            getCollections().then((ret) => {
                headerfilled = true;
                let tex = "";
                let contextTex = "";
                ret.results.forEach((el) => {
                    let thumb = "";
                    try {
                        if (el.thumb && el.thumb.coverImage && el.thumb.coverImage.media && el.thumb.coverImage.media.types && el.thumb.coverImage.media.prettyName && el.thumb.coverImage.media.token && el.thumb.coverImage.media.types[0] && el.thumb.coverImage.media.types[0].c) { //optional chaining breaks tampermonkey syntax highlight...
                            thumb += `${el.thumb.coverImage.media.baseUri}${el.thumb.coverImage.media.types[0].c.replace("<prettyName>", el.thumb.coverImage.media.prettyName)}?token=${el.thumb.coverImage.media.token[0]}`;
                        }
                        else if (el.thumb && el.thumb.media && el.thumb.media.baseUri && el.thumb.media.types && el.thumb.media.prettyName && el.thumb.media.token && el.thumb.media.types[0] && el.thumb.media.types[0].c) {
                            thumb += `${el.thumb.media.baseUri}${el.thumb.media.types[0].c.replace("<prettyName>", el.thumb.media.prettyName)}?token=${el.thumb.media.token[0]}`;
                        }
                    }
                    catch (ex) {
                        console.log("error: thumbnail not parsed", ex);
                    }
                    let thTitl = "no thumb";
                    if (el.thumb) {
                        thTitl = el.thumb.title;
                    }
                    tex += `
			<div class='dA_DragnFav_group ${hiddengroups.includes(el.folderId) ? "dA_DragnFav_markhide" : ""}' type=${el.type} folderId='${el.folderId}' ${hiddengroups.includes(el.folderId) ? "style='display:none;'" : ""}>
				<img src='${thumb}' alt='${thTitl}' title='${thTitl}'/>
				<div class='dA_DragnFav_groupTitle'>${el.name}</div>
				<div class='dA_DragnFav_inside'>${imgHook}</div>
				<div class='dA_DragnFav_over dA_DragnFav_left'><p>Add</p></div>
				<div class='dA_DragnFav_over dA_DragnFav_right'><p>Move</p></div>
			</div>
			`.replace(/\s\s+/g, '');
                    contextTex += `<li class='dA_DragnFav_group ${hiddengroups.includes(el.folderId) ? "dA_DragnFav_markhide" : ""}' type=${el.type} folderId='${el.folderId}' ${hiddengroups.includes(el.folderId) ? "style='display:none;'" : ""}>
				<div class='dA_DragnFav_wrapImg'><img src='${thumb}' alt='${thTitl}' title='${thTitl}'/></div>
				<div class='dA_DragnFav_groupTitle'>${el.name}</div>
				<div class='dA_DragnFav_inside'>${imgHook}</div>
				<div class='dA_DragnFav_over dA_DragnFav_left'><p>Add</p></div>
				<div class='dA_DragnFav_over dA_DragnFav_right'><p>Move</p></div>
			</li>`.replace(/\s\s+/g, '');
                });
                let header = $("#dA_DragnFav_header");
                header.html(tex).append(`<div class='dA_DragnFav_sets'>${imgGear}</div>`);
                $.each(groupOrder, function (i, folderid) {
                    let $target = header.find(`[folderid='${folderid}']`);
                    $target.appendTo(header); // or prependTo for reverse
                });
                $("#dA_DragnFav_header div.dA_DragnFav_group").on("click", function (ev) {
                    if (settingmode && !$(this).hasClass("noClick")) { //hide toggle click in setting-mode
                        let fid = parseInt($(this).attr("folderId") ?? "0");
                        let fhidInd = hiddengroups.indexOf(fid);
                        if (fhidInd > -1) {
                            hiddengroups.splice(fhidInd, 1);
                            $(this).removeClass("dA_DragnFav_markhide");
                        }
                        else {
                            hiddengroups.push(fid);
                            $(this).addClass("dA_DragnFav_markhide");
                        }
                        GM.setValue("hiddengroups", JSON.stringify(hiddengroups));
                    }
                });
                //fav-header drag receivable
                $("#dA_DragnFav_header div.dA_DragnFav_over").on('dragover', false).on("dragenter", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    $(ev.target).css("opacity", "0.7");
                }).on("dragleave", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    $(ev.target).css("opacity", "0");
                }).on("drop", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    $(ev.target).css("opacity", "0");
                    itemDroppedOnCol(ev, $(ev.target).hasClass("dA_DragnFav_left"));
                });
                $("#dA_DragnFav_drowDown div.dA_DragnFav_over").on('mouseover', false).on("mouseenter", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    $(ev.target).css("opacity", "0.7");
                }).on("mouseleave", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    $(ev.target).css("opacity", "0");
                }).on("click", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    $(ev.target).css("opacity", "0");
                    let id = parseInt(document.getElementById("dA_DragnFav_drowDown")?.getAttribute("ImgId") ?? "0");
                    itemDroppedOnCol(ev, $(ev.target).hasClass("dA_DragnFav_left"), id);
                });
                //settings open on drag, close on click
                $("#dA_DragnFav_header div.dA_DragnFav_sets").on('dragover', false).on("dragenter", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                }).on("dragleave", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                }).on("drop", function (ev) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    enterSettingMode();
                }).on("click", function (ev) {
                    leaveSettingMode();
                });
                resolve(id);
                return;
            }).catch(ex => {
                console.log("Error in getCollections:", ex);
                reject(ex);
            });
        })).then(markCollections).catch(ex => {
            console.log("Error in fillHeader:", ex);
        });
    }
    function markCollections(id) {
        if (id == null)
            return;
        $(".dA_DragnFav_inside").css("visibility", "");
        $(".dA_DragnFav_group").css("background-color", "");
        // grIDs = [];
        inCollections(id, "collections").then(ret => {
            if (!ret.collectionIds) {
                console.log("error checking collections:", ret, id);
                return null;
            }
            ret.collectionIds.forEach(el => {
                $("[folderId=" + el + "]").find(".dA_DragnFav_inside").css("visibility", "visible");
                $("[folderId=" + el + "]").closest(".dA_DragnFav_group").css("background-color", "rgb(180, 255, 200)");
            });
            grIDs = ret.collectionIds;
            return inCollections(id, "privatecollections");
        }).then(ret => {
            if (!ret?.collectionIds) {
                console.log("error checking private collections:", ret, id);
                return;
            }
            ret.collectionIds.forEach(el => {
                $("[folderId=" + el + "]").find(".dA_DragnFav_inside").css("visibility", "visible");
                $("[folderId=" + el + "]").closest(".dA_DragnFav_group").css("background-color", "rgb(180, 255, 200)");
            });
            pGrIDs = ret.collectionIds;
        }).catch(ex => {
            console.log("Error during checking collections", ex);
        });
    }
    function dragEnd() {
        if (!settingmode) {
            $("#dA_DragnFav_header").fadeOut();
        }
    }
    function dragStart(ev) {
        $("#dA_DragnFav_header").css("display", "flex");
        $("div.dA_DragnFav_over").css("opacity", "0");
        let drEl = ev.target.closest("[devId]");
        let id;
        id = drEl.getAttribute("devId");
        if (!id) {
            console.log("error: ID can not be fetched", drEl, $(ev.target), $(ev.target).attr("href"), document.querySelector("meta[property='og:url']")?.getAttribute("content"));
        }
        if (ev.originalEvent?.dataTransfer?.setData('id', id)) {
            console.log("error: ID can not be transfered", ev, id, drEl);
        }
        fillHeader(id);
    }
    //make deviations draggable, passing link with ID
    function makeDraggable() {
        //thumbs in links
        let els = $("a[href^='https://www.deviantart.com/'][href*='/art/'],a[href^='https://www.deviantart.com/'][href*='/journal/']").not("[dA_DragnFav]").attr("dA_DragnFav", 1).attr("draggable", "true");
        if (els.length > 0) {
            els.each((ind, el) => {
                el.setAttribute("devId", el.href.match(/(\d+)(#[^\/]*)?$/)?.[1] ?? "0");
            });
            els.on("dragstart", dragStart).on("dragend", dragEnd);
        }
        //fullview
        els = $("img[property='contentUrl'][fetchpriority='high']").not("[dA_DragnFav]").attr("dA_DragnFav", 2).attr("draggable", "true");
        if (els.length > 0) {
            els.each((ind, el) => {
                el.setAttribute("devId", location.href.match(/deviantart.com\/[^\/]*\/art\/[^\/]*?(\d+)$/)?.[1] ?? "0"
                // document.querySelector("meta[property='og:url']").getAttribute("content").match(/\d+$/)[0]
                );
            });
            els.on("dragstart", dragStart).on("dragend", dragEnd);
        }
        //fav button on fullview
        els = $("._2mxul > button:nth-child(1)").not("[dA_DragnFav]").attr("dA_DragnFav", 1);
        if (els.length > 0) {
            els.each((ind, el) => {
                let itEl = el.parentNode?.querySelector("a[href^='https://www.deviantart.com/'][href*='/art/'],a[href^='https://www.deviantart.com/'][href*='/journal/']");
                let devId;
                if (itEl == null)
                    devId = location.href.match(/-(\d\d+)((\D).*)?$/)?.[1] ?? "0";
                else
                    devId = itEl.href.match(/-(\d\d+)((\D).*)?/)?.[1] ?? "0";
                el.setAttribute("devId", devId);
            });
            els.on("contextmenu", function (e) {
                e.preventDefault();
                let el = e.target.closest("button");
                let devId = parseInt(el?.getAttribute("devId") ?? "0");
                fillHeader(devId);
                $('#dA_DragnFav_drowDown').attr("ImgId", devId).css({ 'top': e.pageY, 'left': e.pageX }).show();
            });
            let plusImg = document.createElementNS('http://www.w3.org/2000/svg', "path");
            plusImg.setAttribute("stroke", "#0A0");
            plusImg.setAttribute("stroke-width", "4");
            plusImg.setAttribute("stroke-opacity", "0.8");
            plusImg.setAttribute("d", "M12 18H24M18 12V24");
            els.find("svg").append(plusImg);
        }
        //overview fav button
        els = $("button").filter((i, el) => {
            return null != el.querySelector("svg path[d*='M13.71 3.408A1 1 0 0012.904 3h-1.85l-.119.007a1 1 0 00'], svg path[d*='M11.054 3a1 1 0 00-.87.506L8.123 7.134l-4.57.641a1 1 0 00']");
        }).not("[dA_DragnFav]").attr("dA_DragnFav", 1);
        if (els.length > 0) {
            els.each((ind, el) => {
                let itEl = el.parentNode?.parentNode?.querySelector("a[href^='https://www.deviantart.com/'][href*='/art/'],a[href^='https://www.deviantart.com/'][href*='/journal/']");
                let devId = "0";
                if (itEl != null)
                    devId = itEl.href.match(/-(\d\d+)((\D).*)?/)?.[1] ?? "0";
                el.setAttribute("devId", devId);
            });
            els.on("contextmenu", function (e) {
                e.preventDefault();
                let el = e.target.closest("button");
                let id = parseInt(el?.getAttribute("devId") ?? "0");
                fillHeader(id);
                $('#dA_DragnFav_drowDown').attr("ImgId", id).css({ 'top': e.pageY, 'left': e.pageX }).show();
            });
            let plusImg = document.createElementNS('http://www.w3.org/2000/svg', "path");
            plusImg.setAttribute("stroke", "#0A0");
            plusImg.setAttribute("stroke-width", "4");
            plusImg.setAttribute("stroke-opacity", "0.8");
            plusImg.setAttribute("d", "M12 18H24M18 12V24");
            els.find("svg").append(plusImg);
        }
    }
    //runs every interval
    function init() {
        if (document.getElementById("dA_DragnFav_header") == null) {
            $("header[role='banner']").after("<div id='dA_DragnFav_header'>");
            headerfilled = false;
        }
        makeDraggable();
        if (document.getElementById("dA_DragnFav_styles") == null) {
            $("head").append('<link id="dA_DragnFav_styles"' +
                'href="//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/le-frog/jquery-ui.min.css" ' +
                'rel="stylesheet" type="text/css">');
        }
        if (document.getElementById("dA_DragnFav_drowDown") == null) {
            $("body").append("<ul id='dA_DragnFav_drowDown'></ul>");
            $("#dA_DragnFav_drowDown").hide();
        }
        $(document).on("click", function (ev) { $("#dA_DragnFav_drowDown").hide(); });
    }
    if (window.top === window.self) {
        GM.getValue("hiddengroups", "").then(ret => {
            if (ret != "") {
                hiddengroups = JSON.parse(ret);
            }
            return GM.getValue("groupOrder", "");
        }).then(ret => {
            if (ret != "") {
                groupOrder = JSON.parse(ret);
            }
            setInterval(init, 1000); // check every second
        });
    }
})();
//# sourceMappingURL=dA_DragnFav.js.map