Skip to content

Commit

Permalink
✨ includeの導入
Browse files Browse the repository at this point in the history
  • Loading branch information
r74tech committed Nov 1, 2023
1 parent 3a6204e commit 0c33c92
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 28 deletions.
18 changes: 0 additions & 18 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import css from './css/wikidot.css';
import init from './css/init.css';
import collapsible from './css/collapsible.css';

import { TextWikiParseInclude } from './script/include';


import {
handleDOMContentLoaded
Expand All @@ -18,19 +16,3 @@ document.querySelector("head > style#collapsible")!.innerHTML = collapsible;
document.querySelector("head > style#init")!.innerHTML = init;
// Event listeners...
document.addEventListener('DOMContentLoaded', handleDOMContentLoaded);




// const wiki: Wiki = {
// source: '[[include component:topsubtitle |TITLE=test]]',
// vars: {}
// };

// console.log("Source before parsing: \n", wiki.source);
// const parser = new TextWikiParseInclude(wiki);
// parser.parse().then(() => {
// console.log("Source after parsing: \n", wiki.source);
// }).catch(error => {
// console.error("Parsing failed with error: ", error);
// });
27 changes: 23 additions & 4 deletions src/script/eventHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
generateShortId, getOrCreateUserShortId, getCurrentPageShortId, encryptSha256, setCookie, getCookie
} from './utils';

import { TextWikiParseInclude } from './include';
import { TextWikiParseInclude } from "./include";


import {
Expand Down Expand Up @@ -174,9 +174,28 @@ const handleEditpageInput = debounce((event) => {

// [WIP] includeの処理を行う
// include元のソースを保持する。(GASの実行制限を考慮して、include元のソースを保持する必要がある)
// include元を取得するためのボタンを用意する(5秒おきに取得するのは非効率的)
// include元のページを配列で持っておいて、その中身に変更があった場合は、include元のソースを増えたものだけ取得しに行く

ftml.postMessage({ value, type });

const wiki = {
source: editpageField.value,
vars: {}
};

// console.log("Source before parsing: \n", wiki.source);
const parser = new TextWikiParseInclude(wiki);

// onEditでthis.wiki.sourceを更新する。editpageFieldが更新されたらonEditにeventを渡す。
// editpageField.addEventListener('input', parser.onEdit.bind(parser));
parser.onEdit(event).then(() => {
// console.log("Source after parsing: \n", wiki.source);
ftml.postMessage({ value: wiki.source, type });
}
).catch(error => {
console.error("Parsing failed with error: ", error);
});

// ftml.postMessage({ value, type });

}, 1000);

Expand Down Expand Up @@ -298,7 +317,7 @@ const handleShareButtonClick = async () => {
}




console.debug('Sending data to GAS:', dataToSend);

Expand Down
91 changes: 85 additions & 6 deletions src/script/include.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ class Page {
export class TextWikiParseInclude {
private conf = { base: '/path/to/scripts/' };
private regex = /^\[\[include ([a-zA-Z0-9\s\-:]+?)(\s+.*?)?(?:\]\])$/ims;
private includedPages: string[] = [];

constructor(private wiki: Wiki) { }
constructor(private wiki: Wiki) {
this.updateIncludedPages();
}

async parse(): Promise<void> {
let level = 0;
Expand All @@ -35,23 +38,29 @@ export class TextWikiParseInclude {
}
level++;
} while (oldSource !== this.wiki.source && level <= 10);
this.saveIncludedPagesToLocalStorage();
}


private async process(matches: string[]): Promise<string> {
const [pageName, subs] = matches;
const cleanedPageName = this.toUnixName(pageName.trim());

// const page = await this.getPageFromDb(cleanedPageName);
const cachedPages = this.getCachedPages();
// console.log('cachedPages:', cachedPages);
// cachedPagesにpageNameがあれば、pageIdとsourceを取得
// なければ、GASから取得
const cachedPage = cachedPages[pageName];
const page = cachedPage ? new Page(cachedPage.pageId, cachedPage.source) : await this.getPageFromDb(cleanedPageName);

const page = await this.getPageFromDb(cleanedPageName);
if (!page) {
const output = `\n\n[[div class="error-block"]]\nPage to be included ${cleanedPageName} cannot be found!\n[[/div]]\n\n`;
this.wiki.vars.inclusionsNotExist = { ...this.wiki.vars.inclusionsNotExist, [cleanedPageName]: cleanedPageName };
return output;
}

let output = page.getSource();
if (subs) {
if (subs && output) {
const subsArray = subs.split('|');
for (const sub of subsArray) {
const [varName, value] = sub.split('=').map(s => s.trim());
Expand All @@ -66,7 +75,6 @@ export class TextWikiParseInclude {
}

private toUnixName(name: string): string {
// return name.replace(/\s+/g, '_').toLowerCase();
return name.replace(/\s+/g, '_');
}

Expand All @@ -79,4 +87,75 @@ export class TextWikiParseInclude {
return null;
}
}
}

private updateIncludedPages() {
const regex = /\[\[include ([a-zA-Z0-9\s\-:]+?)(\s+.*?)?\]\]/g;
let match;
while ((match = regex.exec(this.wiki.source)) !== null) {
// this.includedPages.push(match[1].trim()); //重複を削除したい
const pageName = match[1].trim();
if (!this.includedPages.includes(pageName)) {
this.includedPages.push(pageName);
}
}
}

private saveIncludedPagesToLocalStorage() {
localStorage.setItem('includedPages', JSON.stringify(this.includedPages));
}

static loadIncludedPagesFromLocalStorage(): string[] {
const savedData = localStorage.getItem('includedPages');
if (savedData) {
const savedPages = JSON.parse(savedData);
if (Array.isArray(savedPages)) {
return savedPages;
}
}
return [];
}

async onEdit(event: Event) {
const source = (event.target as HTMLTextAreaElement).value;
// console.log('Source changed:', source);
this.wiki.source = source; // クラス内のwiki.sourceを更新
this.updateIncludedPages(); // 引数なしで呼び出し
await this.checkForNewIncludes();
this.saveIncludedPagesToLocalStorage();

// paese()を呼び出し、wiki.sourceを更新
await this.parse();
}

private async checkForNewIncludes() {
const cachedPages = this.getCachedPages();
const newIncludes = this.includedPages.filter(page => !cachedPages[page]);
if (newIncludes.length > 0) {
await this.fetchPagesFromGAS(newIncludes);
}
}

private async fetchPagesFromGAS(pages: string[]) {
for (const page of pages) {
try {
const data = await getDataFromGAS(page);
this.cachePage(page, data);
} catch (error) {
console.error('Failed to fetch page:', page, error);
}
}
}

private cachePage(pageName: string, data: any) {
const cachedPages = this.getCachedPages();
cachedPages[pageName] = { pageId: data.data.shortId, source: data.data.source }; // オブジェクトをそのまま保存
localStorage.setItem('cachedPages', JSON.stringify(cachedPages)); // オブジェクトを文字列に変換して保存
}

private getCachedPages(): Record<string, { pageId: string; source: string }> {
const savedData = localStorage.getItem('cachedPages');
return savedData ? JSON.parse(savedData) : {};
}

}

0 comments on commit 0c33c92

Please sign in to comment.