クロスドメインフレームを含むフレームの完全な階層をチェックする新しいコンテンツスクリプトを挿入します。必要に応じて
メインコンテンツスクリプトは、バックグラウンド/イベントページを要求します:
if (document.activeElement.matches('input') && window == parent) {
console.log('Input', document.activeElement);
document.activeElement.value += ' gotcha!';
} else {
chrome.runtime.sendMessage({action: 'modifyInput'});
}
background/event pageスクリプトはすべてのフレームに追加コンテンツのスクリプトを実行します。
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse)) {
if (msg.action == 'modifyInput') {
chrome.tabs.executeScript(sender.tab && sender.tab.id, {
file: 'modify-input.js',
allFrames: true,
matchAboutBlank: true,
runAt: 'document_end',
});
}
});
修正・入力を。 js、IIFEはガベージコレクションが注入されたものを確実に除去するのに使用されます。
;(function() {
if (isInputActive()) {
if (window == parent) {
foundTheInput();
} else {
askParent();
}
} else if (isFrameActive()) {
window.addEventListener('message', function onMessage(e) {
if (!e.data || e.data.id != chrome.runtime.id)
return;
switch (e.data.action) {
// request from a child frame
case 'checkme':
if (window == parent) {
confirmChild(e.source);
window.removeEventListener('message', onMessage);
} else {
askParent();
}
break;
// response from a parent
case 'confirmed':
window.removeEventListener('message', onMessage);
if (isInputActive()) {
foundTheInput();
} else if (isFrameActive()) {
confirmChild(e.source);
}
break;
}
});
}
function isInputActive() {
return document.activeElement.matches('input');
}
function isFrameActive() {
return document.activeElement.matches('frame, iframe');
}
function askParent() {
parent.postMessage({id: chrome.runtime.id, action: 'checkme'}, '*');
}
function confirmChild(childWindow) {
console.log('Frame', document.activeElement);
childWindow.postMessage({id: chrome.runtime.id, action: 'confirmed': true}, '*');
}
function foundTheInput() {
console.log('Input', document.activeElement);
document.activeElement.value += ' gotcha!';
}
})();
私はこれをテストしませんでしたが、それ以前に同様のコードを使用していました。
興味深い解決策ですが、isInputActiveのケースでもリスナーが必要です: '' 'B'''が' '' A'''のサブフレームで、input-activeElement B. Bには、提案されたコードのリスナーはありません。 これは、(リスナーをクリーンアップするために)私も拒否メッセージを必要とすることを意味します。 – ttyridal
とAがメインウィンドウです。 非常に複雑ですが、仕事は終わってしまいます - そして私はより良い方法を見つけられませんでした=>受け入れられました – ttyridal