How to trace what happens to a DOM Element? - javascript

I'm using the masked input plugin for a web app at work. I'm applying masks using a class selector in $(document).ready():
$(".Primary_Phone_Number").mask("(999) 999-9999");
$(".ZipCodeMask").mask("99999");
$(".StateMask").mask("aa");
$(".date").mask("99/99/9999");
However, everything except the Phone number is losing it's mask. After document ready, if I run these again in the console, they get and retain their mask.
It's a large web app, each page has 1000s of lines of javascript and there are a lot of diverse selectors flying around making changes as well as a lot of ajax calls. We're only testing the web app in IE since it's an internal project. Is there anything available in IE10 to let me know when a particular DOM Element is getting manipulated?

If you use Chrome (and you can use it for debugging, if the problem reproduces), you can put a breakpoint on DOM modification.
Inspect the element, right click on it, choose "Break on..." and choose the event type (e.g. subtree modification). More info on this.
If you still want to do it in IE (9+), you can use Mutation Events and break the JS execution when the element is modified.
E.g.
el.addEventListener("DOMSubtreeModified", function(ev) {
debugger;
}. false);

Related

What does paragraph about figuring out XUL elements mean in MDN document: "How to convert an overlay extension to restartless"

Recently a friend of mine and I have been working on a Firefox extension. He handed the code to me today, and I've been trying to make it restartless. I used the tutorial from How to convert an overlay extension to restartless (on MDN). Since I don't have much experience working with JavaScript and extensions in general, I was wondering if anyone could help to understand what step number 6 means here in this tutorial. They are saying we can't use "no more XUL overlays", and I understand this. What I don't understand is that how to this part:
Figure out what XUL elements you need to create for your add-on to add your interface, where it needs to go into a XUL window, and how to do it. Docs: document.getElementByID(), document.createElement(), Element reference, Node reference (DOM elements are also nodes).
I decided against using document.loadOverlay, since it's very buggy. I'm not sure if this helps much, but here is the code for our overlay.xul. Again, sorry if the question is really basic, any help is much appreciated. If I need to provide more code please let me know. At this point I thought only the code for our overlay.xul file is important.
<?xml version="1.0" encoding="UTF-8"?>
<overlay id="my-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript;version=1.7" src="overlay.js"/>
</overlay>
XUL overlays can be used for a wide variety of things in Firefox. Step 6: No more XUL overlays focuses more on UI elements than other possible uses of overlays (e.g. loading scripts, as you are doing).
In an XUL overlay extension, the UI elements are generally added by providing an XUL overlay file for each portion of the interface which is modified. The XUL overlay extension does not need to consider removal of the interface elements, as they are only removed when the extension is removed or disabled.
In a restartless extension, all UI elements are added programmatically each time the extension is started. Some UI elements are added once; and some must be added both to each open window and when each new window is opened. When the extension is disabled, or removed, the UI elements must be programmatically removed completely from Firefox.
The portion you quoted is attempting to describe the process of converting an actual XUL overlay (used to modify the Firefox UI) to programmatically inserting (and removing) the UI elements. The most common UI element is probably a toolbar button, but it could be anything. Because it could be anything, the description is relatively vague.
That entire section, Step 6: No more XUL overlays, could definitely use some expansion. I remember planning to do so based on the code I used when converting an extension from XUL to overlay. I had wanted to clean the code up a bit, and account for more cases. However, having an example in there would be helpful. I'll see if I can update it in the next week or so (if someone else does not beat me to it).
In your case:
Based on the overlay code which you included in your question, this section is not talking as directly about how you are using your XUL overlay as might be desired. The part you quoted:
Figure out what XUL elements you need to create for your add-on to add your interface, where it needs to go into a XUL window, and how to do it. Docs: [document.getElementByID()][3], [document.createElement()][4], [Element reference][5], [Node reference][6] (DOM elements are also nodes).
is specifically talking about adding UI elements to Firefox, which is not what you are doing with your overlay.
What you are going to need to do is determine how you are going to apply your script, overlay.js, to whatever it is that you are adding it to. Remember, you also need to be able to remove it when your extension is disabled/removed/updated.
In order to provide more detailed information, we are going to need to know what it is that you are adding your script to. For this, we probably need you to include a copy of your chrome.manifest file. It might be helpful to know what your script does as the functionality may be more appropriately handled without applying the script in the way implied by an overlay. However, you should ask this as a new, separate question, not modify this question to ask something different.

Auto-refresh HTML tab in internet explorer

I made a nice website that does a lot of DOM manipulation. Works very nicely in chrome and firefox. Though the client has requested now that it also works in Internet Explorer. The latest version is good enough to start with (that would be 10.0.9200.16721 in my case).
So the adventure starts, i press F12 and see a set of pretty familiar developer tools (coming from chrome and firebug). As i'm tracking the JS code i notice that the HTML tab (with the DOM) doesn't actually update.
According to the manual here http://msdn.microsoft.com/en-us/library/ie/gg589512(v=vs.85).aspx it's "a good idea to refresh the HTML tab to get the current DOM, especially when you use dynamic elements." (d0h ??) problem is .. i can't find a button to enable automatic update of the HTML tab. So i would have to click the refresh button everytime i step into a new line of JS (never mind of real-time DOM view).
But that's not all ... every time i click the refresh button the whole DOM tree view collapses. And i have to click a bunch of pluses to view the node i'm interested in.
Does anyone have a solution for this? Because what would take days will take weeks this way...
Duplicate of How to inspect elements on dynamically created DOM by using IE developers tools
From doing a little digging aroung, it seems like this is an issue other people have reported too. This thread might be of some interest to you.
The most relevant part of it:
The problem is when you modify the dom (with or without jquery) from a callback which is called by a timeout, which is in a callback bound to an event, IE freaks out and doesn't update the dom tree in the development tool. Subsequent modifications to the changed tag in the dev tool won't have any effect.
According to my tests, it's the combination of that sequence of calls that make this happen. If the dom is modified from a settimeout callback but without being inside of an event callback, it works. If instead of settimeout you directly call a function that modifies the dom, it works.
Here's a working example of what you're saying to compound the issue.
Basically, this is an issue with IE. There is no fix available at the moment. The accepted answer on the other thread seems like a very poor workaround.

Prevent inline JS execution

I have a situation where I am loading external HTML into a WYSIWYG editor on a web page. The external HTML is from a trusted source, and includes what ever is between two specific <div> tags from a number of different pages.
My problem is that some of the pages contain inline javascript event handlers. So when I am working in the WYSIWYG editor, certain events cause the execution of this js.
Mostly it doesn't do anything other than fill up the console with errors saying ... is not defined, and this may be all it is, and that wouldn't be a problem. But still, it's messy, and I don't know if there isn't a page somewhere that might execute something like alert(...) which could get extremely annoying. The code is all trusted, but detached from its intended context, it could produced undesirable results.
I want to find a way to globally prevent this execution, preferably without modifying the inline script. I could do something like attach =false; to each handler, but then I have to check all the incoming elements, and even with regular expressions, this will degrade performance. Also, I then would have to remove it before submitting the edited HTML back to the server, which seems like a major pain, and difficult to do flawlessly.
Is there a way to prevent this online code from being executed within this particular context?
Depending on what browser you are trying to support, you can checkout 'Content Security Policy' headers. Checkout http://caniuse.com/contentsecuritypolicy for details on browser support.
If you target browser is in the list, CSP can do exactly what you are looking for. It will disable event handlers by default. It will block execution of any code embedded within on the page in addition to blocking event handlers. So you will need to move all your js code, if present on the html page to a separate js, specify that filename in the safe-list and load your js from there.
CSP are set as Http headers but with the new specification it can be set using meta tags as well. Checkout https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#html-meta-element--experimental.
For WebKit supported browsers(Chrome/Safari) something like
would restrict load from any external source. You can add a list of accepted sources to the list and explore what works for you.
For firefox, though its there in the specification, I do not think the meta tag is supported yet.
https://developer.mozilla.org/en-US/docs/Security/CSP/Introducing_Content_Security_Policy.
So to summarize, as long as you can set headers for the Web-Server that is hosting the web page (unless you only want Chrome/Safari support), and your target browser supports CSP, you might give it a shot.
I copied this from sitepoint forum, a question similar to yours. This takes an approach of pulling div out of the parent and putting it back on. If this is what you want here is the example code:
var div = document.getElementById('div');
var nextSibling = div.nextSibling;
var parent = div.parentNode;
parent.removeChild(div);
function reCreateElement() {
if (nextSibling) {
parent.insertBefore(div, nextSibling);
} else {
parent.appendChild(div);
}
}
setTimeout(reCreateElement, 100);
// Below is the stuff we don't want to run!
document.getElementById('div').onclick = function() {
alert('CLICKED!');
}

Debugging features on Safari to find out when elements added to page

Is there a tool available on Safari to find out when new elements are being added to the page. I have a page where there are invisible elements added at that cause the page to scroll. The elements that I thought where the cause, don't seem to be. I'd like to know if there is a way to find out.
Safari's built-in debugging tools are limited to what Chrome and Firefox offers and as far as I know you cannot set a break point to detect when a node has been inserted.
If you really insist on using Safari to debug, you could use event listeners like below:
document.addEventListener('DOMNodeInserted', function (event) {
console.log('This element was added to the page:', event.target);
});
Using the Web Inspector (or Chrome Developer Tools), right click on the BODY element (or a more specific one, where the elements actually get added) and in the context menu, choose "Break on subtree modifications". Your JS code will break whenever the selected element's subtree gets modified (elements added/removed).
I think you could use "mutation observers".

Question - Setting dynamic HTML using Javascript to iFrames on Windows Mobile 6.1 - IE Mobile6

(excuse me if this is not the right forum to post - i couldn't find anything related to non-native programming and related to this topic)
I Am trying to set a dynamic HTML into an iFrame on the webpage. I have tried a couple of things but none of them seem to work. I m able to read the innerHTML but can't seem to update it.
// Able to read using
document.getElementById('iFrameIdentifier').innerHTML;
// On Desktop IE, this code works
document.getElementById('iFrameId').contentWindow.document.open();
document.getElementById('iFrameId').contentWindow.document.write(dynamicHTML);
document.getElementById('iFrameId').contentWindow.document.close();
Ideally the same function should work as how it works for div's but it says 'Object doesn't support this method or property".
I have also tried document.getElementById('iFrameId').document.body.innerHTML.
This apparently replaces the whole HTML of the page and not just the innerHTML.
I have tried out a couple of things and they didn't work
document.getElementById('iFrameId').body.innerHTML
document.frames[0].document.body.innerHTML
My purpose is to have a container element which can contain dynamic HTML that's set to it.
I've been using it well till now when I observed that the setting innerHTML on a div is taking increasing amount of time because of the onClicks or other JS methods that are attached to the anchors and images in the dynamic HTML. Appears the JS methods or the HTML is some how not getting cleaned up properly (memory leak?)
Also being discussed - http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_26185526.html#a32779090
I have tried a couple of things but none of them seem to work.
Welcome to IEMobile! Nothing you know about DOM scripting applies here.
Unfortunately, cross-iframe scripting does not appear to be possible in IEMobile6-7.
frameelement.contentDocument (the standard DOM method) isn't available
frameelement.contentWindow.document (the IE6-7 workaround version) isn't available
the old-school Netscape window.frames array only works for frames, not iframes
having the child document pass up its document object to the window.parent only works for frames, not iframes. In an iframe, window.parent===window.
So the only ways forward I can see are:
use frames instead of iframes. Nasty. Or,
use document.cookie to communicate between parent and child: the child document is just a script, that checks for a particular cookie in document.cookie on a poller, and when it's found that's a message from the parent, and it can write some HTML or whatever. Slow and nasty. Or,
using the server-side to inject content into the frames, passing it in as an argument to a script. Slow, nasty, and potentially insecure. Or,
avoid frames completely (best, if you can). Or,
drop support from IEMobile6-7 (best for preserving your sanity, if you can get away with it!)
Appears the JS methods or the HTML is some how not getting cleaned up properly (memory leak?)
Yes, probably. IEMobile6-7(*) is close to unusable at dynamic HTML. It gives you a lovely flavour of what scripting used to be like for us poor gits back in the Netscape 4 days.
Try to avoid creating and destroying lots of nodes and event handlers. Keep the page as static as possible, re-using element nodes where possible and setting text node data properties in preference to tearing everything down and making anew with createElement or innerHTML. Use an event stub (onclick="return this._onclick()") in the HTML together with writing to _onclick if you need to set event handlers from JavaScript, in preference to recreating the HTML with a new event handler (or just trying to set the property, which of course doesn't work in IEMobile). Avoid long-running single pages when you can.
It'll still crash, but hopefully it'll take longer.
*: that is, the versions of IE present on WinMo before version 6.1.4, where it became the infinitely better IEMobile8, marketed as “Internet Explorer Mobile 6” (thank you Microsoft).
Okay, I kinda resolved the issues that i was facing earlier and the bigger issue which was setting HTML to an iFrame on IEMobile. But i still have one more PIA which is related to double scollbars - which i am currently looking into. There seems to be more poor souls facing similar problem - if i fix that too. I will post an update here.
How did i finally write to iFrame on IEMobile?
Have 2 divs one to wrap the iFrame and the other to write inside an iFrame.
document.getElementById('OuterDiv').innerHTML = '';
document.getElementById('OuterDiv').innerHTML = '<iframe id="iFrameId" src="somefile.html"></iframe>';
This creates an iFrame each time and in the somefile.html on load there is a InnerDiv.innerHTML which doesn't seem to leak the memory.
In the somefile.html there will be an onLoad method which will fetch the HTML (explained below on how i managed to get it) and do a
document.getElementById('InnerDiv').innerHTML = dynamicHTML;
How did I manage to pass the HTML between parent and child iFrame
As well explained by #bobince earlier, one has to rely on 3rd party service like a cookie or a server to pass around the data between parent and the child iFrame.
I infact used an ActiveXControl to set and get data from the parent and child iFrame's javascript respectively. I won't recommend doing this if you have to introduce an ActiveX Control just for this. I accidentally already have one which I use to get the Dynamic HTML in the first place.
If you need any help you can DM me - Twitter #Swaroop
Thanks #bobince for your help. I am marking this one as an answer because it says what i did to fix the issue.

Categories