Skip to content

Commit

Permalink
fix(template): switch locale use Location service for scene with base…
Browse files Browse the repository at this point in the history
…-href (#398)
  • Loading branch information
why520crazy committed Sep 22, 2022
1 parent abe594b commit 6fe13b5
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 109 deletions.
121 changes: 55 additions & 66 deletions packages/template/src/services/global-context.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { DocgeniSiteConfig } from './../interfaces/config';
import { CONFIG_TOKEN, GlobalContext } from './global-context';
import { createServiceFactory, createHttpFactory, SpectatorHttp, HttpMethod } from '@ngneat/spectator';
import { NavigationItem } from '../interfaces';
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http';
import { Location } from '@angular/common';

describe('GlobalContext', () => {
let spectator: SpectatorHttp<GlobalContext>;
Expand All @@ -19,6 +23,22 @@ describe('GlobalContext', () => {
mocks: []
});

function createGlobalContext(config: Partial<DocgeniSiteConfig>) {
const globalContext = new GlobalContext(
config as DocgeniSiteConfig,
TestBed.inject(HttpClient),
document,
TestBed.inject(Location)
);
return globalContext;
}

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule]
});
});

afterEach(() => {
window.localStorage.setItem('docgeni-locale', '');
});
Expand All @@ -38,102 +58,71 @@ describe('GlobalContext', () => {
});

it(`should set locale from defaultLocale in site config`, () => {
const globalContext = new GlobalContext(
{
defaultLocale: 'zh-cn'
} as DocgeniSiteConfig,
undefined,
document
);
const globalContext = createGlobalContext({
defaultLocale: 'zh-cn'
});
expect(globalContext.locale).toBe('zh-cn');
});

it(`should set locale from cache`, () => {
window.localStorage.setItem('docgeni-locale', 'en-us');
const globalContext = new GlobalContext(
{
defaultLocale: 'zh-cn',
locales: [
{ key: 'zh-cn', name: '中文' },
{ key: 'en-us', name: '英文' }
]
} as DocgeniSiteConfig,
undefined,
document
);
const globalContext = createGlobalContext({
defaultLocale: 'zh-cn',
locales: [
{ key: 'zh-cn', name: '中文' },
{ key: 'en-us', name: '英文' }
]
} as DocgeniSiteConfig);
expect(globalContext.locale).toBe('en-us');
});

it(`should use default locale when cache locale is not in locales`, () => {
window.localStorage.setItem('docgeni-locale', 'en-us');
const globalContext = new GlobalContext(
{
defaultLocale: 'zh-cn',
locales: [{ key: 'zh-cn', name: '中文' }]
} as DocgeniSiteConfig,
undefined,
document
);
const globalContext = createGlobalContext({
defaultLocale: 'zh-cn',
locales: [{ key: 'zh-cn', name: '中文' }]
} as DocgeniSiteConfig);
expect(globalContext.locale).toBe('zh-cn');
});

it(`should use browser locale`, () => {
const browserLanguage = window.navigator.language;
const globalContext = new GlobalContext(
{
defaultLocale: '',
locales: [{ key: browserLanguage, name: browserLanguage }]
} as DocgeniSiteConfig,
undefined,
document
);
const globalContext = createGlobalContext({
defaultLocale: '',
locales: [{ key: browserLanguage, name: browserLanguage }]
} as DocgeniSiteConfig);
expect(globalContext.locale).toBe(browserLanguage);
});

it(`should use url locale`, () => {
const globalContext = new GlobalContext(
{
defaultLocale: 'zh-cn',
locales: [
{ key: 'zh-cn', name: '中文' },
{ key: 'en-us', name: 'EN' }
]
} as DocgeniSiteConfig,
undefined,
{
location: {
pathname: '/en-us/hello'
}
}
);
TestBed.inject(Location).go('/en-us/hello');
const globalContext = createGlobalContext({
defaultLocale: 'zh-cn',
locales: [
{ key: 'zh-cn', name: '中文' },
{ key: 'en-us', name: 'EN' }
]
} as DocgeniSiteConfig);
expect(globalContext.locale).toBe('en-us');
});
});

describe('mode', () => {
it(`should set mode from site config`, () => {
const globalContext = new GlobalContext(
{
defaultLocale: 'zh-cn',
mode: 'full'
} as DocgeniSiteConfig,
undefined,
document
);
const globalContext = createGlobalContext({
defaultLocale: 'zh-cn',
mode: 'full'
} as DocgeniSiteConfig);
expect(globalContext.config.mode).toBe('full');
expect(document.documentElement.classList.contains(`dg-mode-full`));
});

it(`should set mode from cache`, () => {
window.localStorage.setItem('docgeni-mode', 'lite');
const globalContext = new GlobalContext(
{
defaultLocale: 'zh-cn',
mode: 'full'
} as DocgeniSiteConfig,
undefined,
document
);
const globalContext = createGlobalContext({
defaultLocale: 'zh-cn',
mode: 'full'
} as DocgeniSiteConfig);
expect(globalContext.config.mode).toBe('lite');
expect(document.documentElement.classList.contains(`dg-mode-lite`));
window.localStorage.clear();
Expand Down Expand Up @@ -219,7 +208,7 @@ describe('GlobalContext', () => {
},
{ id: '', title: '', path: '', items: [{ id: '4', title: '', path: '', hidden: true }] }
];
const globalContext = new GlobalContext({} as DocgeniSiteConfig, undefined, document);
const globalContext = createGlobalContext({} as DocgeniSiteConfig);
const result = globalContext.sortDocItems(list);
expect(result.length).toBe(3);
expect(result.map(item => item.id)).toEqual(['1', '2', '3']);
Expand Down
81 changes: 47 additions & 34 deletions packages/template/src/services/global-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, Inject, InjectionToken } from '@angular/core';
import { DocgeniSiteConfig, NavigationItem, DocgeniMode, HomeDocMeta } from '../interfaces/public-api';
import { HttpClient } from '@angular/common/http';
import { languageCompare } from '../utils/language-compare';
import { DOCUMENT } from '@angular/common';
import { DOCUMENT, Location } from '@angular/common';
export const CONFIG_TOKEN = new InjectionToken('DOC_SITE_CONFIG');

export const DEFAULT_CONFIG: DocgeniSiteConfig = {
Expand All @@ -17,27 +17,32 @@ const DOCGENI_MODE_KEY = 'docgeni-mode';
providedIn: 'root'
})
export class GlobalContext {
locale: string;
locale!: string;

navs: NavigationItem[];
navs!: NavigationItem[];

docItems: NavigationItem[];
docItems!: NavigationItem[];

homeMeta: HomeDocMeta;
homeMeta!: HomeDocMeta;

owner: string;
owner!: string;

repo: string;
repo!: string;

get isDefaultLocale() {
return this.locale === this.config.defaultLocale;
}

constructor(@Inject(CONFIG_TOKEN) public config: DocgeniSiteConfig, private http: HttpClient, @Inject(DOCUMENT) private document: any) {
constructor(
@Inject(CONFIG_TOKEN) public config: DocgeniSiteConfig,
private http: HttpClient,
@Inject(DOCUMENT) private document: any,
private location: Location
) {
this.setup();
}

private getLocaleKey() {
private getLocaleKey(): string {
const localeKeyFromUrl = this.getLocalKeyFromUrl();
if (localeKeyFromUrl) {
return localeKeyFromUrl;
Expand All @@ -49,7 +54,7 @@ export class GlobalContext {
if (locale) {
return locale.key;
} else {
return this.config.defaultLocale;
return this.config.defaultLocale as string;
}
}
}
Expand All @@ -63,16 +68,18 @@ export class GlobalContext {
}

document.body.classList.add(`dg-mode-${this.config.mode}`, `dg-theme-${this.config.theme}`);
const pattern = /https:\/\/github.com\/([^\/]*)\/([^\/]*)/.exec(this.config.repoUrl);
if (pattern && pattern.length === 3) {
this.owner = pattern[1];
this.repo = pattern[2];
if (this.config.repoUrl) {
const pattern = /https:\/\/github.com\/([^\/]*)\/([^\/]*)/.exec(this.config.repoUrl);
if (pattern && pattern.length === 3) {
this.owner = pattern[1];
this.repo = pattern[2];
}
}
}

public getLocalKeyFromUrl() {
const localeFromUrl = (this.config.locales || []).find(locale => {
return this.document.location.pathname.startsWith(`/${locale.key}`);
return this.location.path().startsWith(`/${locale.key}`);
});
return localeFromUrl && localeFromUrl.key;
}
Expand All @@ -88,17 +95,21 @@ export class GlobalContext {

initialize() {
return new Promise((resolve, reject) => {
this.http.get(`assets/content/navigations-${this.locale}.json?t=${this.getNowTimestamp()}`).subscribe({
next: (response: { navs: NavigationItem[]; docs: NavigationItem[]; homeMeta: HomeDocMeta }) => {
this.homeMeta = response.homeMeta;
this.navs = response.navs;
this.docItems = this.sortDocItems(this.navs);
resolve(response);
},
error: error => {
reject(error);
}
});
this.http
.get<{ navs: NavigationItem[]; docs: NavigationItem[]; homeMeta: HomeDocMeta }>(
`assets/content/navigations-${this.locale}.json?t=${this.getNowTimestamp()}`
)
.subscribe({
next: (response: { navs: NavigationItem[]; docs: NavigationItem[]; homeMeta: HomeDocMeta }) => {
this.homeMeta = response.homeMeta;
this.navs = response.navs;
this.docItems = this.sortDocItems(this.navs);
resolve(response);
},
error: error => {
reject(error);
}
});
});
}

Expand All @@ -111,14 +122,16 @@ export class GlobalContext {
const list: NavigationItem[] = [];
while (navs.length) {
const item = navs.shift();
if (item.items) {
item.items.forEach(child => {
child.ancestors = child.ancestors || [];
child.ancestors.push(...(item.ancestors || []), item);
});
navs.unshift(...item.items);
} else if (!item.hidden) {
list.push(item);
if (item) {
if (item.items) {
item.items.forEach(child => {
child.ancestors = child.ancestors || [];
child.ancestors.push(...(item.ancestors || []), item);
});
navs.unshift(...item.items);
} else if (!item.hidden) {
list.push(item);
}
}
}
return list;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DOCUMENT } from '@angular/common';
import { Location } from '@angular/common';
import { Component, OnInit, HostBinding, ElementRef, Inject } from '@angular/core';
import { NavigationService, GlobalContext } from '../../services/public-api';

Expand All @@ -9,9 +9,9 @@ import { NavigationService, GlobalContext } from '../../services/public-api';
export class LocalesSelectorComponent implements OnInit {
@HostBinding('class.dg-locales-selector') isNavbar = true;

locale: string;
locale!: string;

constructor(public global: GlobalContext, public navigationService: NavigationService, @Inject(DOCUMENT) private document: any) {}
constructor(public global: GlobalContext, public navigationService: NavigationService, private location: Location) {}

ngOnInit(): void {
this.locale = this.global.locale;
Expand All @@ -23,14 +23,13 @@ export class LocalesSelectorComponent implements OnInit {
if (isDefaultLocale) {
this.global.setLocale(this.locale);
}
const currentPath = this.location.path();
if (localKeyFromUrl) {
location.href =
document.location.origin +
document.location.pathname.replace('/' + localKeyFromUrl, isDefaultLocale ? '' : `/${this.locale}`);
this.location.go(currentPath.replace('/' + localKeyFromUrl, isDefaultLocale ? '' : `/${this.locale}`));
} else {
location.href = isDefaultLocale
? document.location.origin + document.location.pathname
: document.location.origin + `/${this.locale}` + location.pathname;
this.location.go(isDefaultLocale ? currentPath : `/${this.locale}${currentPath}`);
}
// 强制刷新
location.href = location.href;
}
}

0 comments on commit 6fe13b5

Please sign in to comment.