Is it possible to pause on svg errors in Chrome/Opera - javascript

Similar to how 'Pause on exceptions' works, is it possible to pause whenever you create a svg element and sets invalid attributes on it?
This example (test on jsfiddle):
circle.setAttribute('fill', 'steelblue');
circle.setAttribute('r', 'big'); // A 'big' circle is obviously wrong
will generate the following error in chrome, but there is no mapping back to the javascript call that generated the svg so it can be hard to find the error:

This is not possible because of how svg is rendered in the browser. Imagine that svg is a like XML, or (HTML) for that matter. Its not executed in a step process like lines of code. Its read into a rendering engine that quickly renders the object and its attributes. The pause would have to happen during this rendering, inside of the engine, and this would cause all sorts of rendering issues.
In reference to your example, javascript doesn't do any sort of type checking on what you pass into the setAttribute value, (I mean it really couldn't as different attributes require different types), but rather adds that key value pair to the element object. (try logging the circle object, before and after and you'll see what I mean). Later when you add your circle to the DOM, it simply takes the object and parses it like I stated above.
Basically this type of error handling will never exist in the browser because the code that you have in your example is correct and executes properly, however you as a programmer need to make sure that you are passing the correct type of value to the setAttribute method. So its not an error in the javascript and that is why you do not get the breakpoint there.

You could create a wrapper which does type-checking. Read the SVG spec to determine what values are allowed for each element's attributes.

Related

Why $('div#my') is returning Object Reference instead of HTML Tag? [duplicate]

This question already has an answer here:
Why sometimes jQuery selector returns something like "a.fn.init"? [closed]
(1 answer)
Closed 6 years ago.
I don't know what happen to my Chrome browser, but all of sudden the behavior of doing $('div#my') in console is totally different from before. One time I've experienced this but later it somehow recovered, so I don't know how to reproduce it, and today it happened again.
Please watch the video:http://peaceevertvimg.org/jq.php.
In the video I do $('div#my') in two different browsers:
the first browser is not chrome but I believe it imitates Chrome so its behavior is what I expect and what I have almost always been experienced. Because currently my chrome is not working as expected so I have to use it to demonstrate my expection: when you do $('div#my)` you see directly the html TAG, and you can easily see the tag's html content, which is "something" in this case.
In contrast, in my chrome browser, the result is different, when I do $('div#my') I see an Object(n.fn.init), and I can't see the "something" immediately, which of course is very inconvenient. But before, I am pretty sure it was not like this, the behavior WAS exactly like that in the first browser.
The simple webpage in this video is http://peaceevertvimg.org/jquery.php, you can go test for yourself in chrome browser. And I am pretty sure most of you will see the first behavior. What happened to my chrome?(I've disabled all expansions and updated it to the latest version)
By the way, is "HTML Tag" and "Object Reference" the right words to describe these two different outcome?
*************Update*************
If the video is not sufficient to understand what I ask and what I want to fix, these two pictures may help.
Picture#1: This is the "normal" behavior I've expected:
Picture#2: This is the current behavior I am experiencing:
You can see the big differences, the first one is much more intuitive, revealing key information immediately, while the 2nd one is not, at least to me. What causes this problem and how do I go back to the first one?
$('div#my') doesn't return a DOM reference. It returns a jQuery wrapper around the found elements.
$('div#my')[0] would return a DOM reference. Or, forget jQuery and use:
document.getElementById("my");
...and you will get a DOM reference directly
Also, since there should/will only ever be one element with a given ID, it is unnecessary to use div#my, just use #my.
Assuming we have a <div id=someDiv>, and then we write:
console.log($("#someDiv"));
console.log($("#someDiv")[0]);
Chrome shows this:
In the first log, we see that the result is a jQuery object that contains one element (the div). In the second, we see the element directly.
Now, depending on what version of Chrome you have, you may see the first one reported simply as [Object object], but that doesn't change the underlying result.
From: Devx (http://www.devx.com/codemag/Article/40923)
Selectors let you select DOM elements so that you can apply
functionality to them with jQuery's operational methods. jQuery uses a
CSS 3.0 syntax (plus some extensions) to select single or multiple
elements in a document. You're probably already familiar with the CSS
syntax from HTML styling. Even if you're not, it's fairly easy to pick
up the key CSS selector features. I'll go as far as saying that jQuery
is the reason I really started to grok CSS. Using CSS syntax you can
select elements by ID, CSS class, attribute filters, or by their
relationship to other elements. You can even chain filter conditions
together. Look at this simple example, which selects all second-column
TD elements in a table using a simple selector: $("#gdEntries
td:nth-child(2)").
The jQuery Object: The Wrapped Set: Selectors return a jQuery object
known as the "wrapped set," which is an array-like structure that
contains all the selected DOM elements. You can iterate over the
wrapped set like an array or access individual elements via the
indexer ($(sel)[0] for example). More importantly, you can also apply
jQuery functions against all the selected elements. - See more at:
http://www.devx.com/codemag/Article/40923#sthash.l8Mo8CbH.dpuf
What you are seeing is said jQuery object returned by jQuery.fn.init().
What is going on is that jQuery() is being defined as jQuery.fn.init() which is another way to say jQuery.prototype.init() which is the selector function! What this means is that no one would call jQuery.fn.init() or jQuery.init() because jQuery() IS .init().
Some more info and a look at the jQuery code here: Help understanding jQuery's jQuery.fn.init Why is init in fn
As for a solution to your problem: https://chrome.google.com/webstore/detail/jquery-console-fix/jlmkkpkcgomkdpfhgjlpaaonhafnjgob?hl=en

Interface of an element in JavaScript

In Chrome, when debugging in JavaScript, it is interesting to get the interface of an element.
Typing the variable name that holds the element in the console usually gives me the element tag. How can I get the interface matching the element. Sometimes Chrome outputs it, but sometimes gives the tag. I am unsure how Chrome returns the value.
Browsers try to be smart when displaying things via console.log to make the output more readable. If you want to consistently get a tree of properties that you can navigate through, you can use console.dir.
interface has no meaning in JS and a very specific meaning in other languages. You can potentially see the WebIDL interface of a DOM Element by viewing the prototype of an element using console.log(element.__proto__); but that is entirely browser dependent and non-standard.
If you want a standard way (i.e. not using __proto__):
console.log(el.constructor.name);
It looks like you can force one view or the other by specifying which you want:
console.dir(el)
gives you the "interface" for that el, while
console.dirxml(el)
prints the element as it would appear in the Elements panel.

__defineSetter__ on innerHTML stops it from rendering

i'm trying to create a watch method for HTML elements, using __define[GS]etter__ when a property is changed. It reacts just fine when i set the value, but if the property listened to, is innerHTML, it somehow fails to render the given string. So basically, when im adding something to innerHTML it doesn't show.
Im using the watch method described in this previous question:
Watch for object properties changes in JavaScript
I could of cause just not listen to innerHTML changes, but i'm also wondering if the __defineSetter__ somehow prevents original handling of setting the value.
Thanks!
That shim code doesn't actually write-through: when you set a property, the value is only remembered on the watch-wrapper and not passed down to the underlying object. It's designed for pure JavaScript objects whose properties have no side-effects (like changing the DOM, in innerHTML's case).
Making it write-through would be a pain since there's no way to directly call the prototype's setter. You'd have to temporarily remove the property, write to the underlying property, then put it back in place.
However it's not really worth pursuing IMO. DOM Nodes are permitted to be ‘host objects’, so there is no guarantee any of the native-JavaScript object-property functions will work on them at all.
(In any case, adding new members onto the Object prototype is generally considered a Really Bad Idea.)
I could of cause just not listen to innerHTML changes
I think that's best, yes.
Ok update.
I found this page on MSDN, which has exactly what i need:
http://msdn.microsoft.com/en-us/library/dd229916(VS.85).aspx
But the Object.getOwnPropertyDescriptor way of doing things apparently only works in IE. Bummer. Any ideas would be appreciated.
I found another webpage with something that looked interesting, but i couldn't quite get it to do what i wanted:
http://www.refactory.org/s/recent/tag/accessors
I've decided to find a workaround for now, something with a timer that checks the attribute for changes and attribute change evnets for browsers that support that.
But if any one finds a solution for the question plz post :)

How to find the snippet of JavaScript that modifies an element?

The page I'm trying inspect has a hidden <input type="hidden" name="Foo" value="123 /> element on a page, where Javascript/AJAX modifies the value. I'm trying to find where on earth in Javascript is the code that modifies this value from time to time.
Is there a tool that could help me find the places in javascript that use/modify that element? Does Firebug provide this, if so, how?
Note: If tried looking for "Foo" in the code, but I haven't found any matching titles. There's JSON and Mootools loaded, +application specific code, which results several thousands lines of code. The element is probably accessed indirectly.
Firebug 1.5 will have "Break-on-Modify" on the HTML panel. See http://getfirebug.com/doc/breakpoints/demo.html#html - Break on DOM (HTML) Mutation Events.
How do you know that the javascript is modifying this value? Since it looks you already know when it's called (since you know it changes), I would suggest a breakpoint in Firebug in the first event that initiates the changing (probably an onclick attribute in other element).
It's kind of hard telling you a "generic" way of knowing where in javascript it's changing Foo's value since there are a lot of different approachs, different libraries, each one with it's syntax.
For example, if you tried searching "Foo" and didn't find it, the script may be traversing the DOM and changing the input's value as a "first child of something". I would try to search for names or ids of input's parent elements and understand the code from there.
I usually just try to understand the javascript logic from every script I use with Firebug's debugging techniques - but just on the script that uses the libraries.
If Firebug doesn't let you define breakpoints on setting some value, you could insert something like this in the page (Firefox-only):
$("textarea")[0].__defineSetter__("value", function(val) {
alert("called");
})
And either breakpoint on the function in Firebug or use console.log or whatever to dump the stack to the firebug console.
I remember seeing somewhere a presentation on Firebug plans, which included a section on various kinds of breakpoints to be supported, but I can't find a link to it right now.
[edit] The above is for the case the value is set by assigning to the value property: .value = .... If you need to catch the moment an attribute is changed (.setAttribute("value", ...)), you can use DOM mutation listeners.

What to do when IE's moveToElementText spits out an Invalid Argument exception

We've written a plugin to the Xinha text editor to handle footnotes. You can take a look at:
http://www.nicholasbs.com/xinha/examples/Newbie.html
In order to handle some problems with the way Webkit and IE handle links at the end of lines (there's no way to use the cursor to get out of the link on the same line) we insert a blank element and move the selection to that, than collapse right. This works fine in Webkit and Gecko, but for some reason moveToElementText is spitting out an Invalid Argument exception. It doesn't matter which element we pass to it, the function seems to be completely broken. In other code paths, however, this function seems to work.
To reproduce the error using the link above, click in the main text input area, type anything, then click on the yellow page icon with the green plus sign, type anything into the lightbox dialog, and click on Insert. An example of the code that causes the problem is below:
if (Xinha.is_ie)
{
var mysel = editor.getSelection();
var myrange = doc.body.createTextRange();
myrange.moveToElementText(newel);
} else
{
editor.selectNodeContents(newel, false);
}
The code in question lives in svn at:
https://svn.openplans.org/svn/xinha_dev/InsertNote
This plugin is built against a branch of Xinha available from svn at:
http://svn.xinha.webfactional.com/branches/new-dialogs
It's not visible in the snippet above, but newel has been appended to the dom using another element that was itself appended to the DOM. When inserting a dom element, you have to re-retrieve your handle if you wish to reference its siblings, since the handle is invalid (I'm not sure, but I think it refers to a DOM element inside of a document fragment and not the one inside of the document.) After re-retrieving the handle from the insert operation, moveToElementText stopped throwing an exception.
I've had the unfortunate experience of debugging this IE exception many different times while implementing a WYSIWYG editor, and it always arises from accessing a property on a DOM node (such as .parentNode) or passing a DOM node to a function (such as moveToElementText) while the DOM node is not currently in the document being rendered.
As you said, sometimes the DOM node is a piece of a document fragment that has been removed from the "actual" DOM being rendered by the browser, and sometimes the node has simply not been inserted yet. Either way, there are a number of properties and methods on DOM nodes that cannot be safely accessed in IE6 until the node has been properly inserted and rendered in the "actual" DOM.
The real kicker is that often this manifestation of IE6's "Invalid Argument" exception cannot be protected by try/catch.

Categories

Resources