I created a Chrome Extension as a solution to override the helpText bubbles in SalesForce Console pages. The helpText bubbles show up the text without the ability to link URLs. It looks like this:
The extension is taking the helpText bubble (which in the SalesForce console window, is inside an iFrame) and makes the URL click-able. It also adds word wrap and marks the links in blue.
The solution works fine when the page loads with the initial iFrame (or iFrames) on it, meaning when you open the SalesForce console the first time (https://eu3.salesforce.com/console).
When a new tab is created at the SalesForce console, my inject script doesn't run.
Can you please assist in understanding how to inject the script on each and every new Tab SalesForce Console is creating?
The Extension as follows:
manifest.js
:
{
"browser_action": {
"default_icon": "icons/icon16.png"
},
"content_scripts": [ {
"all_frames": true,
"js": [ "js/jquery/jquery.js", "src/inject/inject.js" ],
"matches": [ "https://*.salesforce.com/*", "http://*.salesforce.com/*" ]
} ],
"default_locale": "en",
"description": "This extension Fix SalesForce help bubbles",
"icons": {
"128": "icons/icon128.png",
"16": "icons/icon16.png",
"48": "icons/icon48.png"
},
"manifest_version": 2,
"name": "--Fix SalesForce bubble text--",
"permissions": [ "https://*.salesforce.com/*", "http://*.salesforce.com/*" ],
"update_url": "https://clients2.google.com/service/update2/crx",
"version": "5"
}
And this is the inject.js
:
chrome.extension.sendMessage({}, function(response) {
var readyStateCheckInterval = setInterval(function() {
if (document.readyState === "complete") {
clearInterval(readyStateCheckInterval);
var frame = jQuery('#servicedesk iframe.x-border-panel');
frame = frame.contents();
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
var originalText = inputText;
//URLs starting with http://, https://, file:// or ftp://
replacePattern1 = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
replacedText = inputText.replace(replacePattern1, '<a href="$1" style="color: blue;" target="_blank">$1</a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/f])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" style="color: blue;" target="_blank">$2</a>');
//Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');
//If there are hrefs in the original text, let's split
// the text up and only work on the parts that don't have urls yet.
var count = originalText.match(/<a href/g) || [];
if(count.length > 0){
var combinedReplacedText;
//Keep delimiter when splitting
var splitInput = originalText.split(/(<\/a>)/g);
for (i = 0 ; i < splitInput.length ; i++){
if(splitInput[i].match(/<a href/g) == null){
splitInput[i] = splitInput[i].replace(replacePattern1, '<a href="$1" target="_blank">$1</a>').replace(replacePattern2, '$1<a href="http://$2" style="color: blue;" target="_blank">$2</a>').replace(replacePattern3, '<a href="mailto:$1">$1</a>');
}
}
combinedReplacedText = splitInput.join('');
return combinedReplacedText;
} else {
return replacedText;
}
}
var helpOrbReady = setInterval(function() {
var helpOrb = frame.find('.helpOrb');
if (helpOrb) {
clearInterval(helpOrbReady)
} else {
return;
}
helpOrb.on('mouseout', function(event) {
event.stopPropagation();
event.preventDefault();
setTimeout(function() {
var helpText = frame.find('.helpText')
helpText.css('display', 'block');
helpText.css('opacity', '1');
helpText.css('word-wrap', 'break-word');
var text = helpText.html()
text = text.substr(text.indexOf('http'))
text = text.substr(0, text.indexOf(' '))
var newHtml = helpText.html()
helpText.html(linkify(newHtml))
}, 500); });
}, 1000);
}
}, 1000);
});