diff --git a/src/ol/format/kmlformat.js b/src/ol/format/kmlformat.js index fa0ca3ba7d..2b5548ad7f 100644 --- a/src/ol/format/kmlformat.js +++ b/src/ol/format/kmlformat.js @@ -11,7 +11,6 @@ goog.require('goog.Uri'); goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.dom.xml'); goog.require('goog.math'); goog.require('goog.object'); goog.require('goog.string'); @@ -372,10 +371,10 @@ ol.format.KML.readFlatCoordinates_ = function(node) { */ ol.format.KML.readStyleUrl_ = function(node) { var s = goog.string.trim(ol.xml.getAllTextContent(node, false)); - if (goog.isNull(node.baseURI)) { - return s; - } else { + if (goog.isDefAndNotNull(node.baseURI)) { return goog.Uri.resolve(node.baseURI, s).toString(); + } else { + return s; } }; @@ -388,10 +387,10 @@ ol.format.KML.readStyleUrl_ = function(node) { */ ol.format.KML.readURI_ = function(node) { var s = ol.xml.getAllTextContent(node, false); - if (goog.isNull(node.baseURI)) { - return goog.string.trim(s); - } else { + if (goog.isDefAndNotNull(node.baseURI)) { return goog.Uri.resolve(node.baseURI, goog.string.trim(s)).toString(); + } else { + return goog.string.trim(s); } }; @@ -1396,8 +1395,8 @@ ol.format.KML.prototype.getExtensions = function() { */ ol.format.KML.prototype.readDocumentOrFolder_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'Document' || - node.localName == 'Folder'); + var localName = ol.xml.getLocalName(node); + goog.asserts.assert(localName == 'Document' || localName == 'Folder'); // FIXME use scope somehow var parsersNS = ol.xml.makeParsersNS( ol.format.KML.NAMESPACE_URIS_, { @@ -1466,8 +1465,13 @@ ol.format.KML.prototype.readSharedStyle_ = function(node, objectStack) { if (!goog.isNull(id)) { var style = ol.format.KML.readStyle_(node, objectStack); if (goog.isDef(style)) { - var baseURI = goog.isNull(node.baseURI) ? '' : node.baseURI; - this.sharedStyles_[baseURI + '#' + id] = [style]; + var styleUri; + if (goog.isDefAndNotNull(node.baseURI)) { + styleUri = goog.Uri.resolve(node.baseURI, '#' + id).toString(); + } else { + styleUri = '#' + id; + } + this.sharedStyles_[styleUri] = [style]; } } }; @@ -1488,23 +1492,28 @@ ol.format.KML.prototype.readSharedStyleMap_ = function(node, objectStack) { if (!goog.isDef(styleObject)) { return; } - var baseURI = goog.isNull(node.baseURI) ? '' : node.baseURI; var style = /** @type {ol.style.Style} */ (goog.object.get(styleObject, 'style', null)); + var styleUri; + if (goog.isDefAndNotNull(node.baseURI)) { + styleUri = goog.Uri.resolve(node.baseURI, '#' + id).toString(); + } else { + styleUri = '#' + id; + } if (!goog.isNull(style)) { - this.sharedStyles_[baseURI + '#' + id] = [style]; + this.sharedStyles_[styleUri] = [style]; } var styleUrl = /** @type {string|undefined} */ (goog.object.get(styleObject, 'styleUrl')); if (goog.isDef(styleUrl)) { - var styleUri; - if (goog.isNull(node.baseURI)) { - styleUri = '#' + goog.string.trim(styleUrl); + var styleUrlUri; + if (goog.isDefAndNotNull(node.baseURI)) { + styleUrlUri = goog.Uri.resolve(node.baseURI, styleUrl).toString(); } else { - styleUri = goog.Uri.resolve(baseURI, styleUrl).toString(); + styleUrlUri = '#' + goog.string.trim(styleUrl).replace(/^#/, ''); } - goog.asserts.assert(styleUri in this.sharedStyles_); - this.sharedStyles_[baseURI + '#' + id] = this.sharedStyles_[styleUri]; + goog.asserts.assert(styleUrlUri in this.sharedStyles_); + this.sharedStyles_[styleUri] = this.sharedStyles_[styleUrlUri]; } } }; @@ -1539,21 +1548,22 @@ ol.format.KML.prototype.readFeaturesFromNode = function(node) { return []; } var features; - if (node.localName == 'Document' || node.localName == 'Folder') { + var localName = ol.xml.getLocalName(node); + if (localName == 'Document' || localName == 'Folder') { features = this.readDocumentOrFolder_(node, []); if (goog.isDef(features)) { return features; } else { return []; } - } else if (node.localName == 'Placemark') { + } else if (localName == 'Placemark') { var feature = this.readPlacemark_(node, []); if (goog.isDef(feature)) { return [feature]; } else { return []; } - } else if (node.localName == 'kml') { + } else if (localName == 'kml') { features = []; var n; for (n = node.firstElementChild; !goog.isNull(n); @@ -1576,12 +1586,12 @@ ol.format.KML.prototype.readFeaturesFromNode = function(node) { * @todo stability experimental */ ol.format.KML.prototype.readName = function(source) { - if (source instanceof Document) { - return this.readNameFromDocument(source); - } else if (source instanceof Node) { - return this.readNameFromNode(source); + if (ol.xml.isDocument(source)) { + return this.readNameFromDocument(/** @type {Document} */ (source)); + } else if (ol.xml.isNode(source)) { + return this.readNameFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = goog.dom.xml.loadXml(source); + var doc = ol.xml.load(source); return this.readNameFromDocument(doc); } else { goog.asserts.fail(); @@ -1622,12 +1632,13 @@ ol.format.KML.prototype.readNameFromNode = function(node) { } } for (n = node.firstElementChild; !goog.isNull(n); n = n.nextElementSibling) { + var localName = ol.xml.getLocalName(n); if (goog.array.indexOf(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) != -1 && - (n.localName == 'Document' || - n.localName == 'Folder' || - n.localName == 'Placemark' || - n.localName == 'kml')) { + (localName == 'Document' || + localName == 'Folder' || + localName == 'Placemark' || + localName == 'kml')) { var name = this.readNameFromNode(n); if (goog.isDef(name)) { return name; diff --git a/src/ol/format/xmlformat.js b/src/ol/format/xmlformat.js index 0025cbd452..7e0dc19ec1 100644 --- a/src/ol/format/xmlformat.js +++ b/src/ol/format/xmlformat.js @@ -3,9 +3,9 @@ goog.provide('ol.format.XML'); goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.dom.xml'); goog.require('ol.format.Format'); goog.require('ol.format.FormatType'); +goog.require('ol.xml'); @@ -31,12 +31,12 @@ ol.format.XML.prototype.getType = function() { * @inheritDoc */ ol.format.XML.prototype.readFeature = function(source) { - if (source instanceof Document) { - return this.readFeatureFromDocument(source); - } else if (source instanceof Node) { - return this.readFeatureFromNode(source); + if (ol.xml.isDocument(source)) { + return this.readFeatureFromDocument(/** @type {Document} */ (source)); + } else if (ol.xml.isNode(source)) { + return this.readFeatureFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = goog.dom.xml.loadXml(source); + var doc = ol.xml.load(source); return this.readFeatureFromDocument(doc); } else { goog.asserts.fail(); @@ -70,12 +70,12 @@ ol.format.XML.prototype.readFeatureFromNode = goog.abstractMethod; * @inheritDoc */ ol.format.XML.prototype.readFeatures = function(source) { - if (source instanceof Document) { - return this.readFeaturesFromDocument(source); - } else if (source instanceof Node) { - return this.readFeaturesFromNode(source); + if (ol.xml.isDocument(source)) { + return this.readFeaturesFromDocument(/** @type {Document} */ (source)); + } else if (ol.xml.isNode(source)) { + return this.readFeaturesFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = goog.dom.xml.loadXml(source); + var doc = ol.xml.load(source); return this.readFeaturesFromDocument(doc); } else { goog.asserts.fail(); @@ -114,12 +114,12 @@ ol.format.XML.prototype.readFeaturesFromNode = goog.abstractMethod; * @inheritDoc */ ol.format.XML.prototype.readGeometry = function(source) { - if (source instanceof Document) { - return this.readGeometryFromDocument(source); - } else if (source instanceof Node) { - return this.readGeometryFromNode(source); + if (ol.xml.isDocument(source)) { + return this.readGeometryFromDocument(/** @type {Document} */ (source)); + } else if (ol.xml.isNode(source)) { + return this.readGeometryFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = goog.dom.xml.loadXml(source); + var doc = ol.xml.load(source); return this.readGeometryFromDocument(doc); } else { goog.asserts.fail(); @@ -148,12 +148,12 @@ ol.format.XML.prototype.readGeometryFromNode = goog.abstractMethod; * @inheritDoc */ ol.format.XML.prototype.readProjection = function(source) { - if (source instanceof Document) { - return this.readProjectionFromDocument(source); - } else if (source instanceof Node) { - return this.readProjectionFromNode(source); + if (ol.xml.isDocument(source)) { + return this.readProjectionFromDocument(/** @type {Document} */ (source)); + } else if (ol.xml.isNode(source)) { + return this.readProjectionFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = goog.dom.xml.loadXml(source); + var doc = ol.xml.load(source); return this.readProjectionFromDocument(doc); } else { goog.asserts.fail(); diff --git a/src/ol/source/vectorfilesource.js b/src/ol/source/vectorfilesource.js index 88009052f0..c2fd85339a 100644 --- a/src/ol/source/vectorfilesource.js +++ b/src/ol/source/vectorfilesource.js @@ -4,12 +4,13 @@ goog.provide('ol.source.VectorFile'); goog.require('goog.asserts'); -goog.require('goog.dom.xml'); goog.require('goog.net.XhrIo'); +goog.require('goog.userAgent'); goog.require('ol.format.FormatType'); goog.require('ol.proj'); goog.require('ol.source.State'); goog.require('ol.source.Vector'); +goog.require('ol.xml'); @@ -88,9 +89,11 @@ ol.source.VectorFile.prototype.handleXhrIo_ = function(event) { } else if (type == ol.format.FormatType.TEXT) { source = xhrIo.getResponseText(); } else if (type == ol.format.FormatType.XML) { - source = xhrIo.getResponseXml(); - if (goog.isNull(source)) { - source = goog.dom.xml.loadXml(xhrIo.getResponseText()); + if (!goog.userAgent.IE) { + source = xhrIo.getResponseXml(); + } + if (!goog.isDefAndNotNull(source)) { + source = ol.xml.load(xhrIo.getResponseText()); } } else { goog.asserts.fail(); diff --git a/src/ol/xml.js b/src/ol/xml.js index e491d16454..c21e526ea6 100644 --- a/src/ol/xml.js +++ b/src/ol/xml.js @@ -4,6 +4,7 @@ goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); +goog.require('goog.userAgent'); /** @@ -48,6 +49,104 @@ ol.xml.getAllTextContent_ = function(node, normalizeWhitespace, accumulator) { }; +/** + * @param {Node} node Node. + * @private + * @return {string} Local name. + */ +ol.xml.getLocalName_ = function(node) { + return node.localName; +}; + + +/** + * @param {Node} node Node. + * @private + * @return {string} Local name. + */ +ol.xml.getLocalNameIE_ = function(node) { + var localName = node.localName; + if (goog.isDef(localName)) { + return localName; + } + var baseName = node.baseName; + goog.asserts.assert(goog.isDefAndNotNull(baseName)); + return baseName; +}; + + +/** + * @param {Node} node Node. + * @return {string} Local name. + */ +ol.xml.getLocalName = goog.userAgent.IE ? + ol.xml.getLocalNameIE_ : ol.xml.getLocalName_; + + +/** + * @param {?} value Value. + * @private + * @return {boolean} Is document. + */ +ol.xml.isDocument_ = function(value) { + return value instanceof Document; +}; + + +/** + * @param {?} value Value. + * @private + * @return {boolean} Is document. + */ +ol.xml.isDocumentIE_ = function(value) { + return goog.isObject(value) && value.nodeType == goog.dom.NodeType.DOCUMENT; +}; + + +/** + * @param {?} value Value. + * @return {boolean} Is document. + */ +ol.xml.isDocument = goog.userAgent.IE ? + ol.xml.isDocumentIE_ : ol.xml.isDocument_; + + +/** + * @param {?} value Value. + * @private + * @return {boolean} Is node. + */ +ol.xml.isNode_ = function(value) { + return value instanceof Node; +}; + + +/** + * @param {?} value Value. + * @private + * @return {boolean} Is node. + */ +ol.xml.isNodeIE_ = function(value) { + return goog.isObject(value) && goog.isDef(value.nodeType); +}; + + +/** + * @param {?} value Value. + * @return {boolean} Is node. + */ +ol.xml.isNode = goog.userAgent.IE ? ol.xml.isNodeIE_ : ol.xml.isNode_; + + +/** + * @param {string} xml XML. + * @return {Document} Document. + */ +ol.xml.load = function(xml) { + return new DOMParser().parseFromString(xml, 'application/xml'); +}; + + /** * @param {function(this: T, Node, Array.<*>): (Array.<*>|undefined)} * valueReader Value reader. diff --git a/test/spec/ol/format/kmlformat.test.js b/test/spec/ol/format/kmlformat.test.js index 67f7e7c92c..3fb57ec856 100644 --- a/test/spec/ol/format/kmlformat.test.js +++ b/test/spec/ol/format/kmlformat.test.js @@ -917,7 +917,7 @@ describe('ol.format.KML', function() { expect(s.getFill().getColor()).to.eql([0, 0, 0, 0]); }); - it('can read a normal styleUrls', function() { + it('can read normal styleUrls', function() { var text = '' + ' ' + @@ -1398,7 +1398,7 @@ describe('ol.format.KML', function() { var features; before(function(done) { - afterLoadXml('spec/ol/format/kml/states.kml', function(xml) { + afterLoadText('spec/ol/format/kml/states.kml', function(xml) { try { features = format.readFeatures(xml); } catch (e) { @@ -1444,7 +1444,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ' ' + - ' ' + + ' ' + ''; expect(format.readName(kml)).to.be(undefined); }); diff --git a/test/test-extensions.js b/test/test-extensions.js index 1aad4c89cb..156f307752 100644 --- a/test/test-extensions.js +++ b/test/test-extensions.js @@ -1,3 +1,5 @@ +// FIXME remove afterLoadXml as it uses the wrong XML parser on IE9 + // helper functions for async testing (function(global) {