This commit is contained in:
syuilo 2024-08-23 08:12:09 +09:00
parent 2a915374dd
commit ffba07a6e7
5 changed files with 91 additions and 88 deletions

View File

@ -10,7 +10,6 @@ import '@/style.scss';
import { createApp, defineAsyncComponent } from 'vue';
import { setIframeId, postMessageToParentWindow } from '@/scripts/post-message.js';
import { parseEmbedParams } from '@/embed-page.js';
import { createEmbedRouter } from '@/router.js';
const params = new URLSearchParams(location.search);
const embedParams = parseEmbedParams(params);

View File

@ -0,0 +1,88 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
//#region Embed関連の定義
/** 埋め込みの対象となるエンティティ(/embed/xxx の xxx の部分と対応させる) */
const embeddableEntities = [
'notes',
'user-timeline',
'clips',
'tags',
] as const;
/** 埋め込みの対象となるエンティティ */
export type EmbeddableEntity = typeof embeddableEntities[number];
/** 内部でスクロールがあるページ */
export const embedRouteWithScrollbar: EmbeddableEntity[] = [
'clips',
'tags',
'user-timeline',
];
/** 埋め込みコードのパラメータ */
export type EmbedParams = {
maxHeight?: number;
colorMode?: 'light' | 'dark';
rounded?: boolean;
border?: boolean;
autoload?: boolean;
header?: boolean;
};
/** 正規化されたパラメータ */
export type ParsedEmbedParams = Required<Omit<EmbedParams, 'maxHeight' | 'colorMode'>> & Pick<EmbedParams, 'maxHeight' | 'colorMode'>;
/** パラメータのデフォルトの値 */
export const defaultEmbedParams = {
maxHeight: undefined,
colorMode: undefined,
rounded: true,
border: true,
autoload: false,
header: true,
} as const satisfies EmbedParams;
//#endregion
/**
*
* @param searchParams URLSearchParamsもしくはクエリ文字列
* @returns
*/
export function parseEmbedParams(searchParams: URLSearchParams | string): ParsedEmbedParams {
let _searchParams: URLSearchParams;
if (typeof searchParams === 'string') {
_searchParams = new URLSearchParams(searchParams);
} else if (searchParams instanceof URLSearchParams) {
_searchParams = searchParams;
} else {
throw new Error('searchParams must be URLSearchParams or string');
}
const params: EmbedParams = {};
for (const key in defaultEmbedParams) {
const value = _searchParams.get(key);
if (value != null) {
if (value === 'true') {
params[key] = true;
} else if (value === 'false') {
params[key] = false;
} else if (!isNaN(Number(value))) {
params[key] = Number(value);
} else if (key === 'colorMode' && ['light', 'dark'].includes(value)) {
params[key] = value as 'light' | 'dark';
} else {
params[key] = value;
}
}
}
return {
...defaultEmbedParams,
...params,
};
}

View File

@ -4,7 +4,6 @@
*/
import { miLocalStorage } from '@/local-storage.js';
import { isEmbedPage } from '@/scripts/embed-page.js';
const address = new URL(document.querySelector<HTMLMetaElement>('meta[property="instance_url"]')?.content || location.href);
const siteName = document.querySelector<HTMLMetaElement>('meta[property="og:site_name"]')?.content;
@ -22,9 +21,6 @@ export const version = _VERSION_;
export const instanceName = siteName === 'Misskey' || siteName == null ? host : siteName;
export const ui = miLocalStorage.getItem('ui');
export const debug = miLocalStorage.getItem('debug') === 'true';
// config.tsでインポートしているファイルと、その内部で使用される関数では使用できない。
// それらでembedPageの判定をしたい場合は関数を直接呼び出すこと
export const embedPage = isEmbedPage();
export function updateLocale(newLocale): void {
locale = newLocale;

View File

@ -2,7 +2,6 @@
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { isEmbedPage } from '@/scripts/embed-page.js';
export type Keys =
'v' |
@ -45,25 +44,18 @@ export type Keys =
// セッション毎に廃棄されるLocalStorage代替embedなどで使用
const safeSessionStorage = new Map<Keys, string>();
const embedPage = isEmbedPage();
export const miLocalStorage = {
getItem: (key: Keys): string | null => {
if (embedPage) {
return safeSessionStorage.get(key) ?? null;
}
return window.localStorage.getItem(key);
},
setItem: (key: Keys, value: string): void => {
if (embedPage) {
safeSessionStorage.set(key, value);
if (false) {
} else {
window.localStorage.setItem(key, value);
}
},
removeItem: (key: Keys): void => {
if (embedPage) {
safeSessionStorage.delete(key);
if (false) {
} else {
window.localStorage.removeItem(key);
}
@ -79,26 +71,3 @@ export const miLocalStorage = {
miLocalStorage.setItem(key, JSON.stringify(value));
},
};
if (embedPage) {
/**
* EmbedページではlocalStorageを使用できないようにしているが
* safeSessionStorageに移動する
*/
const keysToDuplicate: Keys[] = [
'v',
'instance',
'instanceCachedAt',
'lang',
'locale',
'localeVersion',
];
keysToDuplicate.forEach(key => {
const value = window.localStorage.getItem(key);
if (value && !miLocalStorage.getItem(key)) {
miLocalStorage.setItem(key, value);
}
});
if (_DEV_) console.warn('Using safeSessionStorage as localStorage alternative');
}

View File

@ -5,16 +5,6 @@
//#region Embed関連の定義
let _isEmbedPage: boolean | null = null;
/** 埋め込みページかどうか */
export function isEmbedPage() {
if (_isEmbedPage === null) {
_isEmbedPage = location.pathname.startsWith('/embed/');
}
return _isEmbedPage;
}
/** 埋め込みの対象となるエンティティ(/embed/xxx の xxx の部分と対応させる) */
const embeddableEntities = [
'notes',
@ -30,7 +20,7 @@ export type EmbeddableEntity = typeof embeddableEntities[number];
export const embedRouteWithScrollbar: EmbeddableEntity[] = [
'clips',
'tags',
'user-timeline'
'user-timeline',
];
/** 埋め込みコードのパラメータ */
@ -57,42 +47,3 @@ export const defaultEmbedParams = {
} as const satisfies EmbedParams;
//#endregion
/**
*
* @param searchParams URLSearchParamsもしくはクエリ文字列
* @returns
*/
export function parseEmbedParams(searchParams: URLSearchParams | string): ParsedEmbedParams {
let _searchParams: URLSearchParams;
if (typeof searchParams === 'string') {
_searchParams = new URLSearchParams(searchParams);
} else if (searchParams instanceof URLSearchParams) {
_searchParams = searchParams;
} else {
throw new Error('searchParams must be URLSearchParams or string');
}
const params: EmbedParams = {};
for (const key in defaultEmbedParams) {
const value = _searchParams.get(key);
if (value != null) {
if (value === 'true') {
params[key] = true;
} else if (value === 'false') {
params[key] = false;
} else if (!isNaN(Number(value))) {
params[key] = Number(value);
} else if (key === 'colorMode' && ['light', 'dark'].includes(value)) {
params[key] = value as 'light' | 'dark';
} else {
params[key] = value;
}
}
}
return {
...defaultEmbedParams,
...params,
};
}