I read through https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML, which claims SyntaxError may happen.
dom = document.createElement('div')
// output: <div></div>
dom.innerHTML = '[try.various.strings.here]'
// output: "[try.various.strings.here]"
dom
// check final DOM
I have tried to replace test string with <div> (partial), <div (broken) and <div></p> (unmatched). Never have I met exception. I wonder whether I need to add pre-check or protection (try..catch) for it.
TL;DR
The specifications say it can if the browser wants it to, but I don't think any major browser does so for HTML (well, I wouldn't make any guarantees about IE9-IE11 and certain element types, actually). (Whereas they do for XML.) From the definition of an HTML parser in the HTML 5.2 specification:
This specification defines the parsing rules for HTML documents, whether they are syntactically correct or not. Certain points in the parsing algorithm are said to be parse errors. The error handling for parse errors is well-defined (that’s the processing rules described throughout this specification), but user agents, while parsing an HTML document, may abort the parser at the first parse error that they encounter for which they do not wish to apply the rules described in this specification.
(my emphasis)
Details
The DOM Parsing and Serialization spec defines innerHTML, and says:
On setting, these steps must be run:
Let fragment be the result of invoking the fragment parsing algorithm with the new value as markup, and the context object as the context element.
If the context object is a template element, then let context object be the template's template contents (a DocumentFragment).
Replace all with fragment within the context object.
If we follow the fragment parsing algorithm link, we get to:
The following steps form the fragment parsing algorithm, whose arguments are a markup string and a context element:
If the context element's node document is an HTML document: let algorithm be the HTML fragment parsing algorithm.
If the context element's node document is an XML document: let algorithm be the XML fragment parsing algorithm.
Let new children be the result of invoking algorithm with markup as the input, and context element as the context element.
Let fragment be a new DocumentFragment whose node document is context element's node document.
Append each Node in new children to fragment (in tree order).
Return the value of fragment.
If we follow the HTML parsing algorithm link above, we get steps creating and using an HTML parser. If we follow the link to the definition of an HTML parser, we get the first link in TL;DR above and the text quoted above.
Errors can occur.
Basically, it depends on the content type and how it is served by the browser.
In traditional cases it will not throw an error, but in some edge cases such as Uncaught SyntaxError: Failed to set the 'innerHTML' property on 'Element': The provided markup is invalid XML or as can be seen in this bug report, the error will be triggered.
Better wrap it in a try..catch statement.
Related
In the spec:
The third is a flag indicating whether the element will "non-blocking". Initially, script elements must have this flag set. It is unset by the HTML parser and the XML parser on script elements they insert. In addition, whenever a script element whose "non-blocking" flag is set has an async content attribute added, the element’s "non-blocking" flag must be unset.
Sorry,I can't understand what it means.There are some questions of this:
1.
The third is a flag indicating whether the element will "non-blocking". Initially, script elements must have this flag set
"Initially" means there is a property in HTMLScriptElement class named non-blocking and default is true or it means it's true when the script element created or instantiated before parsered by HTML parser?
2.
It is unset by the HTML parser and the XML parser on script elements they insert.
The "insert" means that the script element insert to the document by using document.write or the insert operation?
3.
In addition, whenever a script element whose "non-blocking" flag is set has an async content attribute added, the element’s "non-blocking" flag must be unset.
The async links to the async attribute,but there is a word "content",so what it exactly means?The attribute or the content fetched from server or local?
And if it means content,does it representes the HTML Parser will continue to parse the subsequent bytes of the script element before the async content added?(I write some tests,I think this is wrong)
4.And the most important,does "non-blocking" means not blocking the IO, fetch resource, update layout, repaint etc like we usually talk about?Or there is some else meaning?And the spec says that "Initially, script elements must have this flag set",but we ofen consider the script is "blocking"(exactly when executed),so I am in doubt when I first read this and so now.Could anyone clarify my doubt?
5.Finally,is there any implemention(exactly I mean the src code which can be debug conveniently) of the spec?I think based in chrome is better,sorry,I am not say others is not good,just because I only install chrome.
I don't follow the distinction. What functional difference would it make which of those an implementation chose?
The insert operation. document.write doesn't insert to the document. It injects characters into the input byte stream that the parser processes.
In HTML5 spec parlance, there are two types of "attribute". "Content attribute" and "IDL attribute". A "content attribute" is what you put in markup: <script async> is the async content attribute. An "IDL attribute" is what most people think of as a property in JavaScript myScriptElement.async.
It means not blocking the parser thread. The parser takes characters from the input stream and creates elements, text node objects etc. When the parser is blocked it stops consuming characters from the input stream. (Although it might look-ahead in the input stream to guess whether it's going be asked to fetch other resources, and speculatively fetch them anyway). When the </script> tag is seen, if non-blocking flag is unset, the parser will not consume any further characters from the current input stream until the script has been fetched and run. This allows the script to include document.write to inject characters into the input stream such that they will be parsed next.
Both Chrome (blink) and Firefox (gecko) are open source, but personally I've not tried inspecting either code base in any detail so can't advise how difficult either is. And it's probably quite a personal preference anyway.
The line JSON.stringify( $("p") ); causes an error:
InvalidStateError: Failed to read the 'selectionDirection' property from 'HTMLInputElement': The input element's type ('button') does not support selection.
(I'm using Google Chrome 34)
Why?
How else should I make $("p") more portable so I can store it or pass it in a message?
There's a ton of state (attributes, event handlers, the code related to those, internal state, ...) involved in an HTML element. It just doesn't make sense to serialize all of that into JSON.
If you want to get some kind of representation of the element in JSON, you could for instance use .html() to get a HTML string representing the element. Or come up with a format that encodes, for instance, tag names, attributes and text only. You could have to implement that by hand though (or find a library - "html to json" could be a good keyword)
I am not quite sure, and haven't been able to find anything.
Using stringByEvaluatingJavascriptFromString:, I have been able to manipulate javascript in my page from objective-c. However, I now want to populate form fields by passing raw xml data from the iOS UIWebView into the html file (which is local to the app), and then using the parsed data.
Looking over the W3C document, it seems I need to do something like:
parser = new DOMParser();
xmlString = parser.parseFromString(txt, "text/xml");
Which should return a DOM object from the XML (which here is represented by the string txt). I should then be able to access the properties of this DOM object from
xmlString.getElementsByTagName("from")[0].childNodes[0].nodeValue;
Assuming we have an XML node such as:
<from>Sender</from>
However, this doesn't seem to work. Setting that nodeValue into a string and returning it returns nil. Likewise, form fields are not populated.
My question, then, is whether the embedded browser in an app can utilize the DOM Parser - and if it can, what syntax I might use to access values from it?
Solved, unfortunately very fast. It seems that when setting form fields you need to specify VALUE instead of innerhtml.
so I did:
document.getElementById("FIELDID").value =
xmlString.getElementsByTagName("from")[0].childNodes[0].nodeValue;
Also, I had the parameters passed to the DOM parser wrong - it is "text/xml" for the second parameter.
I have been using a DOMParser object to parse a text string to an XML tree. However it is not available in the context of a Web Worker (and neither is, of course, document.ELEMENT_NODE or the various other constants that would be needed). Is there any other way to do that?
Please note that I do not want to manipulate the DOM of the current page. The XML file won't contain HTML elements or anything of the sort. In fact, I do not want to touch the document object at all. I simply want to provide a text string like the following:
<car color="blue"><driver/></car>
...and get back a suitable tree structure and a way to traverse it. I also do not care about schema validation or anything fancy. I know about XML for <SCRIPT>, which many may find useful (hence I'm linking to it here), however its licensing is not really suitable for me. I'm not sure if jQuery includes an XML parser (I'm fairly new to this stuff), but even if it does (and it is usable inside a Worker), I would not include an extra ~50K lines of code just for this function.
I suppose I could write a simple XML parser in JavaScript, I'm just wondering if I'm missing a quicker option.
according to the spec
The DOM APIs (Node objects, Document objects, etc) are not available to workers in this version of this specification.
I guess thats why DOMParser is not availlable, but I don't really understand why that decision was made. (fetching and processing an XML document in a WebWorker does not seems unreasonnable)
but you can import other tools available: a "Cross Platform XML Parsing in JavaScript"
At this point I like to share my parser: https://github.com/tobiasnickel/tXml
with its tXml() method you can parse a string into an object and it takes only 0.5kb minified + gzipped
Is it possible to check if loaded with xmlDoc.loadXML(xmlData); xml string is invalid? For example if there is missed closing bracket or a tag.
If you pass a string to loadXML that isn't a well-formed XML document, the document object will be empty (no childNodes) and xmlDoc.parseError.errorCode will be set to something other than 0. xmlDoc.parseError.reason will give you a user-readable error message.
If you want to test a snippet and not a full document, wrap it in <x>...</x> tags so that the parser will only see one root element.
(There are a few reasons that MSXML might fail to parse a document other than it being non-well-formed. For example an external DTD subset or entity might not be network-reachable, or the DTD might use features MSXML doesn't support. You can't use MSXML to parse XHTML documents with their DTD for this reason. But if DTD-cruft isn't involved, a parser failure means the input wasn't well-formed.)
All info about parse errors is hidden in "xmlDoc.parseError"