Possible approach:
One approach could be building an extension that injects a content script in every page. This content script would parse the DOM and remove all and set all target
attributes off the anchor elementstarget
attributes of anchor elements to _self
.
Caveats:
- There are dynamically inserted elements (including anchor elements) on many pages.
- There are dynamically changing elements (including anchor elements) on some pages.
- Not all pages/tabs are opened through links (e.g. some page could use
window.open()
).
Solution:
You could use a MutationObserver that watches for anchor elements being inserted or having their target
attribute modified and make the appropriate adjustments.
You still need to take care of tabs opened by other means (e.g. window.open()
) if it is extremely important to you (but those cases should be very very few, so it might not be worth the trouble).
Sample code:
manifest.json:
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"content_scripts": [{
"matches": ["*://*/*"],
"js": ["content.js"],
"run_at": "document_start",
"all_frames": true
}]
}
content.js:
/* Define helper functions */
var processAnchor = function(a) {
//if (a.hasAttribute('target')) {
// a.removeAttribute('target');
//}
a.setAttribute('target', '_self');
};
/* Define the observer for watching over inserted elements */
var insertedObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(m) {
var inserted = [].slice.call(m.addedNodes);
while (inserted.length > 0) {
var elem = inserted.shift();
[].slice.call(elem.children || []).forEach(function(el) {
inserted.push(el);
});
if (elem.nodeName === 'A') {
processAnchor(elem);
}
}
});
});
/* Define the observer for watching over
* modified attributes of anchor elements */
var modifiedObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(m) {
if ((m.type === 'attributes') && (m.target.nodeName === 'A')) {
processAnchor(m.target);
}
});
});
/* Start observing */
insertedObserver.observe(document.documentElement, {
childList: true,
subtree: true
});
modifiedObserver.observe(document.documentElement, {
attributes: true,
substree: true
});