您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Format the license information from a thing page
- // ==UserScript==
- // @name Thing Remix Attribution Maker
- // @namespace http://poikilos.org/
- // @version 4.0.0
- // @description Format the license information from a thing page
- // @author Poikilos (Jake Gustafson)
- // @match https://www.thingiverse.com/thing:*
- // @grant none
- // @run-at document-end
- // ==/UserScript==
- (function() {
- // now its @match again :eyeroll: -- eslint says it may be obsolete in Manifest v3 in early 2023
- // formerly @include https://www.thingiverse.com/thing:*
- // formerly @match https://www.thingiverse.com/thing:*
- var verbose = true;
- var checkTimer = null;
- var licenseClauseImgPrefix = "License__img";
- var licenseAnchorPrefix = "License__link"; // INFO: License__link* could be author OR license link; author also has License__creator* class.
- var titlePrefix = "ThingTitle__modelName";
- var headingCreatedPrefix = "ThingTitle__createdBy";
- var madeDivClassName = "ThingTitle__madeBy"; // doneDivPrefixes' container[0]'s class (a.k.a. .className)
- var doneDivPrefixes = [titlePrefix, headingCreatedPrefix];
- var clausesContainerPrefix = "License__ccLicense";
- var doneDivPrefixesMain = [clausesContainerPrefix];
- var urlSmallNames = {
- "/by/1.0": "CC BY 1.0",
- "/by/2.0": "CC BY 2.0",
- "/by/2.5": "CC BY 2.5",
- "/by/3.0": "CC BY 3.0",
- "/by/4.0": "CC BY 4.0",
- "/by-sa/1.0": "CC BY-SA 1.0",
- "/by-sa/2.0": "CC BY-SA 2.0",
- "/by-sa/2.5": "CC BY-SA 2.5",
- "/by-sa/3.0": "CC BY-SA 3.0",
- "/by-sa/4.0": "CC BY-SA 4.0",
- "/by-nc/1.0": "CC BY-NC 1.0",
- "/by-nc/2.0": "CC BY-NC 2.0",
- "/by-nc/2.5": "CC BY-NC 2.5",
- "/by-nc/3.0": "CC BY-NC 3.0",
- "/by-nc/4.0": "CC BY-NC 4.0",
- "/by-nc-sa/1.0": "CC BY-NC-SA 1.0",
- "/by-nc-sa/2.0": "CC BY-NC-SA 2.0",
- "/by-nc-sa/2.5": "CC BY-NC-SA 2.5",
- "/by-nc-sa/3.0": "CC BY-NC-SA 3.0",
- "/by-nc-sa/4.0": "CC BY-NC-SA 4.0",
- "/by-nd/1.0": "CC BY-ND 1.0",
- "/by-nd/2.0": "CC BY-ND 2.0",
- "/by-nd/2.5": "CC BY-ND 2.5",
- "/by-nd/3.0": "CC BY-ND 3.0",
- "/by-nd/4.0": "CC BY-ND 4.0",
- "/by-nd-nc/1.0": "CC BY-ND-NC 1.0",
- "/by-nc-nd/2.0": "CC BY-NC-ND 2.0",
- "/by-nc-nd/2.5": "CC BY-NC-ND 2.5",
- "/by-nc-nd/3.0": "CC BY-NC-ND 3.0",
- "/by-nc-nd/4.0": "CC BY-NC-ND 4.0",
- "creativecommons.org/share-your-work/public-domain/cc0": "CC0",
- "creativecommons.org/publicdomain/zero/1.0": "CC0 1.0",
- };
- var bigNames = {
- "CC BY 1.0": "Creative Commons Attribution 1.0 Generic",
- "CC BY 2.0": "Creative Commons Attribution 2.0 Generic",
- "CC BY 2.5": "Creative Commons Attribution 2.5 Generic",
- "CC BY 3.0": "Creative Commons Attribution 3.0 Unported",
- "CC BY 4.0": "Creative Commons Attribution 4.0 International",
- "CC BY-SA 1.0": "Creative Commons Attribution-ShareAlike 1.0 Generic",
- "CC BY-SA 2.0": "Creative Commons Attribution-ShareAlike 2.0 Generic",
- "CC BY-SA 2.5": "Creative Commons Attribution-ShareAlike 2.5 Generic",
- "CC BY-SA 3.0": "Creative Commons Attribution-ShareAlike 3.0 Unported",
- "CC BY-SA 4.0": "Creative Commons Attribution-ShareAlike 4.0 International",
- "CC BY-NC 1.0": "Creative Commons Attribution-NonCommercial 1.0 Generic",
- "CC BY-NC 2.0": "Creative Commons Attribution-NonCommercial 2.0 Generic",
- "CC BY-NC 2.5": "Creative Commons Attribution-NonCommercial 2.5 Generic",
- "CC BY-NC 3.0": "Creative Commons Attribution-NonCommercial 3.0 Unported",
- "CC BY-NC 4.0": "Creative Commons Attribution-NonCommercial 4.0 International",
- "CC BY-NC-SA 1.0": "Creative Commons Attribution-NonCommercial-ShareAlike 1.0 Generic",
- "CC BY-NC-SA 2.0": "Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic",
- "CC BY-NC-SA 2.5": "Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Generic",
- "CC BY-NC-SA 3.0": "Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported",
- "CC BY-NC-SA 4.0": "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International",
- "CC BY-ND 1.0": "Creative Commons Attribution-NoDerivs 1.0 Generic",
- "CC BY-ND 2.0": "Creative Commons Attribution-NoDerivs 2.0 Generic",
- "CC BY-ND 2.5": "Creative Commons Attribution-NoDerivs 2.5 Generic",
- "CC BY-ND 3.0": "Creative Commons Attribution-NoDerivs 3.0 Unported",
- "CC BY-ND 4.0": "Creative Commons Attribution-NoDerivatives 4.0 International",
- "CC BY-ND-NC 1.0": "Creative Commons Attribution-NoDerivs-NonCommercial 1.0 Generic",
- "CC BY-NC-ND 2.0": "Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Generic",
- "CC BY-NC-ND 2.5": "Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Generic",
- "CC BY-NC-ND 3.0": "Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported",
- "CC BY-NC-ND 4.0": "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International",
- "CC0": "No Rights Reserved",
- "CC0 1.0": "Creative Commons CC0 1.0 Universal",
- };
- function getElementsWhereClassStartsWith(str) {
- if (verbose) {
- console.log("");
- console.log("getElementsWhereClassStartsWith(\""+str+"\")...");
- }
- var els = [];
- var all = document.getElementsByTagName("*");
- for (var i=0, max=all.length; i < max; i++) {
- var el = all[i];
- if (el.className && !el.className.startsWith) {
- // Why This started happening (className.startsWith not existing) when className is true is unclear.
- if (el.class) {
- console.log("Warning: no el.className.startsWith for class="+el.class+" + el.className="+el.className);
- }
- else {
- console.log("Warning: no el.className.startsWith for el.className="+el.className);
- }
- }
- if (el.class && el.class.startsWith(str)) {
- els.push(el);
- }
- else if (el.className && el.className.startsWith && el.className.startsWith(str)) {
- els.push(el);
- }
- }
- if (verbose) {
- console.log("- FOUND " + els.length);
- }
- return els;
- }
- function getElementsWhere(tagName, attributeName, value) {
- if (verbose) {
- console.log("");
- console.log("getSubElementsWhere(\""+tagName+"\", \""+attributeName+"\", \""+value+"\")...");
- }
- var els = [];
- var all = document.getElementsByTagName(tagName);
- for (var i=0, max=all.length; i < max; i++) {
- var el = all[i];
- if (el.getAttribute(attributeName) == value) {
- els.push(el);
- }
- }
- if (verbose) {
- console.log("- FOUND " + els.length);
- }
- return els;
- }
- function getDivsWhereClassStartsWith(str) {
- if (verbose) {
- console.log("");
- console.log("FIND getDivsWhereClassStartsWith(\"" + str + "\")...");
- }
- var els = [];
- var all = document.getElementsByTagName("div");
- for (var i=0, max=all.length; i < max; i++) {
- var el = all[i];
- if (el.className.startsWith(str)) {
- els.push(el);
- // console.log("- FOUND (" + els.length + ")");
- }
- else {
- // console.log("- " + el.className + " does not start with it.");
- }
- }
- if (verbose) {
- // console.log("Div count: " + all.length);
- console.log("- FOUND " + els.length);
- }
- return els;
- }
- function getWhereClassStartsWithIn(el, str) {
- if (el === undefined) {
- console.log("[getWhereClassStartsWithIn] Error: el is undefined.");
- return [];
- }
- if (verbose) {
- console.log("");
- console.log("DETECT getWhereClassStartsWithIn(el, \""+str+"\")...");
- // console.log(" el: " + JSON.stringify(el)); // DON'T do (could be circular)
- console.log(" el.className: "+el.className);
- console.log(" el.childNodes.length:"+el.childNodes.length+"...");
- }
- var els = [];
- var all = el.childNodes;
- for (var i=0, max=all.length; i < max; i++) {
- var thisEl = all[i];
- if ((thisEl.className != undefined) && thisEl.className.startsWith(str)) {
- els.push(thisEl);
- }
- else {
- // console.log("- "+el.className+" does not start with "+str+".");
- }
- }
- if (verbose) {
- console.log("- FOUND " + els.length + " " + str);
- // console.log("- done (div count: " + all.length + ")");
- }
- return els;
- }
- function hasAllDivPrefixes(prefixes) {
- var found = 0;
- for (var i=0, max=prefixes.length; i < max; i++) {
- if (getDivsWhereClassStartsWith(prefixes[i]).length > 0) {
- found++;
- }
- }
- return found >= prefixes.length;
- }
- function hasAllClasses(classNames) {
- var found = 0;
- for (var i=0, max=classNames.length; i < max; i++) {
- if (document.getElementsByClassName(classNames[i]).length > 0) {
- found++;
- }
- else {
- if (verbose) {
- console.error("The className " + classNames[i] + " was not found.")
- }
- }
- }
- return found >= classNames.length;
- }
- function elementHasAllPrefixes(el, prefixes) {
- var found = 0;
- for (var i=0, max=prefixes.length; i < max; i++) {
- if (getWhereClassStartsWithIn(el, prefixes[i]).length > 0) {
- found++;
- }
- }
- return found >= prefixes.length;
- }
- function getImgsWhereClassStartsWith(str) {
- var els = [];
- var all = document.images; // document.getElementsByTagName("img");
- for (var i=0, max=all.length; i < max; i++) {
- var el = all[i];
- if (el.className.startsWith(str)) {
- els.push(el);
- }
- }
- return els;
- }
- function getAnchorsWhereClassStartsWith(str) {
- if (verbose) {
- console.log("getAnchorsWhereClassStartsWith(\""+str+"\")...")
- }
- var els = [];
- var all = document.getElementsByTagName("a");
- for (var i=0, max=all.length; i < max; i++) {
- var el = all[i];
- if (el.className.startsWith(str)) {
- els.push(el);
- }
- }
- if (verbose) {
- console.log("- FOUND " + els.length);
- // console.log("- done (div count: " + all.length + ")");
- }
- return els;
- }
- function getAnchorsWhereHrefContains(str) {
- // Example: str=field_art_tags_tid= finds <a href="/art-search-advanced?field_art_tags_tid=grass">...
- if (verbose) {
- console.log("getAnchorsWhereHrefContains(\""+str+"\")...")
- }
- var els = [];
- var all = document.getElementsByTagName("a");
- for (var i=0, max=all.length; i < max; i++) {
- var el = all[i];
- if (el.href.includes(str)) {
- els.push(el);
- }
- }
- if (verbose) {
- console.log("- FOUND " + els.length);
- // console.log("- done (div count: " + all.length + ")");
- }
- return els;
- }
- function elementAToMarkdown(element) {
- var ret = null;
- if (element.href) {
- ret = "[" + element.textContent + "](" + element.href + ")";
- }
- else {
- if (verbose) {
- console.warn("- elementAToMarkdown " + element.textContent + " href is blank in elementAToMarkdown: \"" + element.href + "\"")
- }
- ret = element.textContent;
- }
- return ret;
- }
- function getMarkdown(info) {
- if (verbose) {
- console.log("");
- console.log("getMarkdown...");
- }
- var outputStr = "";
- outputStr = "## License";
- if (info.license) {
- outputStr += "\n- ";
- if (info.licenseHref) {
- outputStr += "[" + info.license + "](" + info.licenseHref + ")";
- }
- else {
- // console.log("* skipping long name detection since a license was detected: \""+info.license+"\"");
- outputStr += info.license;
- }
- if (info.shortLicense) {
- outputStr += "\n (" + info.shortLicense + ")";
- }
- }
- else {
- outputStr += "\n- LICENSE: [insert license name (&URL unless in each content ZIP) of original thing here]";
- }
- if (info.author) {
- outputStr += "\n- by " + info.author + " and <insert remixer's name here>";
- }
- if (info.title) {
- outputStr += "\n- based on";
- if (info.titleHref) {
- outputStr += " [" + info.title + "](" + info.titleHref + ")";
- }
- else {
- outputStr += " " + info.title;
- }
- if (info.author) {
- if (info.authorHref) {
- outputStr += " by [" + info.author + "](" + info.authorHref + ")";
- }
- else {
- outputStr += " by " + info.author;
- }
- }
- if (info.year) {
- outputStr += " ";
- if (info.month) {
- outputStr += info.month + " ";
- if (info.day) {
- outputStr += info.day + ", "
- }
- }
- outputStr += info.year;
- }
- }
- return outputStr;
- }
- function populateCorrespondingLicenseFields(info) {
- var licenseShortStr = "";
- if (info.license) {
- var versionIsFound = false;
- var licenseLower = info.license.toLowerCase();
- if (info.license.startsWith("Creative Commons") || info.license.startsWith("CC")) {
- if (info.license.startsWith("CC0 1.0") || info.license.startsWith("Creative Commons 0 1.0") || info.license.startsWith("Creative Commons Zero 1.0")) {
- if (!info.licenseHref) {
- info.licenseHref = "https://creativecommons.org/publicdomain/zero/1.0/";
- }
- licenseShortStr = "CCO 1.0";
- }
- else if ((info.license == "Creative Commons 0") || (info.license == "Creative Commons Zero")) {
- licenseShortStr = "CCO";
- }
- else {
- console.log("Looking for license clauses in license name \""+licenseLower+"\"...");
- licenseShortStr = "CC ";
- if (licenseLower.includes("attribution")) {
- licenseShortStr += "BY";
- }
- if (licenseLower.includes("non-commercial") || licenseLower.includes("noncommercial") || licenseLower.includes("non commercial")) {
- licenseShortStr += "-NC";
- }
- if (licenseLower.includes("no derivatives") || licenseLower.includes("noderivs") || licenseLower.includes("no-derivatives") || licenseLower.includes("noderivatives")) {
- licenseShortStr += "-ND";
- }
- if (licenseLower.includes("sharealike") || licenseLower.includes("share-alike") || licenseLower.includes("share alike") ) {
- licenseShortStr += "-SA";
- }
- if (info.license.includes("1.0")) {
- licenseShortStr += " 1.0";
- versionIsFound = true;
- }
- else if (info.license.includes("2.0")) {
- licenseShortStr += " 2.0";
- versionIsFound = true;
- }
- else if (info.license.includes("3.0")) {
- licenseShortStr += " 3.0";
- versionIsFound = true;
- }
- else if (info.license.includes("4.0")) {
- licenseShortStr += " 4.0";
- versionIsFound = true;
- }
- else if (exactLicenseVersion !== null) {
- licenseShortStr += " " + exactLicenseVersion;
- versionIsFound = true;
- }
- }
- }
- console.log("licenseShortStr: " + licenseShortStr);
- if (!info.licenseHref) {
- var parts = licenseShortStr.split(" ");
- if (parts.length == 3) {
- var partialHref = null;
- // such as ["CC", "BY-SA", "3.0"]
- if (parts[1] == "BY") {
- partialHref = "http://creativecommons.org/licenses/by/";
- }
- else if (parts[1] == "BY-SA") {
- partialHref = "http://creativecommons.org/licenses/by-sa/";
- }
- else if (parts[1] == "BY-NC-SA") {
- partialHref = "http://creativecommons.org/licenses/by-nc-sa/";
- }
- else if (parts[1] == "BY-NC-ND") {
- partialHref = "http://creativecommons.org/licenses/by-nc-nd/";
- }
- // NOTE: by-nc-nd-sa is NOT a valid license
- if (partialHref != null) {
- info.licenseHref = partialHref + parts[2] + "/";
- }
- }
- }
- }
- else if (info.licenseHref) {
- if (!licenseShortStr) {
- if (verbose) {
- console.log("Generating short license name from URL instead of from clauses...");
- }
- for (var key in urlSmallNames) {
- // Check if the property/key is defined in the object itself, not in parent
- if (urlSmallNames.hasOwnProperty(key)) {
- if (info.licenseHref.includes(key)) {
- licenseShortStr = urlSmallNames[key];
- if (verbose) {
- console.log("- got \""+licenseShortStr+"\" from \""+key+"\"")
- }
- break;
- }
- }
- }
- }
- else {
- console.log("* using existing licenseShortStr \""+licenseShortStr+"\"");
- }
- if (!licenseShortStr) {
- console.warn("Warning: The URL \""+info.licenseHref+"\" is not recognized (No key in Thing Remix Attribution Maker's urlSmallNames is a partial of the URL), so the long license name could not be generated.");
- }
- else {
- info.shortLicense = licenseShortStr;
- if (!info.license) {
- if (verbose) {
- console.log("Generating long license name from URL instead of from clauses...");
- }
- if (bigNames.hasOwnProperty(licenseShortStr)) {
- // ^ The clauses are only in this order for versions above 1.0!
- info.license = bigNames[licenseShortStr];
- if (verbose) {
- console.log("- got \""+info.license+"\"");
- }
- }
- else {
- console.warn("Warning: The short license name \""+licenseShortStr+"\" is not recognized (It is not a key in Thing Remix Attribution Maker's bigNames), so the long license name could not be generated.");
- }
- }
- }
- }
- if (!info.license) {
- console.warn("The license abbreviation cannot be generated because no license text was generated (no license elements were detected).");
- }
- else if (!info.shortLicense) {
- console.warn("The license abbreviation cannot be generated for an unknown license: " + info.license);
- }
- }
- function setClipboardText(text, callbackBtn) {
- var msg = "(ERROR: Your browser API is unknown.)";
- if (callbackBtn == null) {
- msg = "Error: no callbackBtn";
- console.log(msg);
- return msg;
- }
- var okMsg = " ✓";
- // See https://stackoverflow.com/questions/52177405/clipboard-writetext-doesnt-work-on-mozilla-ie
- if (navigator.clipboard != undefined) { // Chrome
- navigator.clipboard.writeText(text).then(
- function () {
- console.log('Async: Copying to clipboard was successful!');
- callbackBtn.innerHTML += okMsg;
- }, function (err) {
- console.error('Async: Could not copy text: ', err);
- callbackBtn.innerHTML += '<br/> (ERROR: Accessing the clipboard failed.)';
- }
- );
- msg = null;
- }
- else if (window.clipboardData) { // Internet Explorer
- window.clipboardData.setData("Text", text);
- msg = okMsg;
- }
- if (msg != null) {
- callbackBtn.innerHTML += msg;
- }
- }
- function getButtonContainer() {
- // var pageInfoEs = document.getElementsByClassName("item-page-info");
- var pageInfoEs = getElementsWhereClassStartsWith(madeDivClassName);
- if (pageInfoEs.length < 1) {
- return null;
- }
- // There should only be one.
- return pageInfoEs[0];
- }
- function getInfo() {
- 'use strict';
- var info = {};
- // There should only be one.
- // pageInfoE.innerHTML += "<button onclick=\"getRemixLicense()\">Copy Markdown</button>";
- // var licenseTextE = document.getElementsByClassName("license-text");
- // var licenseTextE = getDivsWhereClassStartsWith(clausesContainerPrefix);
- // var pageInfoEs = document.getElementsByClassName("item-page-info");
- // var pageInfoEs = getDivsWhereClassStartsWith(madeDivClassName);
- // console.log("Checking "+madeDivClassName+"* elements: " + JSON.stringify(pageInfoEs));
- var headingParts = getDivsWhereClassStartsWith(titlePrefix);
- var headingCreatedParts = getDivsWhereClassStartsWith(headingCreatedPrefix);
- if (headingParts.length > 0) {
- info.title = headingParts[0].textContent;
- }
- else {
- console.warn("The title is missing. There are no divs with a class starting with " + titlePrefix);
- }
- var createdStr = null;
- if (headingCreatedParts.length > 0) {
- createdStr = headingCreatedParts[0].textContent;
- }
- else {
- console.warn("The date is missing. There are no divs with a class starting with " + headingCreatedParts);
- }
- info.titleHref = window.location.href;
- // console.log("info.title: " + info.title);
- // console.log("info.titleHref: " + info.titleHref);
- console.log("createdStr: " + createdStr);
- if (createdStr !== null) {
- var createdParts = createdStr.split(" ");
- if (createdParts.length >= 3) {
- var yI = createdParts.length - 1;
- var dI = createdParts.length - 2;
- var mI = createdParts.length - 3;
- var yStr = createdParts[yI];
- var dStr = createdParts[dI];
- var mStr = createdParts[mI];
- if (dStr.endsWith(",")) {
- info.month = mStr;
- info.day = dStr.slice(0, -1);
- info.year = yStr;
- }
- else {
- console.warn("A date such as MON, D, YYYY was expected at the end of: \""+createdStr+"\"");
- }
- }
- }
- var aspects = [];
- aspects = getImgsWhereClassStartsWith(licenseClauseImgPrefix);
- var ai;
- if (aspects.length > 0) {
- info.license = "";
- }
- else {
- console.error("The license had zero clauses (img tags with "+licenseClauseImgPrefix+"* class)!")
- }
- var sep = " - ";
- for (ai = 0; ai < aspects.length; ai++) {
- var aspectImg = aspects[ai];
- if (aspectImg.src == undefined) {
- console.error("The license symbol src was undefined.");
- }
- else if (aspectImg.src == "") {
- console.error("The license symbol src was blank.");
- }
- else if (aspectImg.src.endsWith("cc.svg")) {
- info.license += "Creative Commons";
- }
- else if (aspectImg.src.endsWith("nc.svg")) {
- info.license += sep + "Non-Commercial";
- }
- else if (aspectImg.src.endsWith("nd.svg")) {
- info.license += sep + "No Derivatives";
- }
- else if (aspectImg.src.endsWith("by.svg")) {
- info.license += sep + "Attribution";
- }
- else if (aspectImg.src.endsWith("sa.svg")) {
- info.license += sep + "ShareAlike"; // It has a space on ThingiVerse, but that is not correct.
- }
- else if (aspectImg.src.endsWith("zero.svg")) {
- // It is preceded by by.svg on ThingiVerse, but that is not correct.
- info.license = "Creative Commons Zero";
- }
- else {
- console.error("The license symbol list has an unknown clause symbol: \"" + aspectImg.src + "\"");
- }
- }
- if (info.license != undefined) {
- if (info.license == "") {
- console.log("The symbols do not indicate a license (The site layout appears to be broken or changed so the license must be detected from the license URL if possible instead).");
- }
- else {
- console.log("The symbols indicate the following license: " + info.license);
- }
- }
- var licenseAnchors = getAnchorsWhereClassStartsWith(licenseAnchorPrefix);
- var exactLicenseVersion = null;
- if (licenseAnchors.length > 0) {
- console.log("Checking " + licenseAnchors.length + " license anchors...");
- for (var lai=0, max=licenseAnchors.length; lai < max; lai++) {
- var licenseA = licenseAnchors[lai];
- if (verbose) {
- console.log(" checking " + licenseA.className + "...");
- // NOTE: .getAttribute("href") gets the raw value, but .href gets the resulting full URL.
- console.log(" licenseA.href is a " + typeof licenseA.href);
- console.log(" licenseA.href.toString is a " + typeof licenseA.href.toString);
- console.log(" licenseA.href.toString().includes is a " + typeof licenseA.href.toString().includes);
- }
- if (licenseA.href === undefined) {
- console.warn("A license a.href is undefined.");
- }
- // else if (typeof licenseA.href.toString !== 'function') {
- // console.warn("A license a.href.toString is not a function.");
- // }
- else if (typeof licenseA.href.includes !== 'function') {
- // NOTE: Firefox 48 removes the "contains" prototype--you must use includes!
- // console.warn("A license a.getAttribute(\"href\").includes is not a function.");
- console.warn("A license a.href.toString.includes is not a function.");
- }
- else if (!licenseA.href.includes("thingiverse.com")) {
- if (verbose) {
- console.log("licenseA.href: ");
- console.log("'",licenseA.href, "'");
- }
- info.licenseHref = licenseA.href;
- if (info.licenseHref.slice(-3, -2) == ".") {
- exactLicenseVersion = licenseA.href.slice(-4, -1);
- }
- else {
- console.warn("slice at -3 is not .: " + info.licenseHref.slice(-3, -2));
- }
- }
- else {
- info.author = licenseA.textContent;
- info.authorHref = licenseA.href;
- if (verbose) {
- console.log("unused[]: " + licenseA.href);
- console.log("author: " + info.author);
- console.log("authorHref: " + info.authorHref);
- }
- }
- }
- }
- else {
- console.warn("There is no anchor with a class like "+licenseAnchorPrefix+"*");
- }
- return info;
- }
- function addButton() {
- 'use strict';
- // This should run when ThingPage_galleryHeader* gets filled in, but only once to prevent an infinite loop.
- // var pageInfoEs = document.getElementsByClassName("item-page-info");
- // NOTE: now ThingiVerse is a React app, so you must use inspect to see the HTML.
- // "ThingPage__madeBy*" includes parts such as:
- // - `ThingPage__modelName*`
- // - `<div class="ThingPage__createdBy*">by <a ...>UserName</a>MON D, YYYY`
- var pageInfoE = getButtonContainer();
- if (pageInfoE == null) {
- console.log('The '+madeSpanClassName+' class was not found so the button wasn\'t added!');
- return;
- }
- // pageInfoE.innerHTML += "<button onclick=\"getRemixLicense()\">Copy License for Remix</button>";
- //or:
- // See https://www.w3schools.com/jsref/met_document_createelement.asp
- var btn = document.createElement("BUTTON"); // Create a <button> element
- btn.setAttribute("class", "button button-secondary"); // as of 2023 button class names are obfuscated :(
- // btn.setAttribute("style", "background-color: rgb(50%, 50%, 50%)");
- var btnText = "Copy License for Remix";
- btn.innerHTML = btnText; // Insert text
- // Any URL starting with a slash comes after: "https://creativecommons.org/licenses"
- // otherwise it comes after "https://"
- // - A list of CC licenses is at <https://creativecommons.org/about/cclicenses/>.
- btn.addEventListener("click", function(){
- btn.innerHTML = btnText;
- var info = getInfo();
- populateCorrespondingLicenseFields(info);
- var markdownStr = getMarkdown(info);
- setClipboardText(markdownStr, btn);
- }); // end addEventListener click
- pageInfoE.appendChild(btn); // Append <button> for Markdown to whatever element was selected.
- }//end addButton
- function checkIfComplete() {
- // console.log("Monitoring page loading...");
- var missing_errors = "";
- var containers = getDivsWhereClassStartsWith(madeDivClassName);
- // console.log("Checking for completed page content...");
- if (containers.length == 1) {
- if (!elementHasAllPrefixes(containers[0], doneDivPrefixes)) {
- missing_errors += "containers[0].className " + containers[0].className + " with all of " + JSON.stringify(doneDivPrefixes) + ". ";
- if (verbose) {
- // console.log("The "+containers[0].className+" container is not complete:");
- // console.log("The document is not ready yet ("+containers[0].className+" does not contain the classes with the prefixes \""+JSON.stringify(doneDivPrefixes)+"\").");
- }
- }
- }
- else {
- missing_errors += "any container (required). ";
- // console.log("The page is not formatted as expected:");
- // console.log(containers.length + " is an unexpected count for divs with a class named like " + madeDivClassName + "*.");
- }
- if (!hasAllDivPrefixes(doneDivPrefixesMain)) {
- missing_errors += "hasAllDivPrefixes("+JSON.stringify(doneDivPrefixesMain)+"). ";
- // console.log("The document is not complete:");
- // console.log("The document is not ready yet (the document does not contain the class(es) with the prefix(es) \""+JSON.stringify(doneDivPrefixesMain)+"\").");
- }
- if (missing_errors.length == 0) {
- if (verbose) {
- console.log("The page has loaded.");
- }
- clearInterval(checkTimer);
- addButton();
- console.log("The license detection will resume after a user clicks the copy license button.");
- }
- else {
- console.log("The document is not ready (or is a new format). It is missing: "+missing_errors);
- }
- }
- checkTimer = setInterval(checkIfComplete, 2000);
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址