Skip to content

Commit 35294d8

Browse files
committed
refactor: migrate index.html and title strategy from patch to localized files
- Move src/index.html to localized file management (.en.html/.html) - Move src/app/core/services/a-dev-title-strategy.ts to localized file management - Add both files to localizedFilePatterns in update-origin.ts - Remove obsolete change-document-title.patch and replace-canonical-host.patch - Simplify patch management by reducing file conflicts This change simplifies the patch application order and prevents conflicts between patches modifying the same file (index.html).
1 parent 2abd5d6 commit 35294d8

File tree

7 files changed

+342
-129
lines changed

7 files changed

+342
-129
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*!
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {Injectable, inject} from '@angular/core';
10+
import {NavigationItem} from '@angular/docs';
11+
import {Meta, Title} from '@angular/platform-browser';
12+
import {ActivatedRouteSnapshot, RouterStateSnapshot, TitleStrategy} from '@angular/router';
13+
14+
export const ROUTE_TITLE_PROPERTY = 'label';
15+
export const ROUTE_PARENT_PROPERTY = 'parent';
16+
export const TITLE_SUFFIX = 'Angular';
17+
export const TITLE_SEPARATOR = ' • ';
18+
export const DEFAULT_PAGE_TITLE = 'Overview';
19+
20+
export const TITLE_OG_META_TAG = 'og:title';
21+
export const TITLE_TWITTER_META_TAG = 'twitter:title';
22+
23+
export const ALL_TITLE_META_TAGS = [TITLE_OG_META_TAG, TITLE_TWITTER_META_TAG];
24+
25+
@Injectable({providedIn: 'root'})
26+
export class ADevTitleStrategy extends TitleStrategy {
27+
private readonly title = inject(Title);
28+
private readonly meta = inject(Meta);
29+
30+
constructor() {
31+
super();
32+
}
33+
34+
override updateTitle(routerState: RouterStateSnapshot) {
35+
const title = this.buildTitle(routerState);
36+
37+
if (title !== undefined) {
38+
this.title.setTitle(title);
39+
ALL_TITLE_META_TAGS.forEach((tag) => this.meta.updateTag({property: tag, content: title}));
40+
}
41+
}
42+
43+
override buildTitle(snapshot: RouterStateSnapshot): string {
44+
let route: ActivatedRouteSnapshot = snapshot.root;
45+
46+
while (route.firstChild) {
47+
route = route.firstChild;
48+
}
49+
50+
const data = route.data as NavigationItem;
51+
const routeTitle = data.label ?? '';
52+
53+
const prefix =
54+
routeTitle.startsWith(DEFAULT_PAGE_TITLE) && data.parent
55+
? `${data.parent.label}${TITLE_SEPARATOR}`
56+
: '';
57+
58+
return !!routeTitle ? `${prefix}${routeTitle}${TITLE_SEPARATOR}${TITLE_SUFFIX}` : TITLE_SUFFIX;
59+
}
60+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*!
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {Injectable, inject} from '@angular/core';
10+
import {NavigationItem} from '@angular/docs';
11+
import {Meta, Title} from '@angular/platform-browser';
12+
import {ActivatedRouteSnapshot, RouterStateSnapshot, TitleStrategy} from '@angular/router';
13+
14+
export const ROUTE_TITLE_PROPERTY = 'label';
15+
export const ROUTE_PARENT_PROPERTY = 'parent';
16+
export const TITLE_SUFFIX = 'Angular 日本語版';
17+
export const TITLE_SEPARATOR = ' • ';
18+
export const DEFAULT_PAGE_TITLE = 'Overview';
19+
20+
export const TITLE_OG_META_TAG = 'og:title';
21+
export const TITLE_TWITTER_META_TAG = 'twitter:title';
22+
23+
export const ALL_TITLE_META_TAGS = [TITLE_OG_META_TAG, TITLE_TWITTER_META_TAG];
24+
25+
@Injectable({providedIn: 'root'})
26+
export class ADevTitleStrategy extends TitleStrategy {
27+
private readonly title = inject(Title);
28+
private readonly meta = inject(Meta);
29+
30+
constructor() {
31+
super();
32+
}
33+
34+
override updateTitle(routerState: RouterStateSnapshot) {
35+
const title = this.buildTitle(routerState);
36+
37+
if (title !== undefined) {
38+
this.title.setTitle(title);
39+
ALL_TITLE_META_TAGS.forEach((tag) => this.meta.updateTag({property: tag, content: title}));
40+
}
41+
}
42+
43+
override buildTitle(snapshot: RouterStateSnapshot): string {
44+
let route: ActivatedRouteSnapshot = snapshot.root;
45+
46+
while (route.firstChild) {
47+
route = route.firstChild;
48+
}
49+
50+
const data = route.data as NavigationItem;
51+
const routeTitle = data.label ?? '';
52+
53+
const prefix =
54+
routeTitle.startsWith(DEFAULT_PAGE_TITLE) && data.parent
55+
? `${data.parent.label}${TITLE_SEPARATOR}`
56+
: '';
57+
58+
return !!routeTitle ? `${prefix}${routeTitle}${TITLE_SEPARATOR}${TITLE_SUFFIX}` : TITLE_SUFFIX;
59+
}
60+
}

adev-ja/src/index.en.html

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!doctype html>
2+
<!-- We set all theme classes to allow critters to inline the theme styles and prevent flickering -->
3+
<html lang="en" class="docs-dark-mode docs-light-mode">
4+
<head>
5+
<script>
6+
// This logic must execute early, so that we set the necessary
7+
// CSS classes to the document node and avoid unstyled content
8+
// from appearing on the page.
9+
const THEME_PREFERENCE_LOCAL_STORAGE_KEY = 'themePreference';
10+
const DARK_MODE_CLASS_NAME = 'docs-dark-mode';
11+
const LIGHT_MODE_CLASS_NAME = 'docs-light-mode';
12+
const PREFERS_COLOR_SCHEME_DARK = '(prefers-color-scheme: dark)';
13+
14+
15+
const theme = localStorage.getItem(THEME_PREFERENCE_LOCAL_STORAGE_KEY) ?? 'auto';
16+
const prefersDark =
17+
window.matchMedia && window.matchMedia(PREFERS_COLOR_SCHEME_DARK).matches;
18+
const documentClassList = this.document.documentElement.classList;
19+
20+
// clearing classes before setting them.
21+
this.document.documentElement.className = '';
22+
if (theme === 'dark' || (theme === 'auto' && prefersDark)) {
23+
documentClassList.add(DARK_MODE_CLASS_NAME);
24+
} else {
25+
documentClassList.add(LIGHT_MODE_CLASS_NAME);
26+
}
27+
28+
if(location.search.includes('uwu')) {
29+
documentClassList.add('uwu');
30+
}
31+
</script>
32+
<style>
33+
.uwu-logo {
34+
display: none;
35+
}
36+
html.uwu .angular-logo {
37+
display: none;
38+
}
39+
html.uwu .uwu-logo {
40+
display: block !important;
41+
}
42+
</style>
43+
44+
<meta charset="utf-8" />
45+
<title>Angular</title>
46+
<base href="/" />
47+
<meta name="viewport" content="width=device-width, initial-scale=1" />
48+
49+
<!-- Primary Meta Tags -->
50+
<meta name="description" content="The web development framework for building modern apps." />
51+
<meta name="author" content="Angular Team" />
52+
<meta
53+
name="keywords"
54+
content="Angular framework, TypeScript, web development, hydration, Signals, standalone components, accessibility, performance"
55+
/>
56+
57+
<!-- Favicons -->
58+
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
59+
<link rel="icon" type="image/png" sizes="48x48" href="/assets/icons/favicon-48x48.png" />
60+
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32x32.png" />
61+
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png" />
62+
<link rel="manifest" href="/assets/icons/site.webmanifest" />
63+
<link rel="mask-icon" href="/assets/icons/safari-pinned-tab.svg" color="#e90464" />
64+
<link rel="shortcut icon" href="/assets/icons/favicon.ico" />
65+
<link rel="canonical" href="https://angular.dev" />
66+
67+
<meta name="apple-mobile-web-app-title" content="Angular" />
68+
<meta name="application-name" content="Angular" />
69+
<meta name="msapplication-TileColor" content="#e90464" />
70+
<meta name="msapplication-config" content="/assets/icons/browserconfig.xml" />
71+
<meta name="theme-color" content="#ffffff" />
72+
73+
<!-- Open Graph / Facebook -->
74+
<meta property="og:type" content="website" />
75+
<meta property="og:url" content="https://angular.dev/" />
76+
<meta property="og:title" content="Angular" />
77+
<meta
78+
property="og:description"
79+
content="The web development framework for building modern apps."
80+
/>
81+
<meta property="og:image" content="https://angular.dev/assets/images/ng-image.jpg" />
82+
83+
<!-- Twitter -->
84+
<meta name="twitter:site" content="@Angular" />
85+
<meta name="twitter:creator" content="@Angular" />
86+
<meta property="twitter:card" content="summary_large_image" />
87+
<meta property="twitter:url" content="https://angular.dev/" />
88+
<meta property="twitter:title" content="Angular" />
89+
<meta
90+
property="twitter:description"
91+
content="The web development framework for building modern apps."
92+
/>
93+
<meta property="twitter:image" content="https://angular.dev/assets/images/ng-image.jpg" />
94+
95+
<!-- Fonts -->
96+
<link rel="preconnect" href="https://fonts.googleapis.com" />
97+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
98+
<link
99+
href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@500;600&family=Inter:wght@400;500;600&family=DM+Mono:ital@0;1&display=swap"
100+
rel="stylesheet"
101+
/>
102+
<link
103+
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0"
104+
rel="stylesheet"
105+
/>
106+
</head>
107+
<body class="mat-typography docs-scroll-track-transparent-large">
108+
<adev-root></adev-root>
109+
</body>
110+
</html>

adev-ja/src/index.html

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!doctype html>
2+
<!-- We set all theme classes to allow critters to inline the theme styles and prevent flickering -->
3+
<html lang="ja" class="docs-dark-mode docs-light-mode">
4+
<head>
5+
<script>
6+
// This logic must execute early, so that we set the necessary
7+
// CSS classes to the document node and avoid unstyled content
8+
// from appearing on the page.
9+
const THEME_PREFERENCE_LOCAL_STORAGE_KEY = 'themePreference';
10+
const DARK_MODE_CLASS_NAME = 'docs-dark-mode';
11+
const LIGHT_MODE_CLASS_NAME = 'docs-light-mode';
12+
const PREFERS_COLOR_SCHEME_DARK = '(prefers-color-scheme: dark)';
13+
14+
15+
const theme = localStorage.getItem(THEME_PREFERENCE_LOCAL_STORAGE_KEY) ?? 'auto';
16+
const prefersDark =
17+
window.matchMedia && window.matchMedia(PREFERS_COLOR_SCHEME_DARK).matches;
18+
const documentClassList = this.document.documentElement.classList;
19+
20+
// clearing classes before setting them.
21+
this.document.documentElement.className = '';
22+
if (theme === 'dark' || (theme === 'auto' && prefersDark)) {
23+
documentClassList.add(DARK_MODE_CLASS_NAME);
24+
} else {
25+
documentClassList.add(LIGHT_MODE_CLASS_NAME);
26+
}
27+
28+
if(location.search.includes('uwu')) {
29+
documentClassList.add('uwu');
30+
}
31+
</script>
32+
<style>
33+
.uwu-logo {
34+
display: none;
35+
}
36+
html.uwu .angular-logo {
37+
display: none;
38+
}
39+
html.uwu .uwu-logo {
40+
display: block !important;
41+
}
42+
</style>
43+
44+
<meta charset="utf-8" />
45+
<title>Angular 日本語版</title>
46+
<base href="/" />
47+
<meta name="viewport" content="width=device-width, initial-scale=1" />
48+
49+
<!-- Primary Meta Tags -->
50+
<meta name="description" content="モダンなアプリを構築するためのウェブ開発フレームワーク" />
51+
<meta name="author" content="Angular Team" />
52+
<meta
53+
name="keywords"
54+
content="Angular framework, TypeScript, web development, hydration, Signals, standalone components, accessibility, performance"
55+
/>
56+
57+
<!-- Favicons -->
58+
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
59+
<link rel="icon" type="image/png" sizes="48x48" href="/assets/icons/favicon-48x48.png" />
60+
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32x32.png" />
61+
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png" />
62+
<link rel="manifest" href="/assets/icons/site.webmanifest" />
63+
<link rel="mask-icon" href="/assets/icons/safari-pinned-tab.svg" color="#e90464" />
64+
<link rel="shortcut icon" href="/assets/icons/favicon.ico" />
65+
<link rel="canonical" href="https://angular.jp" />
66+
67+
<meta name="apple-mobile-web-app-title" content="Angular" />
68+
<meta name="application-name" content="Angular" />
69+
<meta name="msapplication-TileColor" content="#e90464" />
70+
<meta name="msapplication-config" content="/assets/icons/browserconfig.xml" />
71+
<meta name="theme-color" content="#ffffff" />
72+
73+
<!-- Open Graph / Facebook -->
74+
<meta property="og:type" content="website" />
75+
<meta property="og:url" content="https://angular.jp/" />
76+
<meta property="og:title" content="Angular 日本語版" />
77+
<meta
78+
property="og:description"
79+
content="モダンなアプリを構築するためのウェブ開発フレームワーク"
80+
/>
81+
<meta property="og:image" content="https://angular.jp/assets/images/ng-image.jpg" />
82+
83+
<!-- Twitter -->
84+
<meta name="twitter:site" content="@Angular" />
85+
<meta name="twitter:creator" content="@Angular" />
86+
<meta property="twitter:card" content="summary_large_image" />
87+
<meta property="twitter:url" content="https://angular.jp/" />
88+
<meta property="twitter:title" content="Angular 日本語版" />
89+
<meta
90+
property="twitter:description"
91+
content="モダンなアプリを構築するためのウェブ開発フレームワーク"
92+
/>
93+
<meta property="twitter:image" content="https://angular.jp/assets/images/ng-image.jpg" />
94+
95+
<!-- Fonts -->
96+
<link rel="preconnect" href="https://fonts.googleapis.com" />
97+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
98+
<link
99+
href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@500;600&family=Inter:wght@400;500;600&family=DM+Mono:ital@0;1&display=swap"
100+
rel="stylesheet"
101+
/>
102+
<link
103+
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0"
104+
rel="stylesheet"
105+
/>
106+
</head>
107+
<body class="mat-typography docs-scroll-track-transparent-large">
108+
<adev-root></adev-root>
109+
</body>
110+
</html>

0 commit comments

Comments
 (0)