您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Otomatis menampilkan semua halaman artikel berita dalam 1 halaman
当前为
- // ==UserScript==
- // @name Auto All Page
- // @version 2.1.1
- // @author reforget-id
- // @namespace autoallpage
- // @description Otomatis menampilkan semua halaman artikel berita dalam 1 halaman
- // @homepage https://github.com/reforget-id/AutoAllPage
- // @supportURL https://github.com/reforget-id/AutoAllPage/issues
- // @icon https://raw.githubusercontent.com/reforget-id/AutoAllPage/main/assets/icon.png
- // @run-at document-start
- // @grant GM_addStyle
- // @grant GM_xmlhttpRequest
- // @grant GM_registerMenuCommand
- // @noframes
- // @exclude https://*?single=1
- // @exclude https://*?showpage=all
- // @exclude https://*.inews.id/*/all
- // @exclude https://*?page=all#page*
- // @exclude https://*?page=all#sectionall
- // @exclude /^https:\/\/(?!.+\.idntimes\.com).+\?page=all$/
- // @exclude https://*/amp/*
- // @exclude https://amp.*
- // @exclude https://*/amp-*/*
- // @exclude https://*/?amp*
- // @exclude https://*?amp=1*
- // @exclude https://*/*&*
- // @exclude https://*/*&=1*
- // @include https://*.100kpj.com/*/*
- // @include https://*.aboutmalang.com/*/*/*
- // @include https://*.ayocirebon.com/*/*/*
- // @include https://akurat.co/*
- // @include https://*.bolasport.com/read/*
- // @include https://*.cnbcindonesia.com/*/*/*
- // @include https://*.cnnindonesia.com/*/*/*
- // @include https://*.detik.com/*/d-*/*
- // @include https://*.genpi.co/*/*/*
- // @include https://*.grid.id/read/*
- // @include https://*.gridoto.com/read/*
- // @include https://herstory.co.id/read*
- // @include https://*.hops.id/*/*/*
- // @include https://*.idntimes.com/*/*/*/*
- // @include https://*.idxchannel.com/*/*
- // @include https://*.inews.id/*/*
- // @include https://*.intipseleb.com/*/*
- // @include https://*.jatimnetwork.com/*/*/*
- // @include https://*.jpnn.com/*/*
- // @include https://*.kompas.com/read/*
- // @include https://*.kompas.com/*/read/*
- // @include https://*.kompas.tv/article/*
- // @include https://*.kompasiana.com/*/*/*
- // @include https://*.kontan.co.id/news/*
- // @include https://*.motorplus-online.com/read/*
- // @include https://*.parapuan.co/read/*
- // @include https://*.pikiran-rakyat.com/*/pr-*/*
- // @include https://*.republika.co.id/berita/*
- // @include https://republika.co.id/berita/*
- // @include https://*.sahijab.com/*/*
- // @include https://*.sindonews.com/read/*
- // @include https://*.sonora.id/read/*
- // @include https://*.suara.com/*/*/*/*
- // @include https://*.tempo.co/read/*
- // @include https://*.tribunnews.com/*/*/*/*
- // @include https://*.tvonenews.com/*/*
- // @include https://*.unews.id/*/*/*
- // @include https://*.viva.co.id/*/*
- // @include https://wartaekonomi.co.id/read*
- // ==/UserScript==
- // https://*.okezone.com/read/*
- 'use strict';
- (() => {
- GM_addStyle(`
- .aap-divider {
- font-size: 18px !important;
- font-weight: 600 !important;
- margin: 30px 0 30px 0 !important;
- text-align: center !important;
- }
- `)
- GM_registerMenuCommand('Donate me on Trakteer', () => {
- window.open('https://trakteer.id/reforget-id', '_blank')
- })
- class URLBuilder {
- constructor() {
- this._protocol = 'https'
- this._hostname = ''
- this._path = ''
- this._param = ''
- }
- hostname(hostname) {
- this._hostname = hostname
- return this
- }
- path(...pathname) {
- this._path = this._path + pathname.join('/')
- return this
- }
- param(query) {
- this._param = '?' + query
- return this
- }
- toString() {
- let url = `${this._protocol}://${this._hostname}/${this._path}`
- if (this._param !== '') url = url + this._param
- return url
- }
- }
- const url = {
- get url() {
- return window.location
- },
- href: () => url.url.href,
- hostname: () => url.url.hostname,
- path: () => url.url.pathname,
- param: () => url.url.search,
- }
- function splitPath(pathname) {
- return pathname.split('/').filter(v => v)
- }
- function redirect(url) {
- window.location.replace(url)
- }
- function urlChecker(site) {
- return site.hostname.test(url.hostname()) && site.path.test(url.path())
- }
- function log(message) {
- console.log('[AutoAllPage] ' + message)
- }
- function pageDivider(currentPage, totalPages) {
- const divider = new DOMParser().parseFromString(`
- <div class="aap-divider">
- === [AutoAllPage] Halaman ${currentPage} dari ${totalPages} ===
- </div>
- `, 'text/html')
- return divider.body.firstElementChild
- }
- //******************************************************************************
- const websites = [
- {
- id: 'akurat',
- description: 'akurat.co',
- hostname: /(^|\.)akurat\.co$/,
- path: /^\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'cnbc',
- description: 'cnbcindonesia.com',
- hostname: /(^|\.)cnbcindonesia\.com$/,
- path: /\/\d+-\d+-\d+\/.+(\/\d+|(?<!\/\w+))$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'detik',
- description: 'detik.com',
- hostname: /(^|\.)detik\.com$/,
- path: /\/d-\d+\/.+(\/\d+|(?<!\/\w+))$/,
- method: 'param',
- fullpage: 'single=1',
- },
- {
- id: 'grid',
- description: 'bolasport.com, grid.id, gridoto.com, motorplus-online.com, parapuan.co, sonora.id',
- hostname: /(^|\.)(parapuan\.co|(grid|sonora)\.id|(bolasport|gridoto|motorplus-online)\.com)$/,
- path: /^\/read\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'idntimes',
- description: 'idntimes.com',
- hostname: /(^|\.)idntimes\.com$/,
- path: /\/[\w-]+\/[\w-]+\/.+\/.+(?<!\/\w+)$/,
- method: 'dom',
- pagination: 'page=all',
- },
- {
- id: 'idx',
- description: 'idxchannel.com',
- hostname: /(^|\.)idxchannel\.com$/,
- path: /\/.+\/.+(\/\d+|(?<!\/\w+))$/,
- method: 'path',
- fullpage: 'all',
- },
- {
- id: 'inews',
- description: 'inews.id',
- hostname: /(^|\.)inews\.id$/,
- path: /\/(berita|read\/\d+|[a-z-]+\/[a-z-]+)\/.+(\/\d+|(?<!\/\w+))$/,
- method: 'path',
- fullpage: 'all',
- },
- {
- id: 'kompascom',
- description: 'kompas.com',
- hostname: /(^|\.)kompas\.com$/,
- path: /\/read\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'kompasiana',
- description: 'kompasiana.com',
- hostname: /(^|\.)kompasiana\.com$/,
- path: /\/.+(?<!series)\/\w{24}\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'kompastv',
- description: 'kompas.tv',
- hostname: /(^|\.)kompas\.tv$/,
- path: /^\/article\/\d+\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'kontan',
- description: 'kontan.co.id',
- hostname: /(^|\.)kontan\.co\.id$/,
- path: /^\/news\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'pr',
- description: 'pikiran-rakyat.com',
- hostname: /(^|\.)pikiran-rakyat\.com$/,
- path: /\/pr-\d+\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'promedia',
- description: 'aboutmalang.com, ayocirebon.com, jatimnetwork.com, hops.id, unews.id',
- hostname: /(^|\.)((aboutmalang|ayocirebon|jatimnetwork)\.com|(hops|unews)\.id)$/,
- path: /\/(pr-|)\d+\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'sindo',
- description: 'sindonews.com',
- hostname: /(^|\.)sindonews\.com$/,
- path: /^\/read\/\d+\/\d+\/.+(\/\d+0|(?<!\/\w+))$/,
- method: 'param',
- fullpage: 'showpage=all',
- },
- {
- id: 'suara',
- description: 'suara.com',
- hostname: /(^|\.)suara\.com$/,
- path: /\/\d{4}\/\d{2}\/\d{2}\/\d+\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'tribun',
- description: 'tribunnews.com',
- hostname: /(^|\.)tribunnews\.com$/,
- path: /\/\d{4}\/\d{2}\/\d{2}\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'viva',
- description: 'viva.co.id, tvonenews.com, intipseleb.com, sahijab.com, 100kpj.com',
- hostname: /(^|\.)(viva\.co\.id|(tvonenews|intipseleb|sahijab|100kpj)\.com)$/,
- path: /\/.+\/\d+-.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'wartaekonomi',
- description: 'wartaekonomi.co.id, herstory.co.id',
- hostname: /(^|\.)(wartaekonomi|herstory)\.co\.id$/,
- path: /^\/read\d+\/.+(?<!\/\w+)$/,
- method: 'param',
- fullpage: 'page=all',
- },
- {
- id: 'cnn',
- description: 'cnnindonesia.com',
- hostname: /(^|\.)cnnindonesia\.com$/,
- path: /\/\d+-\d+-\d+\/.+(\/\d+|(?<!\/\w+))$/,
- method: 'xhr',
- nextURL: '/',
- urlHelper: 0,
- desktop: {
- pagination: '.anchor_article_long',
- totalPages: 'a:last-of-type',
- content: '.detail_text',
- },
- mobile: {
- pagination: '.anchor_article_long',
- totalPages: 'a:last-of-type',
- content: '.detail_text',
- },
- },
- {
- id: 'genpi',
- description: 'genpi.co',
- hostname: /(^|\.)genpi\.co$/,
- path: /\/\d+\/.+(?<!\/\w+)$/,
- method: 'xhr',
- nextURL: '?page=',
- urlHelper: 0,
- desktop: {
- pagination: '.mnmd-pagination',
- totalPages: 'li:nth-last-of-type(3) a',
- content: 'div.entry-content div.col-md-10',
- },
- mobile: {
- pagination: '.mnmd-pagination',
- totalPages: 'li:nth-last-of-type(3) a',
- content: '.entry-content',
- },
- },
- {
- id: 'jpnn',
- description: 'jpnn.com',
- hostname: /(^|\.)jpnn\.com$/,
- path: /\/(news|[a-z-]+\/\d+)\/.+(?<!\/\w+)$/,
- method: 'xhr',
- nextURL: '?page=',
- urlHelper: 0,
- desktop: {
- pagination: '.pagination',
- totalPages: 'li:nth-last-of-type(3) a',
- content: 'div[itemprop=articleBody]',
- },
- mobile: {
- pagination: '.pagination',
- totalPages: 'li:nth-last-of-type(3) a',
- content: '.page-content',
- },
- },
- {
- id: 'okezone',
- description: 'okezone.com',
- hostname: /(^|\.)okezone\.com$/,
- path: /^\/read\/.+(?<!\/\w+)$/,
- method: 'xhr',
- nextURL: '?page=',
- urlHelper: 0,
- desktop: {
- pagination: '.paging',
- totalPages: '.second-paging',
- content: '#contentx',
- },
- mobile: {
- pagination: '.pagingxm',
- totalPages: '.halnext',
- content: '.description',
- },
- },
- {
- id: 'republika',
- description: 'republika.co.id',
- hostname: /(^|\.)republika\.co\.id$/,
- path: /^\/berita\/.+(?<!\/\w+)$/,
- method: 'xhr',
- nextURL: '-part',
- urlHelper: 1,
- desktop: {
- pagination: '.pagination',
- totalPages: 'li:nth-last-of-type(2) a',
- content: '.artikel',
- },
- mobile: {
- pagination: '.pagination',
- totalPages: 'li:nth-last-of-type(2) a',
- content: 'article',
- },
- },
- {
- id: 'tempo',
- description: 'tempo.co',
- hostname: /(^|\.)tempo\.co$/,
- path: /^\/read\/.+(?<!\/\w+)$/,
- method: 'xhr',
- nextURL: '?page_num=',
- urlHelper: 0,
- desktop: {
- pagination: '.pagging',
- totalPages: 'li:nth-last-of-type(2) a',
- content: '#isi',
- },
- mobile: {
- pagination: '.pagging',
- totalPages: 'li:nth-last-of-type(2) a',
- content: '#isi',
- },
- },
- ]
- //******************************************************************************
- const isValidURL = websites.find(urlChecker)
- if (isValidURL !== undefined) urlRedirector(isValidURL)
- function urlRedirector(site) {
- const redirectURL = new URLBuilder().hostname(url.hostname())
- switch (site.method) {
- case 'param' :
- if (site.id === 'cnbc' || site.id === 'detik') {
- const newPath = url.path().replace(/\/\d+$/, '')
- redirectURL.path(...splitPath(newPath))
- } else {
- redirectURL.path(...splitPath(url.path()))
- }
- redirectURL.param(site.fullpage)
- redirect(redirectURL.toString())
- break
- case 'path' :
- inewsRedirect(redirectURL, site.fullpage)
- break
- case 'dom' :
- case 'xhr' :
- neutralizeURL(redirectURL, site.id)
- }
- }
- function inewsRedirect(redirectURL, fullPage) {
- const newPath = url.path().replace(/\/\d+$/, '')
- redirectURL.path(...splitPath(newPath), fullPage)
- redirect(redirectURL.toString())
- }
- function neutralizeURL(redirectURL, id) {
- switch (id) {
- case 'genpi' :
- case 'idntimes' :
- case 'jpnn' :
- case 'okezone' :
- case 'tempo' :
- clearParamRedirect(redirectURL)
- break
- case 'cnn' :
- cnnRedirect(redirectURL)
- break
- case 'republika' :
- republikaRedirect(redirectURL)
- }
- }
- function clearParamRedirect(redirectURL) {
- if (url.param() !== '') {
- redirectURL.path(...splitPath(url.path()))
- redirect(redirectURL.toString())
- }
- }
- function cnnRedirect(redirectURL) {
- if (/\/\d+$/.test(url.path())) {
- const newPath = url.path().replace(/\/\d+$/, '')
- redirectURL.path(...splitPath(newPath))
- redirect(redirectURL.toString())
- }
- }
- function republikaRedirect(redirectURL) {
- if (/-part\d+$/.test(url.path())) {
- const newPath = url.path().replace(/-part\d+$/, '')
- redirectURL.path(...splitPath(newPath))
- redirect(redirectURL)
- }
- }
- //******************************************************************************
- window.addEventListener('DOMContentLoaded', async () => {
- log('DOM telah selesai dimuat')
- switch (isValidURL.method) {
- case 'dom' :
- generalDOM(isValidURL)
- break
- case 'xhr' :
- await generalXHR(isValidURL)
- }
- })
- const isMobile = /(^|\.)m\./.test(url.hostname()) || window.navigator.userAgent.includes('Mobi')
- const isDesktop = !isMobile
- function generalDOM(website) {
- if (website.id === 'idntimes') {
- idntimesDOM()
- }
- }
- function idntimesDOM() {
- const readMoreButton = document.querySelector('.read-more-btn-check')
- const splitPage = document.getElementsByClassName('split-page')
- if (readMoreButton !== null) {
- readMoreButton.remove()
- for (let i = 1; i < splitPage.length; i++) {
- splitPage[i].classList.add('open')
- }
- }
- }
- async function generalXHR(website) {
- const selector = isMobile ? website.mobile : website.desktop
- const totalPages = findTotalPages(selector.pagination, selector.totalPages)
- if (totalPages === 1) return
- const mainPageNode = document.querySelector(selector.content)
- cleaner(website.id, mainPageNode, 1)
- for (let i = 2; i <= totalPages; i++) {
- let nextPageUrl = url.href() + website.nextURL + (i - website.urlHelper)
- let nextPageNode = await getNextPage(nextPageUrl, i, selector.content)
- if (nextPageNode === null) return
- cleaner(website.id, nextPageNode, i, selector.pagination)
- let divider = pageDivider(i, totalPages)
- mainPageNode.append(divider, ...nextPageNode.children)
- log('Menambahkan halaman ke ' + i)
- }
- }
- function findTotalPages(paginationSelector, totalPagesSelector) {
- let pagination, totalPages
- try {
- pagination = document.querySelector(paginationSelector)
- totalPages = pagination.querySelector(totalPagesSelector)
- .textContent
- .match(/\d+/)
- } catch (e) {
- totalPages = 1
- log(e)
- } finally {
- if (totalPages > 1) {
- pagination.style.display = 'none'
- log('Pagination ditemukan, halaman berjumlah ' + totalPages)
- } else {
- totalPages = 1
- log('Pagination tidak ditemukan')
- }
- }
- return totalPages
- }
- function getNextPage(url, pageNumber, target) {
- log('Bersiap membuat XHR')
- return new Promise((resolve, reject) => {
- GM_xmlhttpRequest({
- method: 'GET',
- url: url,
- overrideMimeType: 'text/html; charset=UTF-8',
- responseType: 'document',
- binary: false,
- timeout: 0,
- headers: {
- 'user-agent': window.navigator.userAgent,
- },
- onerror: function () {
- alert('[AutoAllPage] Tidak bisa membuka halaman ke ' + pageNumber)
- log('Gagal membuat request XHR')
- reject(null)
- },
- onload: function (res) {
- const content = res.response.querySelector(target)
- if (content != null) {
- log('Berhasil mendapatkan halaman ke ' + pageNumber)
- resolve(content)
- } else {
- alert('[AutoAllPage] Gagal mendapatkan halaman ke ' + pageNumber)
- log('Gagal mendapatkan halaman ke ' + pageNumber)
- reject(null)
- }
- },
- })
- })
- }
- //******************************************************************************
- function cleaner(id, pageNode, pageNumber, pagination) {
- switch (id) {
- case 'cnn' :
- cnnCleaner(pageNode, pageNumber, pagination)
- break
- case 'genpi' :
- genpiCleaner(pageNode, pageNumber, pagination)
- break
- case 'okezone' :
- okezoneCleaner(pageNode, pageNumber)
- break
- case 'republika' :
- republikaCleaner(pageNode, pageNumber, pagination)
- break
- case 'tempo' :
- tempoCleaner(pageNode, pageNumber, pagination)
- }
- }
- function cnnCleaner(pageNode, pageNumber, pagination) {
- if (isDesktop) {
- if (pageNumber === 1) {
- document.querySelector('.styled-select')?.remove()
- document.querySelector('.skybanner')?.remove()
- pageNode.parentNode.style.display = 'block'
- }
- } else {
- if (pageNumber === 1) {
- pageNode.querySelector('select[name="page"]')?.parentElement.remove()
- } else {
- const headerArticle = pageNode.querySelector('.picdetail')
- while (pageNode.contains(headerArticle)) {
- pageNode.firstElementChild.remove()
- }
- }
- }
- pageNode.querySelector('.nav_article_long')?.remove()
- pageNode.querySelector(pagination)?.remove()
- log('Membersihkan halaman ke ' + pageNumber)
- }
- function genpiCleaner(pageNode, pageNumber, pagination) {
- if (isDesktop && pageNumber > 1) pageNode.querySelector('.entry-thumb')?.remove()
- const footer = pageNode.querySelector(pagination)
- footer?.nextElementSibling.remove()
- footer?.remove()
- log('Membersihkan halaman ke ' + pageNumber)
- }
- function okezoneCleaner(pageNode, pageNumber) {
- const footerArticle = pageNode.querySelector('#rctiplus')?.previousElementSibling
- while (pageNode.contains(footerArticle)) {
- pageNode.lastElementChild.remove()
- }
- log('Membersihkan halaman ke ' + pageNumber)
- }
- function republikaCleaner(pageNode, pageNumber, pagination) {
- if (isDesktop) {
- if (pageNumber > 1) pageNode.querySelector('.taiching')?.remove()
- pageNode.querySelector('.baca-juga')?.remove()
- } else {
- pageNode.querySelector(pagination)?.remove()
- }
- log('Membersihkan halaman ke ' + pageNumber)
- }
- function tempoCleaner(pageNode, pageNumber, pagination) {
- pageNode.querySelector(pagination)?.remove()
- log('Membersihkan halaman ke ' + pageNumber)
- }
- })()