I wrote a chrome extension which solves the issue; unfortunately, it works everywhere... but on stackexchange sites! (and any site which forbids framing). (EDIT: see at the end for version working on all sites)
For simple sites it works fine, showing both title and full url, usually both cropped to unacceptable lenght if you have many tabs and many extensions.
It works:
- upon new tab opening
- upon tab refresh
- upon request by clicking on its icon
manifest.json:
{
"name": "ShowTitle",
"version": "1.0",
"permissions": [
"tabs"
],
"description": "Show page title and url (titlebar replacement)",
"background": {
"persistent": false,
"scripts": [
"background.js"
]
},
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"content.js"
],
"run_at": "document_end",
"all_frames": true
}
],
"browser_action": {
"title": "Test"
},
"manifest_version": 2
}
background.js:
chrome.browserAction.onClicked.addListener(function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {command: "showTitle"}, function(response) {
//console.log(response.result);
});
});
});
chrome.tabs.onCreated.addListener(function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {command: "showTitle"}, function(response) {
//console.log(response.result);
});
});
});
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if ((changeInfo.status == 'complete') && (tab.active)) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {command: "showTitle"}, function(response) {
//console.log(response.result);
});
});
}
})
content.js:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(request.command);
if (request.command == "showTitle") {
console.log("Adding title frame...");
TITLE_HEIGHT = 60;
// Create an iframe which contains title and URL
frTitle = document.createElement("iframe");
frTitle.setAttribute("src","")
frTitle.setAttribute("width",window.innerWidth)
frTitle.setAttribute("height",TITLE_HEIGHT)
html = '<body><center style="background-color:#aaaaaa"><span>Title: ' + document.title + '</span><br><span>URL: ' + document.location + '</span></center></body>';
blob = new Blob([html], {type: 'text/html'});
frTitle.srcdoc = html;
br = document.createElement("br");
// Cretae a frame where to copy original page contents:
frBody = document.createElement("iframe");
frBody.setAttribute("src",window.location)
frBody.setAttribute("width",window.innerWidth)
frBody.setAttribute("height",window.innerHeight-TITLE_HEIGHT)
orgBody = document.body; // Store original page
// Create new body containing the two frames:
newBody = document.createElement("body");
newBody.appendChild(frTitle);
newBody.appendChild(br);
newBody.appendChild(frBody);
// Replace original body by new one:
document.body = newBody;
//sendResponse({result: "success"});
} else {
console.log("Another command.");
}
});
Edit:
to get it working also on sites which do not allow framing, I had to introduce a toggle function to enable/disable the extension at mouseclick, inside background.js :
var enable=false;
chrome.browserAction.onClicked.addListener(function() {
enable = enable ? false : true;
if(enable){
//turn on...
chrome.browserAction.setIcon({ path: 'showtitle_on.png' });
chrome.browserAction.setBadgeText({ text: 'ON' });
chrome.tabs.executeScript(null, { file: 'content.js' });
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {command: "showTitle"}, function(response) {
//console.log(response.result);
console.log("***ATTIVA***");
});
});
}else{
//turn off...
chrome.browserAction.setIcon({ path: 'showtitle_off.png'});
chrome.browserAction.setBadgeText({ text: 'Off' });
console.log("***NON ATTIVA***");
}
});
chrome.tabs.onCreated.addListener(function() {
if(enable){
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {command: "showTitle"}, function(response) {
//console.log(response.result);
});
});
}
});
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if(enable){
if ((changeInfo.status == 'complete') && (tab.active)) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {command: "showTitle"}, function(response) {
//console.log(response.result);
});
});
}
}
})
I also added default ON status in Manifest.json:
"browser_action": {
"default_title": "ShowTitle",
"default_icon": {
"16": "showtitle_on.png"
}
},