下書き(未公開)。〔 〕と「要決定」の箇所は未確定です。
縦書き原稿仮称

プログラム / src/chrome/background.js

src/chrome/background.js

// Toolbar click opens our editor directly. No access to other sites is requested.let opening = null;let pendingTabId = null;const editorUrl = chrome.runtime.getURL('editor.html');async function focusEditor(tabId, windowId) {  let tab;  try { tab = await chrome.tabs.update(tabId, { active: true }); }  catch { return false; } // The editor may have been closed during the lookup.  try { await chrome.windows.update(tab.windowId ?? windowId, { focused: true }); }  catch (error) { console.warn('原稿タブは開いています。ウィンドウの切替に失敗しました。', error); }  return true;}async function openEditor() {  const contexts = await chrome.runtime.getContexts({ contextTypes: ['TAB'], documentUrls: [editorUrl] });  for (const context of contexts) {    if (context.tabId >= 0 && await focusEditor(context.tabId, context.windowId)) return;  }  // Keep a just-created tab while its document is still loading. This also  // prevents a second quick click from opening a second editing copy.  if (pendingTabId !== null && await focusEditor(pendingTabId)) return;  const tab = await chrome.tabs.create({ url: editorUrl });  pendingTabId = tab.id;}chrome.tabs.onRemoved.addListener(tabId => {  if (pendingTabId === tabId) pendingTabId = null;});chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {  if (pendingTabId === tabId && (changeInfo.status === 'complete' ||      changeInfo.url && changeInfo.url !== editorUrl)) pendingTabId = null;});chrome.action.onClicked.addListener(() => {  if (!opening) opening = openEditor().catch(error => {    console.error('縦書き原稿を開けませんでした。', error);  }).finally(() => { opening = null; });  return opening;});