Dynamic creation of ActiveX on MSIE 11 is broken? - javascript

OS version: Windows 8.1
MSIE (Microsoft Internet Explorer) version: 11.0.9600.16476 (KB2898785)
I have a simple HTML code that is creating my ActiveX Control (AX).
This code always worked in all previous versions of MSIE, but with the new MSIE-11 on Windows 8.1 it stopped working.
I bring here the HTML code that demonstrates the problem.
Please note:
The static HTML code that creates my AX (<OBJECT>) always work,
The dynamic JavaScript code that creates my AX (document.createElement) fails on MSIE 11
<BODY>
<BR>
<BR>
<INPUT TYPE="BUTTON" VALUE="CreateAX" OnClick="CreateAX()" STYLE="WIDTH: 89PX" />
<BR>
<BR>
<!-- This always work: -->
<OBJECT ID = "MyCtrl"
CLASSID = "CLSID:F417FD96-3D17-4556-80AA-F7CEEE1E3FD8"
WIDTH = 100
HEIGHT = 100>
</OBJECT>
<BR>
<BR>
</BODY>
<SCRIPT LANGUAGE="javascript" TYPE="text/javascript">
function CreateAX()
{
// This will not work on MSIE 11
var playbackObjectGlobal = document.createElement('object');
playbackObjectGlobal.setAttribute('id', 'MyCtrl2');
playbackObjectGlobal.setAttribute('classid','CLSID:F417FD96-3D17-4556-80AA-F7CEEE1E3FD8');
playbackObjectGlobal.setAttribute('width', '200');
playbackObjectGlobal.setAttribute('height', '200');
playbackObjectGlobal.setAttribute('hidden', 'false');
document.body.appendChild(playbackObjectGlobal);
}
</SCRIPT>
After debugging I found that my boject does get created but without a window (m_hWnd==NULL) thus all GUI related features and events are disable.
Anyone is familiar with this problem?
Thanks, PazO

After opening a call with Microsoft support I managed to resolve this issue. I will bring here Microsoft answer as is:
With further debugging, we seems to be hitting known behavior and design change in dynamically adding objects.
Earlier, certain actions could force an object to instantiate prior to entering the control tree, which was breaking a number of sites.As part of fixing that, we now fully commit an object when it enters the tree and its identity cannot be changed after that point. Because the repro page doesn't set the CLSID property until after the object enters the tree, the value is ignored.If the step to set the CLSID on the control is moved before the object is inserted into the tree, the control should instantiate correctly.In addition to the above changes, we also removed “Hidden” attribute as it was setting the object in hidden mode.
Before fix:
function CreateAX()
{
var playbackObjectGlobal = document.createElement('object');
playbackObjectGlobal.setAttribute('id', 'MyCtrl2');
playbackObjectGlobal.setAttribute('classid','CLSID:F417FD96-3D17-4556-80AA-F7CEEE1E3FD8');
playbackObjectGlobal.setAttribute('width', '200');
playbackObjectGlobal.setAttribute('height', '200');
playbackObjectGlobal.setAttribute('hidden', 'false');
document.body.appendChild(playbackObjectGlobal);
}
After fix:
function CreateAX_New()
{
var playbackObjectGlobal = document.createElement('object');
// *Change-1* Next two lines swiched places:
playbackObjectGlobal.setAttribute('classid','CLSID:F417FD96-3D17-4556-80AA-F7CEEE1E3FD8');
playbackObjectGlobal.setAttribute('id', 'MyCtrl2');
// *Change-2* Object is appended before sizes are set:
document.body.appendChild(playbackObjectGlobal);
playbackObjectGlobal.setAttribute('width', '200');
playbackObjectGlobal.setAttribute('height', '200');
// *Change-3* The 'Hidden' tag was removed
}
Now all is working for me on Windows 8.1, MSIE-11.

ActiveX is highly restricted on Windows8/IE11 when in Metro mode.
It is locked down to only allowing a very limited set of controls, almost all of which are internal MS controls.
If you need to use any ActiveX controls that aren't in that list, it will only work if you're using Win8 in desktop mode. Even then, you may still need to manually set the browser settings to enable ActiveX.
See this post for more info.

Related

How to debug ScriptError on line 0 on webview?

I have built a mobile webapp in html/js and I am using the 'window.onerror' to track client side js errors and report them to the server.
Recently I noticed that I receive many reports of ScriptError on line 0.
A quick google search brought me to discussions like Cryptic "Script Error." reported in Javascript in Chrome and Firefox and https://ravikiranj.net/posts/2014/code/how-fix-cryptic-script-error-javascript/
For most people such errors seem to be triggered by failures in scripts that are included from a foreign origin. But unfortunately that's not the case for me.
After many hours of debugging I came up with the following minimal example to reproduce the error:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Test</title>
<meta name="google" content="notranslate"/>
<script type="text/javascript">
function init() {
window.onerror = function() {
alert(JSON.stringify(arguments));
}
}
</script>
</head>
<body onload="init()">
<h1>Hello</h1>
<svg width="300" height="300">
<a href="#">
<rect x="50" y="50" width="200" height="200" />
</a>
</svg>
<p>
Link
</p>
</body>
</html>
As we can see it's a simple html page with no javascript at all except for the onerror handler itself.
In Safari (ios 12.4.1) no error is triggered. But in both Google Chrome for iOS and Firefox for iOS a ScriptError on line 0 is reported each time the link inside the <svg> element is tapped - but not when tapping the link outside the <svg>. Note that no js event handler is attached to the <svg>.
A live version of the code is online at https://static.laszlokorte.de/scripterror.php
I know that all third party browsers on iOS actually just use safari under the hood extending in with a few custom features. I suspect that those custom features cause the error but I have no idea how to track it down further.
Why does clicking a link inside a plain svg element causes an error in iOS Chrome and Firefox but not in Safari? Is there a way to connect the Safari Webdev tools to mobile browsers other than native Safari?
Update
After taking a deeper look at both the Chrome(iOS) and Firefox(iOS) source code I now found the cause of the problem. Both browsers inject javascript code that runs on touchstart and processes the event's target node. Both browsers check if an '' or '' element has been touched and try to access their their href or src attribute respectively. They both then try to send the attributes values via webkit.postMessage to the host application.
The error seems to be caused by the fact that an <a> element inside an <svg> is actually an SVGAElement and it's href attribute is not a String but an SVGAnimatedString which (other than String) can not be cloned to be sent to another process.
The corresponding code for Firefox can be found here:
https://github.com/mozilla-mobile/firefox-ios/blob/826cb396a9eb225b7eb667b47b245e2d98d26ed8/Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentEnd/ContextMenu.js#L14-L35
The code for Chrome is here:
https://github.com/chromium/chromium/blob/master/ios/web/web_state/js/resources/all_frames_context_menu.js#L136-L139
So for Chrome the solution is actually simple because it allows to explicitly opt-out of all this by setting the css property -webkit-touch-callout: none (You can see the check for that in the linked file). For example like this:
#namespace svg url(http://www.w3.org/2000/svg);
svg|a {
-webkit-touch-callout: none;
}
For Firefox I have not found a easy solution yet.
Update 2
For Firefox I now came up with the following monkey patch solution:
(function() {
var origClosest = SVGElement.prototype.closest;
SVGElement.prototype.closest = function (sel) {
var c = origClosest.apply(this, arguments);
if(c && sel === 'a' && c.namespaceURI === this.namespaceURI) {
return c.parentNode && c.parentNode.closest(sel);
} else {
return c;
}
};
})();
I override the closest method (that Firefox itself uses to find the touched <a>) on an SVG elements with my own method that skips all <a> elements that belong to the SVG namespace.
Additionally I submitted an issue in the Firefox repo at Github and an issue for Chromium.

Apple iOS browsers randomly won't render HTML objects loaded dynamically

We have a problem that is only evident on iOS browsers (iOS 12.0) with our SPA application that uses HTML object tags to load widgets (HTML/CSS/JS files) through JavaScript onto the page.
The issue is an intermittent one when the page is loaded some of the widgets don't display/render on the screen, yet are loaded into the DOM and can be viewed/highlighted with full element properties in the Safari Web Inspector. but are “invisible” to their user. The problem will occur about 50% of the time if there are 4 widgets to load on a page, 2 typically won't display and it will be different widgets not displaying each time, with no detectable pattern.
The widget javascript load events run properly and there are no errors in the console. In the Safari Web Inspector, we can see some of the HTML elements from the non-rendering object are loaded at position 0,0 but their style is correct in the DOM (left and top set correctly, display: inline, etc.).
Here is the code that loads the widgets (the fragment is added to the DOM after all widgets are setup):
function loadWidget(myFrag, widgetName) {
var widgetObj = document.createElement("object");
widgetObj.data = "widgets/" + widgets[widgetName].type + ".html"; // location of widget
widgetObj.className = "widget unselectable";
widgetObj.id = widgetName;
widgetObj.name = widgetName;
myFrag.appendChild(widgetObj); // build widgets onto fragment
widgetObj.addEventListener("load", widgetLoaded, false); // Run rest of widget initialisation after widget is in DOM
widgetObj.addEventListener("error", badLoad, true);
}
Here is the code in the load event that configures the widget once loaded (we work around a Chrome bug that also affects Safari where the load event is fired twice for every object loaded):
function widgetLoaded(e) {
var loadObj = e.target;
if (loadObj === null) {
// CHROME BUG: Events fire multiple times and error out early if widget file is missing so not loaded (but this still fires), force timeout
return;
}
var widgetName = loadObj.id;
// CHROME BUG: Workaround here is to just set the style to absolute so that the event will fire a second time and exit, then second time around run the entire widgetLoaded
if ((parent.g.isChrome || parent.g.isSafari) && !widgets[widgetName].loaded) {
widgets[widgetName].loaded = true; // CHROME: WidgetLoaded will get run twice due to bug, exit early first time.
loadObj.setAttribute("style", "position:absolute"); // Force a fake style to get it to fire again (without loading all the other stuff) and run through second time around
return;
}
var defView = loadObj.contentDocument.defaultView; // Pointer to functions/objects inside widget DOM
loadObj.setAttribute("style", "position:absolute;overflow:scroll;left:" + myWidget.locX + "px;top:" + myWidget.locY + "px;z-index:" + zIndex);
loadObj.width = myWidget.scaleX * defView.options.settings.iniWidth; // Set the width and height of the widget <object> in dashboard DOM
loadObj.height = myWidget.scaleY * defView.options.settings.iniHeight;
}
The code performs correctly in Chrome (Mac/Windows), IE and Safari (Mac), however, presents the random invisible loading issue in iOS Safari and also in iOS Chrome.
Any ideas what causes this and what the workaround could be?
We couldn't find the exact source of this issue after a lot of investigation and are fairly sure this is a webkit bug. However there is an acceptable workaround, which is to replace the object tag with an iframe tag, and it looks to be working exactly the same way (replace .data with .src) with a bonus it doesn't exhibit the chrome bug where onload events are fired twice, so Chrome runs our app faster now.

How can you change Firefox 25's Network Info Popups?

I noticed a change in Firefox 25 beta, soon to be released: Go to chrome://browser/content/devtools/webconsole.xul, view source, and in the current Firefox (24) you see:
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="devtools-webconsole"
macanimationtype="document"
fullscreenbutton="true"
title="&window.title;"
browserConsoleTitle="&browserConsole.title;"
windowtype="devtools:webconsole"
width="900" height="350"
persist="screenX screenY width height sizemode">
<script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="text/javascript" src="webconsole.js"/>
<commandset id="editMenuCommands"/>
...
In Firefox 25, however, the reference to webconsole.js is replaced with an inline script, function goUpdateConsoleCommands() with two goUpdateCommand calls.
Devtools-tweaks is not working for the network popup now, because the webconsole.js link no longer exists on that window. The code here has nothing to modify to change the popup: https://github.com/programmin1/DevTools-Tweaks/blob/master/content/netWinOverlay.js
Is there any easy way to re-hook this functionality into the network popup? Will JSON/xml parsing be introduced in Firefox soon, making this unnecessary?
The WebConsoleFrame stuff was ported to the add-on SDK loader in bug 877262.
Judging from the code, the following should give access to the WebConsoleFrame the add-on "uses":
var {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
var {WebConsoleFrame} = devtools.require("devtools/webconsole/webconsole");
As for the second part of your question: Will the devtools support the same stuff natively?
I'm not sure. You should get in touch with the devtools team and ask them and have a look at the existing bugs: Open devtools bugs containing "json". And/or file a new enhancement bug.

My html/javascript/css site works in IE but not in FF

www.warhawkcomputers.com/Birenbaum
This site has various projects for my Computer class that I am in. A check is coming up and all programs will need to work in FF and IE.
My Bouncing Ball, Race Track, and Tanks projects under Third quarter as well as pong under Fourth Quarter work in IE when the objects need to be moved by a continuously adding variable performed in a javascript script, and it works perfectly fine in IE, but when viewed with Firefox 3, the moving objects no longer move and I have tested to find out it gets the variables but seems to only add it once and that the document.getElementById("objectname").style.left = "continuously adding variable" seems to not be executed despite being in a timer running every 10 milliseconds.
Also, none of my keypress code works in Firefox, but I believe that is because I use an outdated method of moving objects via keypress. This is largely due to my teacher's outdated methods.
Thanks for all of your guys's help.
You need to add a 'units' to your positions:
document.getElementById("ball").style.left = x + 'px';
document.getElementById("ball").style.top = y + 'px';
That will work in FF as well now.
Firefox does not use a global event object. They pass an event object into the handler. As a result, you need to modify your Move function:
function Move(e) {
/* snip */
var whichkey = window.event ? window.event.keyCode : e.keyCode;
/* ... */
Gerrat is absolutely correct about the other problem you asked about.
EDIT: this won't work with how you hooked your event handler in the body tag. You need to remove the onkeydown="Move()" attribute from the body tag and add the following code at the top of JavaScript.js:
document.body.onkeydown=Move;
If allowed to do so by your teacher, you would be MUCH better off using jQuery or some other framework.

Accessing frames via the DOM in IE

OK, every other browser works fine with the method I have coded so far but for some reason Internet Explorer will not work. I have spent hours of time (more time than actually developing the feature!) on compatibility and am close to giving up!
I have a forum and one of its neat features is the WYSIWYG editor. For that, I essentially have an IFrame that acts as the document:
<iframe name="writer" src="/scripts/blank.html" class="writer"></iframe>
This is the current state of the JavaScript (constantly updated):
function initEditor()
{
w = frames['writer']
wc = g('writerCopy')
if(w == null) return
frames['writer'].document.designMode = 'on'
frames['writer'].document.body.innerHTML = styleSheet+wc.value
frames['writer'].focus()
}
It works partially now, but fails on the line:
frames['writer'].document.body.innerHTML = styleSheet+wc.value
in Internet Explorer with "'frames.writer.document.body' is null or not an object".
I'm not even sure IE supports that designMode.
And, .contentDocument is only IE8, IE7 and less uses .contentWindow.document, but iframe windows are part of the frames-collection.
try this, should be crossbrowser:
<iframe name="writer"></iframe>
frames["writer"].document.body.innerHTML = "some html...";
You need to point your iframe to a dummy document for IE. Just create a file blank.html with the following:
<html><body></body></html>
and set <iframe src="blank.html" ... >
Then you can go about referencing frame.document.body.innerHTML = '...' to your hearts content.
BTW that is a terrible title to a question.
Evidently IE8 does not make frame elements available until the entire parent page has loaded. Also note, you can write to the frame before the parent page loads, but this will overwrite the frame and prevent it from being loaded.
The easy solution is to move the InitEditor() call from inside the body to here:
<body onload="InitEditor()">
Perhaps the iframe isn't loaded yet. I can duplicate your "'frames.writer.document.body' is null or not an object" error. I added a setTimeout around it and it then worked for me.
setTimeout(function () {
frames['writer'].document.body.innerHTML = "some text";
}, 200);
Have you activated IE's debugging facilities?
Am I missing something here? shouldn't you use something like:
window.frames[nameOrNumberOfFrame]...
See also in MSDN:
This collection contains only window
objects and does not provide access to
the corresponding frame and iframe
objects. To access these objects, use
the all collection for the document
containing the objects.
In the end I used frames['frameName'].document.write('someText') but only if the other method fails.

Categories

Resources