diff --git a/res/mobile_article_page.css b/res/mobile_article_page.css new file mode 100644 index 000000000..6de633f24 --- /dev/null +++ b/res/mobile_article_page.css @@ -0,0 +1,9 @@ +body { + margin: 0 auto; +} +.reference-link::after { + content: none !important; +} +.mw-body h3, .mw-body h2 { + width: auto; +} diff --git a/res/script.js b/res/script.js index 2e484cdb2..cdb654c62 100644 --- a/res/script.js +++ b/res/script.js @@ -27,6 +27,21 @@ window.onload = function () { /* Add the user-agent to allow dedicated CSS rules (like for KaiOS) */ document.querySelector('body').setAttribute('data-useragent', navigator.userAgent); + + // Check if there is a PCS output page + if (document.querySelector('#pcs')) { + document.addEventListener("DOMContentLoaded", function() { + const supElements = document.querySelectorAll('sup'); + const backLinkElements = document.querySelectorAll('a.pcs-ref-back-link'); + const disabledElems = Array.from(supElements).concat(Array.from(backLinkElements)) + disabledElems.forEach((elem) => { + elem.addEventListener('click', (event) => { + event.stopPropagation(); + }, true); + }); + }); + } + } /* WebP Polyfill */ diff --git a/src/Downloader.ts b/src/Downloader.ts index 12e48210b..fd6f80345 100644 --- a/src/Downloader.ts +++ b/src/Downloader.ts @@ -198,6 +198,13 @@ class Downloader { break } break + case 'WikimediaMobile': + if (MediaWiki.hasWikimediaMobileApi()) { + this.baseUrl = MediaWiki.mobileApiUrl.href + this.baseUrlForMainPage = MediaWiki.mobileApiUrl.href + break + } + break default: throw new Error('Unable to find specific API end-point to retrieve article HTML') } diff --git a/src/config.ts b/src/config.ts index d30ae9252..68d4338cc 100644 --- a/src/config.ts +++ b/src/config.ts @@ -56,6 +56,7 @@ const config = { // CSS resources added by Kiwix cssResources: ['style', 'content.parsoid', 'inserted_style'], mainPageCssResources: ['mobile_main_page'], + mobileArticleCssResources: ['mobile_article_page'], jsResources: ['script', 'masonry.min', 'article_list_home', 'images_loaded.min', '../node_modules/details-element-polyfill/dist/details-element-polyfill'], diff --git a/src/renderers/wikimedia-mobile.renderer.ts b/src/renderers/wikimedia-mobile.renderer.ts index 7a7496186..67cb0d025 100644 --- a/src/renderers/wikimedia-mobile.renderer.ts +++ b/src/renderers/wikimedia-mobile.renderer.ts @@ -1,10 +1,11 @@ import * as domino from 'domino' import * as logger from '../Logger.js' +import { config } from '../config.js' import { Renderer } from './abstract.renderer.js' import { getStrippedTitleFromHtml } from '../util/misc.js' import { RenderOpts, RenderOutput } from './abstract.renderer.js' -type PipeFunction = (data: string) => string +type PipeFunction = (value: DominoElement) => DominoElement | Promise // Represent 'https://{wikimedia-wiki}/api/rest_v1/page/mobile-html/' export class WikimediaMobileRenderer extends Renderer { @@ -27,25 +28,32 @@ export class WikimediaMobileRenderer extends Renderer { const displayTitle = this.getStrippedTitle(renderOpts) if (data) { - const { finalHTML, subtitles, mediaDependencies } = await super.processHtml(data, dump, articleId, articleDetail, _moduleDependencies, webp) - const finalHTMLDoc = domino.createDocument(finalHTML) - const mobileHTML = this.pipeMobileTransformations( - finalHTMLDoc, - this.addMobileModules, + let mediaDependenciesVal + let subtitlesVal + const mobileHTML = domino.createDocument(data) + const finalHTMLMobile = await this.pipeMobileTransformations( + mobileHTML, this.convertLazyLoadToImages, this.removeEditContainer, this.removeHiddenClass, + async (doc) => { + const { finalHTML, subtitles, mediaDependencies } = await super.processHtml(doc.documentElement.outerHTML, dump, articleId, articleDetail, _moduleDependencies, webp) + + mediaDependenciesVal = mediaDependencies + subtitlesVal = subtitles + return domino.createDocument(finalHTML) + }, this.restoreLinkDefaults, - this.disableClientLinkListener, + this.addMobileModules, this.overrideMobileStyles, ) result.push({ articleId, displayTitle, - html: mobileHTML.documentElement.outerHTML, - mediaDependencies, - subtitles, + html: finalHTMLMobile.documentElement.outerHTML, + mediaDependencies: mediaDependenciesVal, + subtitles: subtitlesVal, }) return result } @@ -55,8 +63,12 @@ export class WikimediaMobileRenderer extends Renderer { } } - private pipeMobileTransformations(value, ...fns: PipeFunction[]) { - return fns.reduce((acc, fn) => fn(acc), value) + private async pipeMobileTransformations(value: DominoElement, ...fns: PipeFunction[]): Promise { + let result: DominoElement | Promise = value + for (const fn of fns) { + result = fn(await result) + } + return result } private addMobileModules(doc: DominoElement) { @@ -156,26 +168,6 @@ export class WikimediaMobileRenderer extends Renderer { return doc } - private disableClientLinkListener(doc: DominoElement) { - const scriptEl = doc.createElement('script') - scriptEl.type = 'text/javascript' - scriptEl.text = ` - document.addEventListener("DOMContentLoaded", function() { - const supElements = document.querySelectorAll('sup'); - const backLinkElements = document.querySelectorAll('a.pcs-ref-back-link'); - const disabledElems = Array.from(supElements).concat(Array.from(backLinkElements)) - disabledElems.forEach((elem) => { - elem.addEventListener('click', (event) => { - event.stopPropagation(); - }, true); - }); - }); - ` - doc.head.appendChild(scriptEl) - - return doc - } - private overrideMobileStyles(doc: DominoElement) { const styleEl = doc.createElement('style') styleEl.innerHTML = `