How to prevent empty namespace generation in Firefox? - javascript

What I want to do is to serialize a DOM to XML. So I create a new document
var doc = document.implementation.createDocument ('http://AOR-AppML.org', 'Application', null);
and I add nodes, attributes etc. This is working fine.
The problem is that I have different behaviours with XMLSerializer in Google Chrome and Mozilla Firefox.
Chrome console output:
<Application xmlns="http://AOR-AppML.org" name="SoRiN"><ObjectType name="ObjectTypeName"/><Enumeration name="EnumerationName"/></Application>
Firefox console output (notice the xmlns=""):
<Application xmlns="http://AOR-AppML.org" name="SoRiN"><ObjectType xmlns="" name="ObjectTypeName"/><Enumeration xmlns="" name="EnumerationName"/></Application>
I don't want to generate that empty namespace. I've read this namespaces indicates that the corresponding elements have no default namespace (http://www.w3.org/TR/xml-names/#defaulting), but actually I want them to be in the same namespace as Application.
Is there any way to prevent the namespace generation in Firefox?
P.S. - yes, I've followed the advice from this post -> How to prevent the namespace generation?
UPDATE
Here is a fiddle to play with.

You have to use the method createElementNS, instead of createElement, since the latter creates an element with empty namespace URI.
Chrome serializes incorrectly the document (if you parse the string you would get a different document, with namespace URIs wrong), Firefox does the job right. Actually a bug was filed and marked as solved, but the problem seems to be still there.
So, simply replace doc.createElement(yourElementName) with doc.createElementNS('http://AOR-AppML.org', yourElementName).

Related

IE7 JSON object being appended to basepage url

I'm having strange IE7 behavior at the moment. We reach out to an external service that returns a formatted JSON object back to us. Any other version of IE can handle this object. However in IE7, it simply appends the JSON string to the end of the basepage url. so we end up with something like this...
http://localhost:1111/X?Param=223"#13988652796891&{"TestCodes":{"TestCode":.....
The page then takes it upon itself to refresh, and breaks because the url isn't correct. Has anyone seen anything like this before, and if so was there something they were using that caused this to happen? I can give a few more details, I have other issues debugging because I do not have an actual instance of IE7 on this machine. (I've been using IETester, but I can't actually step through code this way)
Thanks in advance!

Object doesn't support property or method remove

I am using extjs and trying to remove a dom element dynamically like this-
if (Ext.getElementById('a'))
Ext.getElementById('a').remove();
This works fine in Chrome. I am running application on IE9 as well but it throws the error- Object doesn't support property or method remove
Please let me know if there is a workaround.
Ext.getElementById() is a private method - you may want to consider using Ext.get() instead.
Anyhow, if it works in Chrome and not in IE, most likely your dom is invalid - search for missing closing tags, or alternatively validate your dom using an online validator. Also see this.

Using exslt extentions be used in javascript xpaths

I would like to use javascript XPaths in a web app using exslt extensions, but I can't figure out how to do this.
Pretend I've got an html doc with some divs in it. I want to run this:
namespaces={'regexp':'http://exslt.org/regular-expressions'};
result = document.evaluate(
"//div[regexp:test(.,'$')]",
document,
function(ns){
return namespaces.hasOwnProperty(ns) ? namespaces[ns] : null;
},
XPathResult.ANY_TYPE,
null);
Only that results in an invalid XPath expression exception in evaluate. I'm using chrome.
Is there anything else I need to do to make this stuff work? I see on exslt.org that there are implementations for javascript, but how do I make sure those are available? Do I need to insert my javascript into a namespaced script element in the dom or something insane?
UPDATE
If this isn't possible directly using browser dom + javascript and xpath, would it be possible to write XSLT using exslt extensions in the browser to simulate document.evaluate (returning a list of elements that match the xpath)?
I don't think the default browser XPath implementation supports EXSLT. The javascript support mentioned on the EXSLT page is likely about how you can provide your own implementation of the exslt function using in-browser.javascript. Here's one example I was able to find very quickly.
In Firefox, for example, you can have Saxon-B as an extension to run XSLT2.0 and Saxon-B has built-in support for exslt (unlike Saxon-HE), though you will likely be better off just using XSLT/XPath 2.0 features. Here's the regular expression syntax, for example. That said, however, relying on a Mozilla Saxon-B extension isn't something that will help you with Chrome or other browsers for that matter.
With that said I don't think you can find a cross-browser solution to use EXSLT extensions in your XPath. The conformance section of the DOM Level 3 XPath calls for XPath 1.0 support and doesn't mention EXSLT. The INVALID_EXPRESSION_ERR is said to be thrown:
if the expression has a syntax error or otherwise is not a legal expression according to the rules of the specific XPathEvaluator or contains specialized extension functions or variables not supported by this implementation.
Finally, here's an open bugzilla ticket for Firefox to open up EXSLT support for their DOM Level 3 XPath implementation. It seems to be sitting there in NEW status since 2007. The ticket says that:
Currently Mozilla gives an exception "The expression is not a legal expression." even if a namespace resolver correctly resolving the EXSLT prefixes to the corresponding URLs is passed in. Here's the test case.
--
If you don't mind me asking, what exactly you wanted to use the regex for? Maybe we can help you get away with a combination of standard XPath string functions?
--
UPDATE You can build an XPath runner via XSLT (like you're asking in the update to your question) but it won't return the nodes from the source document, it will return new nodes that look exactly the same. XSLT produces a new result tree document and I don't think there's a way to let it return references to the original nodes.
As far as I can tell, Mozilla (and Chrome) both support XSLT not only for XML documents loaded from external sources, but also for DOM elements from the document being displayed. The XSLTProcessor documentation mentions how tranformToFragment(), for example, will only produce HTML DOM objects if the owner document is itself an HTMLDocument, or if the output method of the stylesheet is HTML.
Here's a simple XPath Runner that I built testing out your ides:
1) First you would need an XSLT template to work with.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:regexp="http://exslt.org/regular-expressions"
extension-element-prefixes="regexp">
<xsl:template match="/">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
I started building it in the JavaScript using the document.implementation.createDocument APi but figured it would be easier to just load it. FF still supports document.load while Chrome only lets you load stuff using XHR. You would need to start your Chrome with --allow-file-access-from-files if you want to load files with XHR from your local disk.
2) Once we have the template loaded we would need to modify the value of the select attribute of the xsl:copy-of instruction to run the XPath we need:
function runXPath(xpath) {
var processor = new XSLTProcessor();
var xsltns = 'http://www.w3.org/1999/XSL/Transform';
var xmlhttp = new window.XMLHttpRequest();
xmlhttp.open("GET", "xpathrunner.xslt", false);
xmlhttp.send(null);
var transform = xmlhttp.responseXML.documentElement;
var copyof = transform.getElementsByTagNameNS(xsltns, 'copy-of')[0];
copyof.setAttribute('select', xpath);
processor.importStylesheet(transform);
var body = document.getElementById('body'); // I gave my <body> an id attribute
return processor.transformToFragment(body, document);
}
You can now run it with something like:
var nodes = runXPath('//div[#id]');
console.log(nodes.hasChildNodes());
if (nodes.firstChild) {
console.log(nodes.firstChild.localName);
}
It works great for "regular" XPath like that //div[#id] (and fails to find //div[#not-there]) but I just can't get it to run the regexp:test extension function. With the //div[regexp:test(string(#id), "a")] it doesn't error out, just returns empty set.
Mozilla documentation suggests their XSLT processor support EXSLT. I would imagine they are all using libxml/libxslt behind the scenes anyway. That said, I couldn't get it to work in Mozilla either.
Hope it helps.
Any chance you can get away with jQuery regexp? not likely to be helpful for your XPath builder utility but still a way to run regexp on HTML nodes.

Avoid FF JS automatic HTML encoding?

I'm trying to make simple templating for users on a site. I have a test line like this :
<div id="test">Test</div>
It will alert the HTML properly with the following JS in all browsers except FF:
alert( document.getElementById( 'test' ).innerHTML );
In FF it will change the curly braces to their HTML encoded version. I don't want to just URL decode in case the user enters HTML with an actual URL instead of one of the templated ones. Any ideas to solve this outside of REGEXing the return value?
My fiddle is here: http://jsfiddle.net/davestein/ppWkT/
EDIT
Since it's seemingly impossible to avoid the difference in FF, and we're still early in development, we are just going to switch to using [] instead of {}. Marking #Quentin as the correct answer since it's what I'm going by,
When you get the innerHTML of something, you get a serialised representation of the DOM which will include any error recovery or replacing constructs with equivalents that the browser does.
There is no way to get the original source from the DOM.
If your code won't contain %xx elsewhere, you can just run it through unescape().

view contents of large array?

I have a very large array I need to check for debugging purposes, problem is it crashes firebug and the like if I try to view the data.
Is there a way I can dump the array to a text file or something?
Why not just dump it on the document itself? If you are using Firefox, try the following:
document.write(myBigArray.toSource());
Then copy paste like your usually do on normal website.
p/s: toSource() requires browser that supports Javascript 1.3 and above
Opera has scrollable alerts, it's very useful for developing.
EDIT: Tested with success for messages with 500000 lines. You can also copy from it.
Post the array to the server (json/hidden field normal form post), and use your server-side language to save that array dump to a file.
If you are using IE you could try copying a string representation of the array to the clipboard.
There are some libraries that can help in writing to files. You can use ActiveX, but that binds you to internet explorer for your debugging and that's kind of outside the javascript world.

Categories

Resources