I am attempting to make ie7-js work with my wordpress installation. After reading about this library it seems like it is a great solution to making my website more compatible with older versions of IE more specifically IE8. It may seem odd to try and still support an old browser like that but I have noticed that several hundred visitors a month are visiting our site using browsers as old as IE6. A majority of our users are elderly and still using Windows XP. Now on to the problem.
I am running a copy of the Windows XP virtual machine with IE8 from modern.ie I have followed the instructions on the library code page on how to include the file. I am trying to get the Specific IE9.js file to work. When I access the page in IE8 I get the error
permission denied: line 850 character 37
I have tracked it down to the line below:
for (var i = 0, imported; i < styleSheet.imports.length; i++)
from this function:
function getCSSText(styleSheet, path, media, level) {
var cssText = "";
if (!level) {
media = toSimpleMedia(styleSheet.media);
level = 0;
}
if (media === "none") {
styleSheet.disabled = true;
return "";
}
if (media === "all" || media === self.media) {
// IE only allows importing style sheets three levels deep.
// it will crash if you try to access a level below this
try {
var canAcess = !!styleSheet.cssText;
} catch (exe) {}
if (level < 3 && canAcess) {
var hrefs = styleSheet.cssText.match(IMPORTS);
// loop through imported style sheets
for (var i = 0, imported; i < styleSheet.imports.length; i++) {
var imported = styleSheet.imports[i];
var href = styleSheet._href || styleSheet.href;
imported._href = hrefs[i].replace(TRIM_IMPORTS, "");
// call this function recursively to get all imported style sheets
cssText += getCSSText(imported, getPath(href, path), media, level + 1);
}
}
// retrieve inline style or load an external style sheet
cssText += encode(styleSheet.href ? loadStyleSheet(styleSheet, path) : styleSheet.owningElement._cssText);
cssText = parseMedia(cssText, self.media);
}
return cssText;
};
Upon researching to see if anyone else has had the same issue I did find posts regarding it but none had solutions to them. I have been trying to sort this out for a few hours now only to be banging my head against the desk. Does anyone have possible solutions or things to check next? I have tried changing file permissions to 777 but that does not seem to work either.
Older browsers have limitations when working with CORS on client-side.
Not quite a "bug" from his javascript and can not be corrected by the client-side.
The best way is to work with CDNs that have permissions to CORS.
http://schock.net/articles/2013/07/03/hosting-web-fonts-on-a-cdn-youre-going-to-need-some-cors/
http://support.maxcdn.com/howto/use-cdn-with-webfonts/
Yet still can be difficult, so another alternative would be to put all the CSS on a sub domain your (or your own domain).
Read about CORS:
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
http://enable-cors.org/
I would like to call js function via ExternalInterface from as3 code LOCALLY, not on remote server.
All browsers work great but not Chrome.
Note that in flash-debug player version (C:\Windows\system32\Macromed\Flash\NPSWF32_11_9_900_170.dll, version 11,9,900,170) I have installed in Chrome it works.
But in default flash player version (C:\Program Files\Google\Chrome\Application\33.0.1750.117\PepperFlash\pepflashplayer.dll, version 12.0.0.70) it doesn't work.
PS: I've also tried to open my old project (with ExternalInterface) I've developed 2 years ago -> same issue.
IDE I have used -> FlashBuilder4.6 and also tried in FlashDevelop.
I am using AC_OETags.js in order to include swf into web-page.
ExternalInterface.call("someFunc","testMsg") calls when swf initializes.
Chrome version is 33.0.1750.117 m
Thanks in advance.
This is a bug in Chrome using the pepper plugin: https://code.google.com/p/chromium/issues/detail?id=137734
What's happening is that the trusted locations (set here: https://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html) aren't taken into account, so any Flash <-> JS interaction is broken.
It doesn't look like this bug is getting fixed (judging by the comments on the issue today, there's a good chance it'll get marked as a "Won't fix"), so for now there's 3 ways around it:
Use another browser - not ideal
Use the NPAPI plugin - the pepper plugin is the default, but it's mostly a set-once-and-forget sort of task
Run a local webserver - either something like apache (http://www.easyphp.org/) or node (http://nodejs.org/). This is Google's preferred method of dealing with this, as it more closely mimics network behaviour (including security stuff)
This code helps you to check if PepperPlayer is installed:
checkPepperPlayer=function(){
var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
if (is_chrome) {
var pluginsList = navigator.plugins;
for (var plugin in pluginsList) {
if (plugin && pluginsList[plugin] && pluginsList[plugin].filename) {
var filename = pluginsList[plugin].filename;
if (filename == "pepflashplayer.dll" || filename == "PepperFlashPlayer.plugin" || filename == "libpepflashplayer.so") {
return true;
}
}
}
}
return false;
};
I need to detect if the Adblock extension is installed on the user's browser.
I have seen similar question on SO, but most of them suggest to check if the DOM has been modified.
I would rather want to check if the extension is installed (maybe with Javascript ?) on the browser rather than check the DOM. How do i do this ?
Try the global navigator.plugins variable. With a loop it should work. (JS)
Nice blog to the topic: http://webdevwonders.com/detecting-browser-plugins/
EDIT: For chrome you can try this if you now the APP GUID.
try {
var appGUID = "nnbmlagghjjcbdhgmkedmbmedengocbn";
a = new Image();
a.src = "chrome-extension://"+appGUID+"/icon16.gif";
if(a.width != 0) {
//App installed!
}
} catch(e) {
//App not installed
}
I'm using the Firefox Addon SDK to build something that monitors and displays the HTTP traffic in the browser. Similar to HTTPFox or Live HTTP Headers. I am interested in identifying which tab in the browser (if any) generated the request
Using the observer-service I am monitoring for "http-on-examine-response" events. I have code like the following to identify the nsIDomWindow that generated the request:
const observer = require("observer-service"),
{Ci} = require("chrome");
function getTabFromChannel(channel) {
try {
var noteCB= channel.notificationCallbacks ? channel.notificationCallbacks : channel.loadGroup.notificationCallbacks;
if (!noteCB) { return null; }
var domWin = noteCB.getInterface(Ci.nsIDOMWindow);
return domWin.top;
} catch (e) {
dump(e + "\n");
return null;
}
}
function logHTTPTraffic(sub, data) {
sub.QueryInterface(Ci.nsIHttpChannel);
var ab = getTabFromChannel(sub);
console.log(tab);
}
observer.add("http-on-examine-response", logHTTPTraffic);
Mostly cribbed from the documentation for how to identify the browser that generated the request. Some is also taken from the Google PageSpeed Firefox addon.
Is there a recommended or preferred way to go from the nsIDOMWindow object domWin to a tab element in the SDK tabs module?
I've considered something hacky like scanning the tabs list for one with a URL that matches the URL for domWin, but then I have to worry about multiple tabs having the same URL.
You have to keep using the internal packages. From what I can tell, getTabForWindow() function in api-utils/lib/tabs/tab.js package does exactly what you want. Untested code:
var tabsLib = require("sdk/tabs/tab.js");
return tabsLib.getTabForWindow(domWin.top);
The API has changed since this was originally asked/answered...
It should now (as of 1.15) be:
return require("sdk/tabs/utils").getTabForWindow(domWin.top);
As of Addon SDK version 1.13 change:
var tabsLib = require("tabs/tab.js");
to
var tabsLib = require("sdk/tabs/helpers.js");
If anyone still cares about this:
Although the Addon SDK is being deprecated in support of the newer WebExtensions API, I want to point out that
var a_tab = require("sdk/tabs/utils").getTabForContentWindow(window)
returns a different 'tab' object than the one you would typically get by using
worker.tab in a PageMod.
For example, a_tab will not have the 'id' attribute, but would have linkedPanel property that's similar to the 'id' attribute.
We are using software that registers its own protocol. We can run application from browser then by link like:
customprotocol://do_this.
but is there a way to check is such custom protocol supported by user`s system? If not we would like to ask user to install software first.
E.g:
if (canHandle ('customprotocol')) {
// run software
}
else {
// ask to install
}
Edit
I know about protocolLong property but it works only in IE.
Unfortunately, there's no easy way of achieving this. There's certainly no method of pre-determining whether or not the protocol handler is installed.
Internet Explorer, as you mentioned, has the protocolLong property but I'm having trouble getting it to return anything other than "Unknown Protocol" for all custom protocol handlers -- if anyone knows how to get IE to return the correct value please let me know so I can update this section. The best solution I've found with IE is to append to the user agent string or install a browser extension along with your app that exposes a Javascript accessible property.
Firefox is by far the easiest of the major browsers, as it will allow you to try and catch a navigation attempt that fails. The error object returned contains a name property whose value is NS_ERROR_UNKNOWN_PROTOCOL:
try {
iframe.contentWindow.location.href = "randomprotocolstring://test/";
} catch(e) {
if (e.name == "NS_ERROR_UNKNOWN_PROTOCOL")
window.location = "/download/";
}
Firefox will pop up with its own alert box:
Firefox doesn't know how to open this address, because the protocol (randomprotocolstring) isn't associated with any program.
Once you close this box, the catch block will execute and you have a working fallback.
Second is Opera, which allows you to employ the laws of predictability to detect success of a custom protocol link clicked. If a custom protocol click works, the page will remain the same location. If there is no handler installed, Opera will navigate to an error page. This makes it rather easy to detect with an iframe:
iframe.contentWindow.location = "randomprotocolstring://test/";
window.setTimeout(function () {
try {
alert(ifr.contentWindow.location);
} catch (e) { window.location = "/download/"; }
}, 0);
The setTimeout here is to make sure we check the location after navigation. It's important to note that if you try and access the page, Opera throws a ReferenceException (cross-domain security error). That doesn't matter, because all we need to know is that the location changed from about:blank, so a try...catch works just fine.
Chrome officially sucks with this regard. If a custom protocol handler fails, it does absolutely zip. If the handler works... you guessed it... it does absolutely zip. No way of differentiating between the two, I'm afraid.
I haven't tested Safari but I fear it would be the same as Chrome.
You're welcome to try the test code I wrote whilst investigating this (I had a vested interest in it myself). It's Opera and Firefox cross compatible but currently does nothing in IE and Chrome.
Here's an off-the-wall answer: Install an unusual font at the time you register your custom protocol. Then use javascript to check whether that font exists, using something like this.
Sure it's a hack, but unlike the other answers it would work across browsers and operating systems.
Just to chime in with our own experience, we used FireBreath to create a simple cross-platform plugin. Once installed this plugin registers a mime type which can be detected from the browser javascript after a page refresh. Detection of the mime type indicates that the protocol handler is installed.
if(IE) { //This bastard always needs special treatment
try {
var flash = new ActiveXObject("Plugin.Name");
} catch (e) {
//not installed
}
else { //firefox,chrome,opera
navigator.plugins.refresh(true);
var mimeTypes = navigator.mimeTypes;
var mime = navigator.mimeTypes['application/x-plugin-name'];
if(mime) {
//installed
} else {
//not installed
}
}
Internet Explorer 10 on Windows 8 introduced the very useful navigator.msLaunchUri method for launching a custom protocol URL and detecting the success or failure. For example:
if (typeof (navigator.msLaunchUri) == typeof (Function)) {
navigator.msLaunchUri(witchUrl,
function () { /* Success */ },
function () { /* Failure */ showError(); });
return;
}
Windows 7 / IE 9 and below support conditional comments as suggested by #mark-kahn.
For Internet Explorer, the best solution I've found is to use Conditionl comments & Version Vector (application must write something to registry while installing protocol, see http://msdn.microsoft.com/en-us/library/ms537512.aspx#Version_Vectors). protocolLong doesn't work for custom protocol.
On mobile you can use an embedded iframe to auto switch between the custom protocol and a known one (web or app store), see https://gist.github.com/2662899
I just want to explain more previous Mark's answer (some people did not understand for example user7892745).
1) When you launch you web-page or web-application it checks for an unusual font (something like Chinese Konfuciuz font http://www.fontspace.com/apostrophic-lab/konfuciuz).
Below is the code of sample web-page with function which checks the font (called isFontAvailable):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
/**
* Checks if a font is available to be used on a web page.
*
* #param {String} fontName The name of the font to check
* #return {Boolean}
* #license MIT
* #copyright Sam Clarke 2013
* #author Sam Clarke <sam#samclarke.com>
*/
(function (document) {
var width;
var body = document.body;
var container = document.createElement('span');
container.innerHTML = Array(100).join('wi');
container.style.cssText = [
'position:absolute',
'width:auto',
'font-size:128px',
'left:-99999px'
].join(' !important;');
var getWidth = function (fontFamily) {
container.style.fontFamily = fontFamily;
body.appendChild(container);
width = container.clientWidth;
body.removeChild(container);
return width;
};
// Pre compute the widths of monospace, serif & sans-serif
// to improve performance.
var monoWidth = getWidth('monospace');
var serifWidth = getWidth('serif');
var sansWidth = getWidth('sans-serif');
window.isFontAvailable = function (font) {
return monoWidth !== getWidth(font + ',monospace') ||
sansWidth !== getWidth(font + ',sans-serif') ||
serifWidth !== getWidth(font + ',serif');
};
})(document);
function isProtocolAvailable()
{
if (isFontAvailable('Konfuciuz'))
{
return true;
}
else
{
return false;
}
}
function checkProtocolAvail()
{
if (isProtocolAvailable())
{
alert('Custom protocol is available!');
}
else
{
alert('Please run executable to install protocol!');
}
}
</script>
<h3>Check if custom protocol was installed or not</h3>
<pre>
<input type="button" value="Check if custom protocol was installed!" onclick="checkProtocolAvail()">
</body>
</html>
2) First time when user opens this page, font will not be installed so he will get a message saying "Please run executable to install custom protocol...".
3) He will run executable which will install the font. Your exe can just copy the font file (in my case it is KONFUC__.ttf) into C:\Windows directory or using a code like this (example on Delphi):
// Adding the font ..
AddFontResource(PChar('XXXFont.TTF'));
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
4) After that, when user runs web app again, he gets "Custom protocol is available!" message because font was installed this time.
Tested on Google Chrome, Internet Explorer and Firefox - working great!
For Firefox, most of articles I googled, including Andy E 's answer here, and this gist Cross-browser implementation of navigator.msLaunchUri or https://github.com/ismailhabib/custom-protocol-detection using
iframe.contentWindow.location.href = uri
But it has stopped working since Firefox 64, e.g here https://github.com/ismailhabib/custom-protocol-detection/issues/37 also confirmed that.
So FF 64+ I found I can either using Chrome's method, blurHandler or using the post there https://github.com/ismailhabib/custom-protocol-detection/issues/37#issuecomment-617962659
try {
iframe.contentWindow.location.href = uri;
setTimeout(function () {
try {
if (iframe.contentWindow.location.protocol === "about:") {
successCb();
} else {
failCb();
}
} catch (e) {
if (e.name === "NS_ERROR_UNKNOWN_PROTOCOL" ||
e.name === "NS_ERROR_FAILURE" || e.name === "SecurityError") {
failCb();
}
}
}, 500);
} catch (e) {
if (e.name === "NS_ERROR_UNKNOWN_PROTOCOL" || e.name === "NS_ERROR_FAILURE"
|| e.name === "SecurityError") {
failCb();
}
}
For Chrome 86+ it also fails to work, check my answer for details Detect Custom Protocol handler in chrome 86
BTW, I find most of answers/articles are outdated in some cases.