wip
This commit is contained in:
parent
2a915374dd
commit
ffba07a6e7
|
@ -10,7 +10,6 @@ import '@/style.scss';
|
||||||
import { createApp, defineAsyncComponent } from 'vue';
|
import { createApp, defineAsyncComponent } from 'vue';
|
||||||
import { setIframeId, postMessageToParentWindow } from '@/scripts/post-message.js';
|
import { setIframeId, postMessageToParentWindow } from '@/scripts/post-message.js';
|
||||||
import { parseEmbedParams } from '@/embed-page.js';
|
import { parseEmbedParams } from '@/embed-page.js';
|
||||||
import { createEmbedRouter } from '@/router.js';
|
|
||||||
|
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const embedParams = parseEmbedParams(params);
|
const embedParams = parseEmbedParams(params);
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
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 address = new URL(document.querySelector<HTMLMetaElement>('meta[property="instance_url"]')?.content || location.href);
|
||||||
const siteName = document.querySelector<HTMLMetaElement>('meta[property="og:site_name"]')?.content;
|
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 instanceName = siteName === 'Misskey' || siteName == null ? host : siteName;
|
||||||
export const ui = miLocalStorage.getItem('ui');
|
export const ui = miLocalStorage.getItem('ui');
|
||||||
export const debug = miLocalStorage.getItem('debug') === 'true';
|
export const debug = miLocalStorage.getItem('debug') === 'true';
|
||||||
// config.tsでインポートしているファイルと、その内部で使用される関数では使用できない。
|
|
||||||
// それらでembedPageの判定をしたい場合は関数を直接呼び出すこと
|
|
||||||
export const embedPage = isEmbedPage();
|
|
||||||
|
|
||||||
export function updateLocale(newLocale): void {
|
export function updateLocale(newLocale): void {
|
||||||
locale = newLocale;
|
locale = newLocale;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { isEmbedPage } from '@/scripts/embed-page.js';
|
|
||||||
|
|
||||||
export type Keys =
|
export type Keys =
|
||||||
'v' |
|
'v' |
|
||||||
|
@ -45,25 +44,18 @@ export type Keys =
|
||||||
// セッション毎に廃棄されるLocalStorage代替(embedなどで使用)
|
// セッション毎に廃棄されるLocalStorage代替(embedなどで使用)
|
||||||
const safeSessionStorage = new Map<Keys, string>();
|
const safeSessionStorage = new Map<Keys, string>();
|
||||||
|
|
||||||
const embedPage = isEmbedPage();
|
|
||||||
|
|
||||||
export const miLocalStorage = {
|
export const miLocalStorage = {
|
||||||
getItem: (key: Keys): string | null => {
|
getItem: (key: Keys): string | null => {
|
||||||
if (embedPage) {
|
|
||||||
return safeSessionStorage.get(key) ?? null;
|
|
||||||
}
|
|
||||||
return window.localStorage.getItem(key);
|
return window.localStorage.getItem(key);
|
||||||
},
|
},
|
||||||
setItem: (key: Keys, value: string): void => {
|
setItem: (key: Keys, value: string): void => {
|
||||||
if (embedPage) {
|
if (false) {
|
||||||
safeSessionStorage.set(key, value);
|
|
||||||
} else {
|
} else {
|
||||||
window.localStorage.setItem(key, value);
|
window.localStorage.setItem(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeItem: (key: Keys): void => {
|
removeItem: (key: Keys): void => {
|
||||||
if (embedPage) {
|
if (false) {
|
||||||
safeSessionStorage.delete(key);
|
|
||||||
} else {
|
} else {
|
||||||
window.localStorage.removeItem(key);
|
window.localStorage.removeItem(key);
|
||||||
}
|
}
|
||||||
|
@ -79,26 +71,3 @@ export const miLocalStorage = {
|
||||||
miLocalStorage.setItem(key, JSON.stringify(value));
|
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');
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,16 +5,6 @@
|
||||||
|
|
||||||
//#region Embed関連の定義
|
//#region Embed関連の定義
|
||||||
|
|
||||||
let _isEmbedPage: boolean | null = null;
|
|
||||||
|
|
||||||
/** 埋め込みページかどうか */
|
|
||||||
export function isEmbedPage() {
|
|
||||||
if (_isEmbedPage === null) {
|
|
||||||
_isEmbedPage = location.pathname.startsWith('/embed/');
|
|
||||||
}
|
|
||||||
return _isEmbedPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 埋め込みの対象となるエンティティ(/embed/xxx の xxx の部分と対応させる) */
|
/** 埋め込みの対象となるエンティティ(/embed/xxx の xxx の部分と対応させる) */
|
||||||
const embeddableEntities = [
|
const embeddableEntities = [
|
||||||
'notes',
|
'notes',
|
||||||
|
@ -30,7 +20,7 @@ export type EmbeddableEntity = typeof embeddableEntities[number];
|
||||||
export const embedRouteWithScrollbar: EmbeddableEntity[] = [
|
export const embedRouteWithScrollbar: EmbeddableEntity[] = [
|
||||||
'clips',
|
'clips',
|
||||||
'tags',
|
'tags',
|
||||||
'user-timeline'
|
'user-timeline',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** 埋め込みコードのパラメータ */
|
/** 埋め込みコードのパラメータ */
|
||||||
|
@ -57,42 +47,3 @@ export const defaultEmbedParams = {
|
||||||
} as const satisfies EmbedParams;
|
} as const satisfies EmbedParams;
|
||||||
|
|
||||||
//#endregion
|
//#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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue