Skip to content

Commit

Permalink
Render mobile images to standard size
Browse files Browse the repository at this point in the history
  • Loading branch information
audiodude committed Jun 21, 2024
1 parent 7911a16 commit 7c79b4d
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 3 deletions.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"test-verbose": "npm run test:unit-coverage && npm run test:e2e-coverage",
"test-without-coverage": "npm run test:unit -- -- --silent && npm run test:e2e -- -- --silent",
"codecov": "nyc --reporter=lcov npm t",
"codecov:unit": "nyc --reporter=text-lcov npm run test:unit-coverage > coverage.lcov",
"lint": "eslint -c .eslintrc.cjs --ext .ts .",
"lint-fix": "eslint -c .eslintrc.cjs --ext .ts --fix .",
"format": "prettier --write './**/*.ts'",
Expand Down Expand Up @@ -106,6 +107,7 @@
"split-by-grapheme": "^1.0.1",
"swig-templates": "^2.0.3",
"typescript": "^4.9.4",
"url-join": "^5.0.0",
"utf8-binary-cutter": "^0.9.2",
"webp-hero": "0.0.2",
"yargs": "^17.7.1"
Expand Down
22 changes: 19 additions & 3 deletions src/renderers/wikimedia-mobile.renderer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import * as domino from 'domino'
import urlJoin from 'url-join'
import * as logger from '../Logger.js'
import { MobileRenderer } from './abstractMobile.render.js'
import { getStrippedTitleFromHtml } from '../util/misc.js'
import { RenderOpts, RenderOutput } from './abstract.renderer.js'

type PipeFunction = (value: DominoElement) => DominoElement | Promise<DominoElement>

export const MOBILE_IMG_WIDTH = '140px'

// Represent 'https://{wikimedia-wiki}/api/rest_v1/page/mobile-html/'
export class WikimediaMobileRenderer extends MobileRenderer {
constructor() {
Expand Down Expand Up @@ -33,7 +36,7 @@ export class WikimediaMobileRenderer extends MobileRenderer {
const mobileHTML = domino.createDocument(data)
const finalHTMLMobile = await this.pipeMobileTransformations(
mobileHTML,
this.convertLazyLoadToImages,
this.INTERNAL.convertLazyLoadToImages,
this.removeEditContainer,
this.removeHiddenClass,
async (doc) => {
Expand Down Expand Up @@ -91,16 +94,25 @@ export class WikimediaMobileRenderer extends MobileRenderer {
return doc
}

private convertLazyLoadToImages(doc: DominoElement) {
private convertLazyLoadToImagesImpl(doc: DominoElement) {
const protocol = 'https://'
const spans = doc.querySelectorAll('.pcs-lazy-load-placeholder')

function getImgSrc(element: DominoElement) {
let src = element.getAttribute('data-src')
const origSrc = element.getAttribute('data-data-file-original-src')
if (origSrc && /\/\d+px/.test(origSrc)) {
src = origSrc.replace(/\/\d+px/, `/${MOBILE_IMG_WIDTH}`)
}
return urlJoin(protocol, src)
}

spans.forEach((span: DominoElement) => {
// Create a new img element
const img = doc.createElement('img') as DominoElement

// Set the attributes for the img element based on the data attributes in the span
img.src = protocol + span.getAttribute('data-src')
img.src = getImgSrc(span)
img.setAttribute('decoding', 'async')
img.width = span.getAttribute('data-width')
img.height = span.getAttribute('data-height')
Expand Down Expand Up @@ -148,4 +160,8 @@ export class WikimediaMobileRenderer extends MobileRenderer {

return doc
}

public readonly INTERNAL = {
convertLazyLoadToImages: this.convertLazyLoadToImagesImpl,
}
}
143 changes: 143 additions & 0 deletions test/unit/renderers/mobile.renderer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import * as domino from 'domino'

import { WikimediaMobileRenderer } from '../../../src/renderers/wikimedia-mobile.renderer'

describe('mobile renderer', () => {
let window

describe('image converter', () => {
beforeEach(() => {
window = domino.createWindow(
`
<figure typeof="mw:File/Thumb" class="pcs-widen-image-ancestor">
<a href="./Fichier:Bamako_et_fleuve_Niger.jpg" class="mw-file-description pcs-widen-image-ancestor">
<span class="mw-file-element pcs-widen-image-override pcs-lazy-load-placeholder pcs-lazy-load-placeholder-pending"
style="width: 320px;" data-class="mw-file-element pcs-widen-image-override"
data-src="//upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Bamako_et_fleuve_Niger.jpg/320px-Bamako_et_fleuve_Niger.jpg"
data-srcset="//upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Bamako_et_fleuve_Niger.jpg/480px-Bamako_et_fleuve_Niger.jpg 1.5x"
data-width="320" data-height="241" data-data-file-width="600" data-data-file-height="450"
data-data-file-original-src="//upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Bamako_et_fleuve_Niger.jpg/250px-Bamako_et_fleuve_Niger.jpg"
>
<span style="padding-top: 75.3125%;"></span>
</span>
</a>
<figcaption>Bamako</figcaption>
</figure>
<figure typeof="mw:File/Thumb" class="pcs-widen-image-ancestor">
<a href="./Fichier:Bamako_bridge2.jpg" class="mw-file-description pcs-widen-image-ancestor">
<span class="mw-file-element pcs-widen-image-override pcs-lazy-load-placeholder pcs-lazy-load-placeholder-pending"
style="width: 640px;" data-class="mw-file-element pcs-widen-image-override"
data-src="//upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg/640px-Bamako_bridge2.jpg"
data-width="640" data-height="428" data-data-file-width="800" data-data-file-height="533"
data-data-file-original-src="//upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg/250px-Bamako_bridge2.jpg"
>
<span style="padding-top: 66.875%;"></span>
</span>
</a>
<figcaption> Bamako Pont, mi bɛ Niger baw kan</figcaption>
</figure>
<p>
San 2021 mɔgɔ 3 000 000 dɛ tun sigin len bɛ Mali faba kɔnɔ. An bɛ yoro mi nan farafina be kono Bamakɔ fanga wili tɔgɔ ka bɔ ni bɛɛ ta ye. wa
dumia kɔnɔ a bɛ la wɔrɔ dugu la dɛ la singɛ munu la
</p>
<p><b>bamakɔ</b> dɛ yɛ ka famgadɔda yɛ.wa nafa ka bɔ a lamini mara bɛ ma </p>
<p>
Bamako faaba kila nɛ dɔ ni <b>ki</b> woro dɛ yɛ. ni o niɛmogo tɔgɔ IBRAHIMA N’DIAYE ni ɔ ba fɔ ɔ ma maire
Kinw minu bɛ Bamakɔ kɔnɔ:
</p>
<ul>
<li>Hippɔdrɔme (tɔgɔkɔrɔ milliɔnki)</li>
<li>Korofina</li>
<li>Badalabugu</li>
<li>Bamakɔ Kura</li>
<li>Jikoroni</li>
<li>Bakɔ jikɔrɔni (= derrière le fleuve)</li>
<li>Misira</li>
<li>Medina Kura</li>
<li>Bankɔni</li>
<li>Maɲambugu</li>
<li>Dravela</li>
<li>Jɛlibugu</li>
<li>Bolibana</li>
<li>Wɔlɔfɔbugu</li>
<li>Bajalan I,II,III</li>
<li>ɲarela</li>
<li>Bagadaji</li>
<li>Bozola</li>
<li>Falaje</li>
<li>ɲamakoro</li>
<li>Sɛbenikɔrɔ</li>
<li>Quinzanbugu</li>
<li>Kinsanbugu</li>
<li>Amdalayɛ</li>
<li>Sabalibugu</li>
<li>Titibugu</li>
<li>Lafiabugu</li>
<li>Badalabugu</li>
<li>Torokɔrɔbugu</li>
<li>Quartier du fleuve</li>
</ul>`,
'http://bm.wikipedia.org/api/rest_v1/page/mobile-html/BamakBamakɔ',
)
})

test('it converts lazy load to images with the proper size', async () => {
const mobileRenderer = new WikimediaMobileRenderer()

const actual = mobileRenderer.INTERNAL.convertLazyLoadToImages(window.document)
const spans = actual.querySelectorAll('.pcs-lazy-load-placeholder')
const imgs = actual.querySelectorAll('img')

expect(spans.length).toBe(0)
expect(imgs.length).toBe(2)
expect(imgs[0].src).toEqual('https://upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Bamako_et_fleuve_Niger.jpg/140px-Bamako_et_fleuve_Niger.jpg')
expect(imgs[1].src).toEqual('https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg/140px-Bamako_bridge2.jpg')
})

test('it falls back to src attribute if data-data-file-original does not match ZZZpx', () => {
const testWindow = domino.createWindow(
`
<span class="mw-file-element pcs-widen-image-override pcs-lazy-load-placeholder pcs-lazy-load-placeholder-pending"
style="width: 640px;" data-class="mw-file-element pcs-widen-image-override"
data-src="//upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg/640px-Bamako_bridge2.jpg"
data-width="640" data-height="428" data-data-file-width="800" data-data-file-height="533"
data-data-file-original-src="//upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg"
>
<span style="padding-top: 66.875%;"></span>
</span>
`,
'http://bm.wikipedia.org/api/rest_v1/page/mobile-html/BamakBamakɔ',
)
const mobileRenderer = new WikimediaMobileRenderer()

const actual = mobileRenderer.INTERNAL.convertLazyLoadToImages(testWindow.document)
const imgs = actual.querySelectorAll('img')

expect(imgs[0].src).toEqual('https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg/640px-Bamako_bridge2.jpg')
})

test('it falls back to src attribute if data-data-file-original does not exist', () => {
const testWindow = domino.createWindow(
`
<span class="mw-file-element pcs-widen-image-override pcs-lazy-load-placeholder pcs-lazy-load-placeholder-pending"
style="width: 640px;" data-class="mw-file-element pcs-widen-image-override"
data-src="//upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg/640px-Bamako_bridge2.jpg"
data-width="640" data-height="428" data-data-file-width="800" data-data-file-height="533"
>
<span style="padding-top: 66.875%;"></span>
</span>
`,
'http://bm.wikipedia.org/api/rest_v1/page/mobile-html/BamakBamakɔ',
)
const mobileRenderer = new WikimediaMobileRenderer()

const actual = mobileRenderer.INTERNAL.convertLazyLoadToImages(testWindow.document)
const imgs = actual.querySelectorAll('img')

expect(imgs[0].src).toEqual('https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Bamako_bridge2.jpg/640px-Bamako_bridge2.jpg')
})
})
})

0 comments on commit 7c79b4d

Please sign in to comment.