質問: "niconico://sm9") { chrome.tabs.create({url: niocnicoUrl, active:false}, OnTabCreated); } function OnTabCreated(tabInfo) { console.log("tab id " + tabInfo.id); chrome.tabs.remove(tabInfo.id, () => { if (chrome.runtime.lastError) { console.log("failed: " + chrome.runtime.lastError); } else { console.log("removed tab"); } }); } ``` 独自プロトコルのURLではtabs.createのコールバックを受けられないのでしょうか? manifest.jsonを含めたソースコード テスト環境 Windows 10 AU適用済み Firefox Developer Edition 51.0a2 (2016-10-27) (32-bit)
回答: 自己解決しました。 原因 カスタムURIスキーマの場合、chrome.tabs.createの第二引数に渡されるコールバックは呼び出されません。(これがバグか仕様なのかは調べがつきませんでした。) 回避方法 カスタムURIスキーマを指定して作成したタブを、chrome.tabs.queryで取得して手動で閉じるようにします。 注意点として、カスタムURIスキーマにhost要素が含まれない場合、chrome.tabs.query( {url: urlPattern} ) のurlPatternの判定で invalid pattern の判定がされる場合があります。 サンプルコード ``` function OpenNiconicoProtocol(niocnicoUrl) { chrome.tabs.query({ currentWindow: true, active: true }, function (maybeCurrentTab) { var currentTab = maybeCurrentTab[0]; // 新しいタブとして開く chrome.tabs.create({url: niocnicoUrl, active:false}); // カスタムスキームURLは tabs.create のコールバックが呼ばれない // 少ししてから不要なタブを閉じる処理を実行する setTimeout(function() { // queryに 渡す url がカスタムスキームかつ // host部分がないURLパターンの場合 // invalid patternとなり対応していない // すべてのタブを取得して不要なタブを逐次判断する形で回避する chrome.tabs.query( {}, (tabs) => { if (tabs && tabs.length) { for (var tabIndex in tabs) { var tab = tabs[tabIndex]; var isRemoveTarget = false; if (tab.url && isNiconicoSchemeUrl(tab.url)) { isRemoveTarget = true; } else if (currentTab.index < tabIndex) { // httpとしてレンダリングが実行されてないページは // tab.urlがabout:blankのままっぽい (firefoxで確認) // 現在のタブより新しく開いたっぽい空ページタブを対象として判断 if (tab.url && tab.url == "about:blank") { isRemoveTarget = true; } } if (isRemoveTarget) { chrome.tabs.remove(tab.id, () => { if (chrome.runtime.lastError) { console.log("failed: " + chrome.runtime.lastError); } else { console.log("removed tab"); } }); } } } }); }, 1000); }); } ``` **参考** Chrome拡張機能から外部プログラムでリンクを開く前にタブを閉じるには(英語) chrome.tabs.query url pattern