Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(build): copy images that are only in default locale to l10n folder #7917

Merged
merged 11 commits into from
Jul 17, 2023
23 changes: 7 additions & 16 deletions build/check-images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import { DEFAULT_LOCALE } from "../libs/constants";
*
*/
export function checkImageReferences(doc, $, options, { url, rawContent }) {
const filePaths = new Set();
// filePaths is a map of basename to full path
const filePaths = new Map<string, string>();
caugner marked this conversation as resolved.
Show resolved Hide resolved

const checkImages = options.flawLevels.get("images") !== FLAW_LEVELS.IGNORE;

Expand Down Expand Up @@ -137,9 +138,7 @@ export function checkImageReferences(doc, $, options, { url, rawContent }) {
// insensitively.

// What follows uses the same algorithm as Image.findByURLWithFallback
// but only adds a filePath if it exists for the DEFAULT_LOCALE
const filePath = Image.findByURL(finalSrc);
let enUSFallback = false;
let filePath = Image.findByURL(finalSrc);
if (
!filePath &&
doc.locale !== DEFAULT_LOCALE &&
Expand All @@ -149,23 +148,15 @@ export function checkImageReferences(doc, $, options, { url, rawContent }) {
new RegExp(`^/${doc.locale}/`, "i"),
`/${DEFAULT_LOCALE}/`
);
if (Image.findByURL(enUSFinalSrc)) {
// Use the en-US src instead
finalSrc = enUSFinalSrc;
// Note that this `<img src="...">` value can work if you use the
// en-US equivalent URL instead.
enUSFallback = true;
}
// try to find the image in the default locale
filePath = Image.findByURL(enUSFinalSrc);
}
if (filePath) {
filePaths.add(filePath);
filePaths.set(path.basename(filePath), filePath);
}

if (checkImages) {
if (enUSFallback) {
// If it worked by switching to the en-US src, don't do anything more.
// Do nothing! I.e. don't try to perfect the spelling.
} else if (!filePath) {
if (!filePath) {
// E.g. <img src="doesnotexist.png"
addImageFlaw(img, src, {
explanation:
Expand Down
4 changes: 2 additions & 2 deletions build/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,10 @@ async function buildDocuments(
fs.writeFileSync(liveSamplePath, html);
}

for (const filePath of fileAttachments) {
for (const [basename, filePath] of fileAttachments) {
caugner marked this conversation as resolved.
Show resolved Hide resolved
// We *could* use symlinks instead. But, there's no point :)
// Yes, a symlink is less disk I/O but it's nominal.
fs.copyFileSync(filePath, path.join(outPath, path.basename(filePath)));
fs.copyFileSync(filePath, path.join(outPath, basename));
}

// Collect active documents' slugs to be used in sitemap building and
Expand Down
29 changes: 24 additions & 5 deletions build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {
MacroRedirectedLinkError,
} from "../kumascript/src/errors";

import { Document, Image, execGit } from "../content";
import { Document, Image, execGit, slugToFolder } from "../content";
import { CONTENT_ROOT, REPOSITORY_URLS } from "../libs/env";
import * as kumascript from "../kumascript";

import { FLAW_LEVELS } from "../libs/constants";
import { DEFAULT_LOCALE, FLAW_LEVELS } from "../libs/constants";
import { extractSections } from "./extract-sections";
import { extractSidebar } from "./extract-sidebar";
import { extractSummary } from "./extract-summary";
Expand Down Expand Up @@ -154,7 +154,7 @@ function postLocalFileLinks($, doc) {
// links, so it's presumed to be worth it.
if (
!href ||
/^(\/|\.\.|http|#|mailto:|about:|ftp:|news:|irc:|ftp:)/i.test(href)
/^(\/|\.\.|http|#|mailto:|about:|ftp:|news:|irc:)/i.test(href)
) {
return;
}
Expand Down Expand Up @@ -276,7 +276,7 @@ function getAdjacentImages(documentDirectory) {
export interface BuiltDocument {
doc: Doc;
liveSamples: any;
fileAttachments: any;
fileAttachments: Map<string, string>;
caugner marked this conversation as resolved.
Show resolved Hide resolved
bcdData: BCDData[];
source?: {
github_url: string;
Expand Down Expand Up @@ -500,9 +500,28 @@ export async function buildDocument(
// it returns which images it checked. But we'll need to complement any
// other images in the folder.
getAdjacentImages(path.dirname(document.fileInfo.path)).forEach((fp) =>
fileAttachments.add(fp)
fileAttachments.set(path.basename(fp), fp)
);

if (doc.locale !== DEFAULT_LOCALE) {
// If it's not the default locale, we need to add the images
// from the default locale too.
const defaultLocaleDir = path.join(
CONTENT_ROOT,
DEFAULT_LOCALE.toLowerCase(),
slugToFolder(metadata.slug)
);

if (fs.existsSync(defaultLocaleDir)) {
getAdjacentImages(defaultLocaleDir).forEach((fp) => {
const basename = path.basename(fp);
if (!fileAttachments.has(basename)) {
fileAttachments.set(basename, fp);
}
});
}
}

// Check the img tags for possible flaws and possible build-time rewrites
checkImageWidths(doc, $, options, document);

Expand Down
47 changes: 43 additions & 4 deletions testing/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,11 @@ test("content built foo page", () => {
expect($('script[src="/static/js/ga.js"]')).toHaveLength(1);

// Because this en-US page has a French translation
expect($('link[rel="alternate"]')).toHaveLength(3);
expect($('link[rel="alternate"]')).toHaveLength(4);
expect($('link[rel="alternate"][hreflang="en"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="fr"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="zh"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="zh-TW"]')).toHaveLength(1);
const toEnUSURL = $('link[rel="alternate"][hreflang="en"]').attr("href");
const toFrURL = $('link[rel="alternate"][hreflang="fr"]').attr("href");
// The domain is hardcoded because the URL needs to be absolute and when
Expand Down Expand Up @@ -248,10 +249,11 @@ test("content built French foo page", () => {
const htmlFile = path.join(builtFolder, "index.html");
const html = fs.readFileSync(htmlFile, "utf-8");
const $ = cheerio.load(html);
expect($('link[rel="alternate"]')).toHaveLength(3);
expect($('link[rel="alternate"]')).toHaveLength(4);
expect($('link[rel="alternate"][hreflang="en"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="fr"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="zh"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="zh-TW"]')).toHaveLength(1);
expect($('meta[property="og:locale"]').attr("content")).toBe("fr");
expect($('meta[property="og:title"]').attr("content")).toBe(
"<foo>: Une page de test | MDN"
Expand Down Expand Up @@ -283,6 +285,39 @@ test("French translation using English front-matter bits", () => {
expect(bcd.value.query).toBe("javascript.builtins.Array.toLocaleString");
});

test("content built zh-CN page with en-US fallback image", () => {
const builtFolder = path.join(buildRoot, "zh-cn", "docs", "web", "foo");
const jsonFile = path.join(builtFolder, "index.json");
expect(fs.existsSync(jsonFile)).toBeTruthy();
const { doc } = JSON.parse(fs.readFileSync(jsonFile, "utf-8")) as {
doc: Doc;
};
expect(Object.keys(doc.flaws)).toHaveLength(1);
expect(doc.flaws.translation_differences).toHaveLength(1);
expect(doc.title).toBe("<foo>: 测试网页");
expect(doc.isTranslated).toBe(true);
expect(doc.other_translations[0].locale).toBe("en-US");
expect(doc.other_translations[0].native).toBe("English (US)");
expect(doc.other_translations[0].title).toBe("<foo>: A test tag");

const htmlFile = path.join(builtFolder, "index.html");
const html = fs.readFileSync(htmlFile, "utf-8");
const $ = cheerio.load(html);
expect($('link[rel="alternate"]')).toHaveLength(4);
expect($('link[rel="alternate"][hreflang="en"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="fr"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="zh"]')).toHaveLength(2);
yin1999 marked this conversation as resolved.
Show resolved Hide resolved
expect($('meta[property="og:locale"]').attr("content")).toBe("zh-CN");
expect($('meta[property="og:title"]').attr("content")).toBe(
"<foo>: 测试网页 | MDN"
);

// The image should be in the built folder,
// even though it's not referenced in the translated content.
const imageFile = path.join(builtFolder, "screenshot.png");
expect(fs.existsSync(imageFile)).toBeTruthy();
});

test("content built zh-TW page with en-US fallback image", () => {
const builtFolder = path.join(buildRoot, "zh-tw", "docs", "web", "foo");
const jsonFile = path.join(builtFolder, "index.json");
Expand All @@ -301,17 +336,21 @@ test("content built zh-TW page with en-US fallback image", () => {
const htmlFile = path.join(builtFolder, "index.html");
const html = fs.readFileSync(htmlFile, "utf-8");
const $ = cheerio.load(html);
expect($('link[rel="alternate"]')).toHaveLength(3);
expect($('link[rel="alternate"]')).toHaveLength(4);
expect($('link[rel="alternate"][hreflang="en"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="fr"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="zh"]')).toHaveLength(1);
expect($('link[rel="alternate"][hreflang="zh-TW"]')).toHaveLength(1);
expect($('meta[property="og:locale"]').attr("content")).toBe("zh-TW");
expect($('meta[property="og:title"]').attr("content")).toBe(
"<foo>: 測試網頁 | MDN"
);
expect($("#content img").attr("src")).toBe(
"/en-US/docs/Web/Foo/screenshot.png"
"/zh-TW/docs/Web/Foo/screenshot.png"
);

const imageFile = path.join(builtFolder, "screenshot.png");
expect(fs.existsSync(imageFile)).toBeTruthy();
});

test("content built French Embeddable page", () => {
Expand Down
10 changes: 10 additions & 0 deletions testing/translated-content/files/zh-cn/web/foo/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: "<foo>: 测试网页"
slug: Web/Foo
translation_of: Web/Foo
---

This is a test page for copying all the images from the default locale to the
translated locale.

We should not reference the images in the default locale.