diff --git a/.eslintignore [DEPRECATED] b/.eslintignore [DEPRECATED] new file mode 100644 index 0000000..db181dd --- /dev/null +++ b/.eslintignore [DEPRECATED] @@ -0,0 +1 @@ +**/*.min.js diff --git a/.eslintrc.js b/.eslintrc.js [DEPRECATED] similarity index 73% rename from .eslintrc.js rename to .eslintrc.js [DEPRECATED] index c233581..8ebc3c0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js [DEPRECATED] @@ -1,4 +1,8 @@ +/* eslint-disable quotes */ + module.exports = { + "root": true, + "env": { "browser": true, "es6": true, @@ -6,23 +10,10 @@ module.exports = { "jquery": true, // "node": true }, - // "extends": "eslint:all", - // "extends": "eslint:recommended", - "extends": [ - // "eslint:all", - "eslint:recommended", - // "plugin:clean-regex/recommended" - // "plugin:regexp/all" - "plugin:regexp/recommended" - ], - "plugins": [ - // "clean-regex" - "regexp" - ], "parserOptions": { // "ecmaVersion": 12, - "ecmaVersion": 'latest', + "ecmaVersion": "latest", "sourceType": "script", "ecmaFeatures": { "globalReturn ": true, @@ -30,19 +21,46 @@ module.exports = { // "jsx": true, }, }, + + // "extends": "eslint:all", + // "extends": "eslint:recommended", + "extends": [ + "eslint:recommended", + // "eslint:all", + "plugin:css/recommended", + "plugin:jsonc/recommended-with-json", + // "plugin:no-jquery/recommended", + "plugin:no-jquery/deprecated", + // "plugin:no-jquery/slim", + // "plugin:no-jquery/all", + // "plugin:clean-regex/recommended" + "plugin:regexp/recommended", + // "plugin:regexp/all", + ], + + "plugins": [ + "css", + "jsonc", + // "clean-regex", + "no-jquery", + "regexp", + ], + "rules": { "complexity": ["warn", 20], "eqeqeq": "warn", "func-style": "off", // "indent": ["warn","tab" ], // "indent": ["warn","tab", { "SwitchCase": 1 } ], - "indent": ["warn","tab", { "ignoreComments": true, "SwitchCase": 1 } ], + // "indent": ["warn","tab", { "ignoreComments": true, "SwitchCase": 1 } ], + "indent": ["warn","tab", { "ignoreComments": false, "SwitchCase": 1 } ], "linebreak-style": ["warn","unix"], "max-len": "off", "max-statements-per-line": "off", "new-cap": "off", "no-alert": "warn", "no-console": "warn", + "no-dupe-keys": "warn", "no-extra-semi": "warn", "no-inline-comments": "off", "no-magic-numbers": "off", @@ -63,8 +81,8 @@ module.exports = { "space-before-function-paren": "off", // "space-in-parens": ["warn", "always"], "unicode-bom": ["warn", "never"], - }, + "reportUnusedDisableDirectives": true }; diff --git a/.eslintrc.json [DEPRECATED] b/.eslintrc.json [DEPRECATED] new file mode 100644 index 0000000..a34a4d6 --- /dev/null +++ b/.eslintrc.json [DEPRECATED] @@ -0,0 +1,61 @@ +{ + "root": true, + "env": { + "browser": true, + "es6": true, + "greasemonkey": true, + "jquery": true + }, + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "script", + "ecmaFeatures": { + "globalReturn ": true, + "impliedStrict": true + } + }, + "extends": [ + "eslint:recommended", + "plugin:css/recommended", + "plugin:jsonc/recommended-with-json", + "plugin:no-jquery/deprecated", + "plugin:regexp/recommended" + ], + "plugins": [ + "css", + "jsonc", + "no-jquery", + "regexp" + ], + "rules": { + "complexity": ["warn", 20], + "eqeqeq": "warn", + "func-style": "off", + "indent": ["warn","tab", { "ignoreComments": false, "SwitchCase": 1 } ], + "linebreak-style": ["warn","unix"], + "max-len": "off", + "max-statements-per-line": "off", + "new-cap": "off", + "no-alert": "warn", + "no-console": "warn", + "no-dupe-keys": "warn", + "no-extra-semi": "warn", + "no-inline-comments": "off", + "no-magic-numbers": "off", + "no-misleading-character-class": "warn", + "no-mixed-spaces-and-tabs": "warn", + "no-multiple-empty-lines": "off", + "no-tabs": "off", + "no-unused-labels": "warn", + "no-unused-vars": ["warn", {"vars": "all", "args": "after-used"}], + "no-useless-escape": "warn", + "padded-blocks": "off", + "quotes": ["warn", "single", { "allowTemplateLiterals": true }] , + "require-jsdoc": "off", + "require-unicode-regexp": "off", + "semi": ["warn","always"], + "space-before-function-paren": "off", + "unicode-bom": ["warn", "never"] + }, + "reportUnusedDisableDirectives": true +} diff --git a/.gitattributes b/.gitattributes index bdb0cab..1e78b8c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ # Auto detect text files and perform LF normalization -* text=auto +* text=auto eol=lf # Custom for Visual Studio *.cs diff=csharp diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 4dc9225..eaba567 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -20,23 +20,18 @@ body: required: true - label: The bug is caused by the script itself. It doesn't happen if I disable the script, or in a fresh browser profile. required: true + - type: checkboxes + attributes: + label: 'Include in this issue:' + options: + - label: Screenshots/video/gif demonstrating the bug, if it’s visual + - label: Console errors, if any - type: textarea id: the-problem attributes: label: Describe the problem and how to replicate it validations: required: true - - type: textarea - id: screenshots - attributes: - label: Screenshots/video/gif showing the issue, if it’s visual - description: Files can be dropped in this field - - type: textarea - id: logs - attributes: - label: Console errors - description: If any - render: shell - type: input id: example-url attributes: @@ -50,6 +45,7 @@ body: attributes: label: Script Manager description: (Tampermonkey and Violentmonkey are supported - Greasemonkey is NOT supported) + placeholder: e.g. Tampermonkey 4.14 validations: required: true - type: input @@ -57,5 +53,6 @@ body: attributes: label: Browser(s) used description: (make sure it is the latest version - old versions are NOT supported) + placeholder: e.g. Chrome 92 validations: required: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..75d11ec --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" # Check for updates to GitHub Actions every week diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..b9d6d20 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,14 @@ +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/evergreen.yml b/.github/workflows/evergreen.yml new file mode 100644 index 0000000..57eb768 --- /dev/null +++ b/.github/workflows/evergreen.yml @@ -0,0 +1,22 @@ +name: Weekly dependabot checks + +on: + workflow_dispatch: + schedule: + - cron: '3 2 1 * *' + +permissions: + issues: write + pull-requests: write + +jobs: + evergreen: + name: evergreen + runs-on: ubuntu-latest + + steps: + - name: Run evergreen action + uses: github/evergreen@v1 + env: + GH_TOKEN: ${{ secrets.EVERGREEN_ACTION }} + REPOSITORY: darkred diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..f2415f5 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,31 @@ +# from https://github.com/tophf/mpiv/blob/master/.github/workflows/lint.yml +# and https://github.com/stefanoeb/eslint-action/blob/master/README.md + +name: ESLint + +on: + push: + branches: [ master ] + paths-ignore: + - '.github/**' # this yml is also excluded so you need to re-run it explicitly if necessary + - .editorconfig + - LICENSE + - README.md + pull_request: + branches: [ master ] + paths-ignore: + - '.github/**' # this yml is also excluded so you need to re-run it explicitly if necessary + - .editorconfig + - LICENSE + - README.md + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install modules + run: npm install + - name: Run ESLint + run: npx eslint . --ext .user.js diff --git a/1337x_-_torrent_and_magnet_links/1337x_-_torrent_and_magnet_links.user.js b/1337x_-_torrent_and_magnet_links/1337x_-_torrent_and_magnet_links.user.js index d19671f..a6244e8 100644 --- a/1337x_-_torrent_and_magnet_links/1337x_-_torrent_and_magnet_links.user.js +++ b/1337x_-_torrent_and_magnet_links/1337x_-_torrent_and_magnet_links.user.js @@ -1,19 +1,23 @@ // ==UserScript== // @name 1337x - torrent and magnet links // @namespace darkred -// @version 2021.7.29 +// @version 2021.8.17 // @description Adds a column with torrent and magnet links in lists // @author darkred -// @contributor NotNeo +// @contributor NotNeo, barn852 // @license MIT // @include /^https:\/\/(www\.)?1337x\.(to|st|ws|eu|se|is|gd|unblocked\.dk)((?!\/torrent)).*$/ // @grant GM_addStyle // @run-at document-idle // -// Thanks to NotNeo: most of the CSS used is taken from this script https://greasyfork.org/en/scripts/373230-1337x-magnet-torrent-links-everywhere . +// Thanks to: +// - NotNeo: most of the CSS used is taken from this script: https://greasyfork.org/en/scripts/373230-1337x-magnet-torrent-links-everywhere . +// - barn852 for his contribution here: https://greasyfork.org/en/scripts/420754-1337x-torrent-and-magnet-links/discussions/96026 +// +// Official mirrors list: https://1337x.to/about +// // ==/UserScript== -// Official mirrors list: https://1337x.to/about GM_addStyle(` @@ -35,13 +39,13 @@ GM_addStyle(` table.table-list td.dl-buttons { border-left: 1px solid #f6f6f6; + border-right: 1px solid #c0c0c0; padding-left: 2.5px; padding-right: 2.5px; text-align: center !important; position: relative; - display: inline-block !important; - /* width: 50px; */ - width: 52px; + display: table-cell !important; /* proper height of cell on multiple row torrent name */ + width: 6%; } td.dl-buttons > a, @@ -71,53 +75,47 @@ GM_addStyle(` function appendColumn() { - + const allTables = document.querySelectorAll('.table-list-wrap'); // for pages with multiple tables e.g. https://1337x.to/home/ + const isSeries = window.location.href.includes('/series/'); // for pages with tables that have no header e.g. https://1337x.to/series/a-to-z/1/13/ const title = 'ml dl'; - let headers = document.querySelectorAll('.table-list > thead > tr:not(.blank) > th:nth-child(1)'); // the initial column 'Files' after of which the extra column will be appended - let cells = document.querySelectorAll('.table-list > tbody > tr:not(.blank) > td:nth-child(1)'); // the initial column 'Files' after of which the extra column will be appended - for (let i = 0; i < headers.length; i++) { - headers[i].insertAdjacentHTML('afterend', `` + title + ``); // creation of the extra column - } - - for (let i = 0; i < cells.length; i++) { - cells[i].insertAdjacentHTML('afterend', `` + '' + ``); - } - - - let headersNew = document.querySelectorAll('.table-list > thead > tr:not(.blank) > th:nth-child(2)'); // the first cell (the header cell) of the new column - let cellsNew = document.querySelectorAll('.table-list > tbody > tr:not(.blank) > td:nth-child(2)'); // the rest cells of the new column tr:not(.blank) is for lists that also have empty lines e.g. https://1337x.to/series/a-to-z/1/13/ - - for (let i = 0; i < headersNew.length; i++) { - headersNew[i].innerHTML = title; - headersNew[i].setAttribute('class', 'coll-1b'); - } + allTables.forEach((table) => { - for (let i = 0; i < cellsNew.length; i++) { - cellsNew[i].classList.add('coll-1b'); - cellsNew[i].classList.add('dl-buttons'); - } - - - - let newColumn = document.querySelectorAll('.table-list > tbody > tr:not(.blank) > td:nth-child(2)'); // new column - let oldColumn = document.querySelectorAll('.table-list > tbody > tr:not(.blank) > td:nth-child(1)'); // old column - - for (let i = 0; i < newColumn.length; i++) { - - let href; - if (!window.location.href.includes('/series/')){ - href = oldColumn[i].firstElementChild.nextElementSibling.href; - } else { // e.g. https://1337x.to/series/a-to-z/1/13/ - href = oldColumn[i].firstElementChild.href; - } + const headersCellsInitial = table.querySelectorAll(`.table-list > thead > tr:not(.blank) > th:nth-child(1), + .table-list > tbody > tr:not(.blank) > td:nth-child(1)`); + headersCellsInitial.forEach((cell, index) => { + if (index === 0 && !isSeries) { + cell.insertAdjacentHTML('afterend', `` + title + ``); + } else { + cell.insertAdjacentHTML('afterend', `` + title + ``); + } + }); + + const headersCellsNew = table.querySelectorAll(`.table-list > thead > tr:not(.blank) > th:nth-child(2), + .table-list > tbody > tr:not(.blank) > td:nth-child(2)`); + headersCellsNew.forEach((cell, index) => { + cell.classList.add('coll-1b'); + if (index === 0 && !isSeries) { + cell.innerHTML = title; + } else { + cell.classList.add('dl-buttons'); + + let href; + if (!isSeries){ + href = headersCellsInitial[index].firstElementChild.nextElementSibling.href; + } else { + href = headersCellsInitial[index].firstElementChild.href; + } + + cell.innerHTML = ``; + cell.innerHTML += ``; + } + }); - newColumn[i].innerHTML = ''; - newColumn[i].innerHTML += ''; + }); - } } @@ -125,9 +123,9 @@ function appendColumn() { function addClickListeners(links, type){ - for(let i = 0; i < links.length; i++) { + links.forEach((link) => { - links[i].addEventListener('click', function(event){ + link.addEventListener('click', function(){ let href = this.getAttribute('href'); if (href === 'javascript:void(0)') { @@ -140,17 +138,11 @@ function addClickListeners(links, type){ let container = document.implementation.createHTMLDocument().documentElement; container.innerHTML = xhr.responseText; - let retrievedLink; - if (type === 'ml'){ - retrievedLink = container.querySelector('a[href^="magnet:"]'); // the 'magnet link' element in the retrieved page - } else { - retrievedLink = container.querySelector('.dropdown-menu > li > a'); // the 'download link' element in the retrieved page - } - + let retrievedLink = (type === 'ml') ? container.querySelector('a[href^="magnet:"]') : container.querySelector('.dropdown-menu > li > a'); if (retrievedLink) { - links[i].setAttribute('href', retrievedLink.href.replace('http:', 'https:')); // the links are http and as such are blocked in Chrome - links[i].click(); + link.setAttribute('href', retrievedLink.href.replace('http:', 'https:')); // the links are http and as such are blocked in Chrome + link.click(); } @@ -161,7 +153,7 @@ function addClickListeners(links, type){ }, false); - } + }); } diff --git a/1337x_-_torrent_and_magnet_links/README.md b/1337x_-_torrent_and_magnet_links/README.md index 3ff0759..899c5f6 100644 --- a/1337x_-_torrent_and_magnet_links/README.md +++ b/1337x_-_torrent_and_magnet_links/README.md @@ -1,11 +1,17 @@ -Adds a column with torrent and magnet links in 1337x lists: -![](https://i.imgur.com/S4nzRP8.jpg) +Adds a column with torrent and magnet links in 1337x lists: +![](https://i.imgur.com/goYAFQH.jpg) -Notes: +Notes: - The script generates all links via XHR: - - The DL/ML links will have: - - initially, as its destination (`href`) a: `javascript:void(0)`, - - as tooltip: "`DL/ML via XHR`". - - As you click a DL/ML icon, the relevant target page will be retrieved via XHR in the background (so, after clicking an icon, it will now have the magnet link). -- Thanks to NotNeo: most of the CSS used is taken from this script https://greasyfork.org/en/scripts/373230-1337x-magnet-torrent-links-everywhere . + - The DL/ML links will have: + - as tooltip: "`ml/dl via xhr`". + - as destination (href): + - initially: `javascript:void(0)` *(to avoid taking the user back to the top of the page, which occurred if having `#`, instead)*, + - as you click a ml/dl icon, the relevant target URL will be retrieved via XHR in the background. +- Thanks to: + - NotNeo: most of the CSS is from his [1337X - Magnet/Torrent links everywhere](https://greasyfork.org/en/scripts/373230-1337x-magnet-torrent-links-everywhere) script, + - barn852 for [this](https://greasyfork.org/en/scripts/420754-1337x-torrent-and-magnet-links/discussions/96026) contribution . +- Tampermonkey and Violentmonkey are supported - Greasemonkey is NOT supported. + +[Hosted at GitHub](https://github.com/darkred/Userscripts) diff --git a/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area.user.js b/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area.user.js index 357a4aa..d28f711 100644 --- a/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area.user.js +++ b/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area/Blabbermouth_-_generate_timestamps_and_add_link_to_the_FB_comments_area.user.js @@ -1,22 +1,24 @@ // ==UserScript== // @name Blabbermouth - generate timestamps and add link to the fb comments area // @namespace darkred -// @version 1.2.1 -// @date 2021.3.31 +// @version 2.0 +// @date 2022.5.14 // @description Generates missing timestamps or converts the existing ones in relative format, and adds link to the fb comments area // @author darkred // @license MIT -// @include /^(https?:)?\/\/(www\.)?blabbermouth\.net\/(news|cdreviews|dvdreviews)?/ -// @exclude /^(https?:)?\/\/(www\.)?blabbermouth\.net\/(cdreviews|dvdreviews)(\/page|$)/ +// @include /^(https?:)?\/\/(www\.)?blabbermouth\.net\/(news|reviews)?/ +// @exclude /^(https?:)?\/\/(www\.)?blabbermouth\.net\/reviews(\/page|$)/ // @include https://www.facebook.com/plugins/feedback.php* // @grant none // @require https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js // @supportURL https://github.com/darkred/Userscripts/issues -// @icon https://www.blabbermouth.net/assets/favicon-309148577f1b67c003487c069cccf8731e6f68e4d847c5576d6f5453b083c27a.png +// @icon https://drnizx3otcofi.cloudfront.net/b64e6010-2ac1-4e95-b545-1a2994bbbd04/img/favicon/favicon-32x32.png // ==/UserScript== /* global moment */ +/* eslint-disable no-console */ + 'use strict'; @@ -41,11 +43,12 @@ moment.updateLocale('en', { function convertToLocalTimezone(timestamp) { // (the timestamp is in ISO 8601 format and its trailing Z means that it's in UTC ) - // 2020-03-05T15:40:38.000Z + // 2020-03-05T15:40:38.000Z old + // 2022-05-11T12:16:05+00:00 new let initialTimestamp = timestamp; if (moment(initialTimestamp, moment.ISO_8601, true).isValid()) { // let convertedToLocalTimezone = moment(initialTimestamp.replace('Z','') + '-05:00', 'YYYY-MM-DDTHH:mm:ssZ'); // the server's timezone is GMT-5 - let convertedToLocalTimezone = moment(initialTimestamp.replace('Z','') + '-03:47', 'YYYY-MM-DDTHH:mm:ssZ'); // the server's timezone is GMT-4 plus 13 min, in order to sync with the relevant post timestamps in both Facebook and Twitter(TW is 1 min later than FB) blabbbermouth pages + let convertedToLocalTimezone = moment(initialTimestamp + '-03:47', 'YYYY-MM-DDTHH:mm:ss+Z'); // the server's timezone is GMT-4 plus 13 min, in order to sync with the relevant post timestamps in both Facebook and Twitter(TW is 1 min later than FB) blabbbermouth pages publishedTimeLTZ = convertedToLocalTimezone.fromNow(); let format = 'YYYY-MM-DD HH:mm:ss'; publishedTimeLTZtitle = convertedToLocalTimezone.format(format); @@ -63,6 +66,12 @@ function recalc(existingTimestampElement, format, notitle) { } +function onClick(){ + document.querySelector('iframe[title="fb:comments Facebook Social Plugin"]').scrollIntoView(); +} + + +// 1. IF ON NEWS PAGES LISTINGS (convertTolocal + apply to pagination) if ( window.location.href.endsWith('blabbermouth.net/') || window.location.href.endsWith('blabbermouth.net/news') || @@ -75,7 +84,7 @@ if ( threshold: 0 }; - let callback = (entries, observer) => { + let callback = (entries) => { entries.forEach(entry => { if (!entry.target.classList.contains('done')){ @@ -84,17 +93,15 @@ if ( if (entry.isIntersecting && !entry.target.classList.contains('in-viewport') ) { entry.target.classList.add('in-viewport'); - var xhr = new XMLHttpRequest(); - var url = entry.target.parentElement.parentElement.firstElementChild.firstElementChild.href; + const xhr = new XMLHttpRequest(); + const url = entry.target.parentElement.parentElement.firstElementChild.firstElementChild.href; xhr.open('GET', url, true); // XMLHttpRequest.open(method, url, async) xhr.onload = function () { let container = document.implementation.createHTMLDocument().documentElement; container.innerHTML = xhr.responseText; - let publishedTimestamp = container.querySelector( - 'meta[property="article:published_time"]' - ).content; + let publishedTimestamp = container.querySelector('meta[property="article:published_time"]').content; convertToLocalTimezone(publishedTimestamp); @@ -113,7 +120,7 @@ if ( let observer = new IntersectionObserver(callback, options); - var allTimestamps = document.querySelectorAll('span.date-time'); + let allTimestamps = document.querySelectorAll('.news-single span.date'); allTimestamps.forEach((element) => { observer.observe(element); }); @@ -121,13 +128,13 @@ if ( // ---------------------------------------- // Watch for pagination events (when new '.article' children are added inside the '.infinite_scroll' element) - const targetNode2 = document.querySelector('.infinite_scroll'); + const targetNode2 = document.querySelector('.infinite-scroll-component'); const config2 = { attributes: false, childList: true, subtree: false }; - const callback2 = function(mutationsList, observer2) { + const callback2 = function(mutationsList) { for(const mutation of mutationsList) { if (mutation.type === 'childList') { - var allTimestamps = document.querySelectorAll('span.date-time'); + let allTimestamps = document.querySelectorAll('.news-single span.date'); allTimestamps.forEach((element) => { observer.observe(element); }); @@ -140,107 +147,109 @@ if ( // ---------------------------------------- -} else if (window.location.href.includes('blabbermouth.net/news/')) { - if ( - document.querySelector('meta[property="article:published_time"]') !== - null - ) { - var publishedTimestamp = document.querySelector( - 'meta[property="article:published_time"]' - ).content; - } + // /blabbermouth\.net/\(reviews|news)/i.test(window.location.href) + +// 2+3. ELSE IF ON CD/DVD REVIEWS OR NEWS PAGES ((convertTolocal + generate timestamp) +} else if ( /blabbermouth\.net\/(reviews|news)/i.test(window.location.href) && + !window.location.href.includes('/page/') ) { + + //--- Double-check that this iframe is on the expected domain: + if (/blabbermouth\.net/i.test(location.host)) { + console.log('Userscript is in the MAIN page.'); + // 2019-10-17T15:32:18.000Z - console.log('publishedTimestamp: ' + publishedTimestamp); - var publishedTimeLTZ, publishedTimeLTZtitle; + let publishedTimestamp; + if (document.querySelector('meta[property="article:published_time"]') !== null) { + publishedTimestamp = document.querySelector('meta[property="article:published_time"]').content; + } + console.log('publishedTimestamp: ' + publishedTimestamp); - convertToLocalTimezone(publishedTimestamp); - let existingTimestampElement = document.querySelector('.date-time'); - existingTimestampElement.textContent = publishedTimeLTZ; - existingTimestampElement.title = publishedTimeLTZtitle; + if (window.location.href.includes('blabbermouth.net/news/')) { - recalc(existingTimestampElement, 'YYYY-MM-DD HH:mm:ss'); + var publishedTimeLTZ, publishedTimeLTZtitle; + convertToLocalTimezone(publishedTimestamp); -} else if ( - (window.location.href.includes('blabbermouth.net/cdreviews/') || - window.location.href.includes('blabbermouth.net/dvdreviews/')) && - !window.location.href.includes('/page/') -) { - //--- Double-check that this iframe is on the expected domain: - if (/blabbermouth\.net/i.test(location.host)) { - console.log('Userscript is in the MAIN page.'); + let existingTimestampElement = document.querySelector('div > h1+span.date'); - // 2019-10-17T15:32:18.000Z + existingTimestampElement.textContent = publishedTimeLTZ; + existingTimestampElement.title = publishedTimeLTZtitle; + + recalc(existingTimestampElement, 'YYYY-MM-DD HH:mm:ss'); - if ( - document.querySelector( - 'meta[property="article:published_time"]' - ) !== null - ) { - publishedTimestamp = document.querySelector( - 'meta[property="article:published_time"]' - ).content; } - console.log(publishedTimestamp); - var currentURL = window.location.href; - convertToLocalTimezone(publishedTimestamp); - var commentcount = ''; - var HTML = ` -

-${publishedTimeLTZ} - -${commentcount} - -Comments - + + + + if (!window.location.href.includes('blabbermouth.net/news/page/')){ + + convertToLocalTimezone(publishedTimestamp); + + var commentcount = '0'; + + var datePart = !window.location.href.includes('blabbermouth.net/news/') ? `${publishedTimeLTZ}` : ''; + + var HTML = ` +${datePart} +

+ +${commentcount} Comments -

+
`; - if (document.querySelector('.entry-content') !== null) { - document - .querySelector('.entry-content') - .insertAdjacentHTML('beforebegin', HTML); - document.querySelector('.date-time').title = publishedTimeLTZtitle; + const refSelector = '.reviews-single-article > div > .reviews-rate-comments,div > h1+span.date'; + + if (document.querySelector(refSelector) !== null) { + document.querySelector(refSelector).insertAdjacentHTML('afterend', HTML); + document.querySelector(refSelector).title = publishedTimeLTZtitle; + + document.getElementById('commentCount').addEventListener('click', onClick, false); + + let newDateTimeElement = document.querySelector('span.date'); + recalc(newDateTimeElement, 'YYYY-MM-DD HH:mm:ss'); + } - let newDateTimeElement = document.querySelector('.date-time'); - recalc(newDateTimeElement, 'YYYY-MM-DD HH:mm:ss'); } - // Wait fof messages (from iframe) - window.addEventListener( - 'message', - function addFbCounter(e) { - // something from an unknown domain, or doesn't contain the string "Comment" let's ignore it - if (e.origin !== 'https://www.facebook.com' || e.data.indexOf(' Comment') === -1) { - return; - } - console.log('Received message: ' + e.data); - document.querySelector( - '#main > article > p > span.date-comments > a:nth-child(1)' - ).innerText = e.data.replace(/ Comments?/i,''); - window.removeEventListener('message', addFbCounter); - }, - false + // Wait for messages [commentcount] (from iframe) + window.addEventListener('message', function addFbCounter(e) { + // something from an unknown domain, or doesn't contain the string "Comment" let's ignore it + console.log('Received message: ' + e.data); + if (e.origin !== 'https://www.facebook.com' || e.data.indexOf(' Comment') === -1) { + return; + } + console.log('Received message: ' + e.data); + // document.querySelector('#commentCount').innerText = e.data.replace(/ Comments?/i,''); + document.querySelector('#commentCount').innerText = e.data; + window.removeEventListener('message', addFbCounter); + }, + false ); console.log('Waiting for Message 1, from iframe...'); } -} else if (window.location.href.includes('facebook.com')) { + + +// ELSE IF IT'S ON THE FACEBOOK COMMENTS IFRAME (send fb comment count to main page) +} + +if (window.location.href.includes('facebook.com')) { console.log('Userscript is in the FRAMED page.'); - var selector = '._50f7'; + const selector = '._50f7'; + // Send commentcount to MAIN page window.parent.postMessage( document.querySelector(selector).innerText, - 'https://www.blabbermouth.net/cdreviews/' + 'https://blabbermouth.net/reviews/' ); } diff --git a/Google_youtube_search_link/Google_youtube_search_link.user.js b/Google_youtube_search_link/Google_youtube_search_link.user.js index 6931a43..e998740 100644 --- a/Google_youtube_search_link/Google_youtube_search_link.user.js +++ b/Google_youtube_search_link/Google_youtube_search_link.user.js @@ -4,7 +4,7 @@ // @author wOxxOm, darkred // @license MIT // @description Adds a YouTube search link next to the Videos link (e.g. Web, Images, Videos, YouTube, News, Maps, Shopping, ...) -// @version 2021.2.13.1 +// @version 2022.5.27 // @include https://www.google.com/* // @include /https?:\/\/(www\.)?google\.(com|(?:com?\.)?\w\w)\/.*/ // @grant none @@ -12,6 +12,13 @@ // @supportURL https://github.com/darkred/Userscripts/issues // ==/UserScript== +const escapeHTMLPolicy = (({ trustedTypes }, policy) => + trustedTypes + ? trustedTypes.createPolicy('myEscapePolicy', policy) + : policy)(window, { + createHTML: (str) => str, +}); + process(); new MutationObserver(process).observe(document, { childList: true, subtree: true }); @@ -20,17 +27,17 @@ function process(mutations) { if (youtube) return; - // var menu = document.querySelector('#hdtb'); // selector for the element that contains all the links (Web, Images, Videos, News, Maps, Shopping, ...) - var menu = document.querySelector('#hdtb, .ndYZfc'); // .ndYZfc is for when Images tab is selected + // Selectors for the bar element that contains all the links (Web, Images, Videos, News, Maps, Shopping, ...) + // '.ndYZfc', is for when the 'Images' tab is selected. The other, '#hdtb', is for all other cases. + var menu = document.querySelector('#hdtb, .ndYZfc'); if (!menu) return; - // var menuContainer = menu.querySelector('#hdtb-msb').parentNode; - var menuContainer = menu.querySelector('#hdtb-msb, .tAcEof').parentNode; // .tAcEof is for when Images tab is selected + var menuContainer = menu.querySelector('#hdtb-msb, .tAcEof').parentNode; // '.tAcEof' is for when the 'Images' tab is selected. The other, '#hdtb-msb', is for all other cases. if (!youtube) { var q = '', - queryElement = document.querySelector('input[name="q"]'); // selector for the Google search input textbox + queryElement = document.querySelector('input[name="q"]'); // The google search input textbox if (queryElement) { if (queryElement.value) q = encodeURIComponent(queryElement.value); @@ -72,18 +79,21 @@ function process(mutations) { '' + svg + 'YouTube' + ''; - var node = document.querySelector(`a[href*='tbm=vid']`) || document.querySelector('path[d^="M10 16.5l6-4.5-6-4.5"]').closest('span'); + const isVideosTabSelected = !!document.querySelector('.hdtb-mitem.hdtb-msel path[d^="M10 16.5l6-4.5-6-4.5"]'); + var node = isVideosTabSelected === false ? document.querySelector(`a[href*='tbm=vid']`) : document.querySelector('path[d^="M10 16.5l6-4.5-6-4.5"]').closest('span').parentNode; + - // select the 'Images' selected tab svg icon by its path[d] attribute - var imagesTabElement = document.querySelector('path[d^="M14 13l"]').closest('span.rQEFy'); - if (imagesTabElement) { - text = '' + svg + 'YouTube'; - // select the 'Videos' tab svg icon by its path[d] attribute + // select the (next, non-selected/non-active) 'Videos' tab svg icon by its path[d] attribute node = document.querySelector('path[d^="M10 16.5l6-4.5-6-4.5"]').closest('span'); } - node.parentElement.insertAdjacentHTML('afterend', text); // insert the YouTube link + const escaped = escapeHTMLPolicy.createHTML(text); + node.parentElement.insertAdjacentHTML('afterend', escaped); // insert the YouTube link } @@ -95,7 +105,7 @@ function addCss(cssString) { var head = document.getElementsByTagName('head')[0]; var newCss = document.createElement('style'); newCss.type = 'text/css'; - newCss.innerHTML = cssString; + newCss.innerHTML = escapeHTMLPolicy.createHTML(cssString); head.appendChild(newCss); } diff --git a/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js b/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js index 8eac977..3c5be12 100644 --- a/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js +++ b/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Instagram - visible images counter // @namespace darkred -// @version 2021.4.12 +// @version 2024.2.23 // @description Shows in instagram profile pages how many images out of total (as a number and as a percentage) are currently visible, as you scroll down the page. // @author darkred // @license MIT @@ -12,6 +12,15 @@ // @supportURL https://github.com/darkred/Userscripts/issues // ==/UserScript== +/* eslint-disable no-console */ + +const escapeHTMLPolicy = (({ trustedTypes }, policy) => + trustedTypes + ? trustedTypes.createPolicy('myEscapePolicy', policy) + : policy)(window, { + createHTML: (str) => str, +}); + var stylesheet = `