Merge pull request #1639 from twpayne/kml-ie9

KML support for Internet Explorer
This commit is contained in:
Tom Payne
2014-02-05 14:23:07 +01:00
6 changed files with 174 additions and 59 deletions

View File

@@ -11,7 +11,6 @@ goog.require('goog.Uri');
goog.require('goog.array'); goog.require('goog.array');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('goog.dom.NodeType'); goog.require('goog.dom.NodeType');
goog.require('goog.dom.xml');
goog.require('goog.math'); goog.require('goog.math');
goog.require('goog.object'); goog.require('goog.object');
goog.require('goog.string'); goog.require('goog.string');
@@ -372,10 +371,10 @@ ol.format.KML.readFlatCoordinates_ = function(node) {
*/ */
ol.format.KML.readStyleUrl_ = function(node) { ol.format.KML.readStyleUrl_ = function(node) {
var s = goog.string.trim(ol.xml.getAllTextContent(node, false)); var s = goog.string.trim(ol.xml.getAllTextContent(node, false));
if (goog.isNull(node.baseURI)) { if (goog.isDefAndNotNull(node.baseURI)) {
return s;
} else {
return goog.Uri.resolve(node.baseURI, s).toString(); 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) { ol.format.KML.readURI_ = function(node) {
var s = ol.xml.getAllTextContent(node, false); var s = ol.xml.getAllTextContent(node, false);
if (goog.isNull(node.baseURI)) { if (goog.isDefAndNotNull(node.baseURI)) {
return goog.string.trim(s);
} else {
return goog.Uri.resolve(node.baseURI, goog.string.trim(s)).toString(); 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) { ol.format.KML.prototype.readDocumentOrFolder_ = function(node, objectStack) {
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
goog.asserts.assert(node.localName == 'Document' || var localName = ol.xml.getLocalName(node);
node.localName == 'Folder'); goog.asserts.assert(localName == 'Document' || localName == 'Folder');
// FIXME use scope somehow // FIXME use scope somehow
var parsersNS = ol.xml.makeParsersNS( var parsersNS = ol.xml.makeParsersNS(
ol.format.KML.NAMESPACE_URIS_, { ol.format.KML.NAMESPACE_URIS_, {
@@ -1466,8 +1465,13 @@ ol.format.KML.prototype.readSharedStyle_ = function(node, objectStack) {
if (!goog.isNull(id)) { if (!goog.isNull(id)) {
var style = ol.format.KML.readStyle_(node, objectStack); var style = ol.format.KML.readStyle_(node, objectStack);
if (goog.isDef(style)) { if (goog.isDef(style)) {
var baseURI = goog.isNull(node.baseURI) ? '' : node.baseURI; var styleUri;
this.sharedStyles_[baseURI + '#' + id] = [style]; 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)) { if (!goog.isDef(styleObject)) {
return; return;
} }
var baseURI = goog.isNull(node.baseURI) ? '' : node.baseURI;
var style = /** @type {ol.style.Style} */ var style = /** @type {ol.style.Style} */
(goog.object.get(styleObject, 'style', null)); (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)) { if (!goog.isNull(style)) {
this.sharedStyles_[baseURI + '#' + id] = [style]; this.sharedStyles_[styleUri] = [style];
} }
var styleUrl = /** @type {string|undefined} */ var styleUrl = /** @type {string|undefined} */
(goog.object.get(styleObject, 'styleUrl')); (goog.object.get(styleObject, 'styleUrl'));
if (goog.isDef(styleUrl)) { if (goog.isDef(styleUrl)) {
var styleUri; var styleUrlUri;
if (goog.isNull(node.baseURI)) { if (goog.isDefAndNotNull(node.baseURI)) {
styleUri = '#' + goog.string.trim(styleUrl); styleUrlUri = goog.Uri.resolve(node.baseURI, styleUrl).toString();
} else { } else {
styleUri = goog.Uri.resolve(baseURI, styleUrl).toString(); styleUrlUri = '#' + goog.string.trim(styleUrl).replace(/^#/, '');
} }
goog.asserts.assert(styleUri in this.sharedStyles_); goog.asserts.assert(styleUrlUri in this.sharedStyles_);
this.sharedStyles_[baseURI + '#' + id] = this.sharedStyles_[styleUri]; this.sharedStyles_[styleUri] = this.sharedStyles_[styleUrlUri];
} }
} }
}; };
@@ -1539,21 +1548,22 @@ ol.format.KML.prototype.readFeaturesFromNode = function(node) {
return []; return [];
} }
var features; var features;
if (node.localName == 'Document' || node.localName == 'Folder') { var localName = ol.xml.getLocalName(node);
if (localName == 'Document' || localName == 'Folder') {
features = this.readDocumentOrFolder_(node, []); features = this.readDocumentOrFolder_(node, []);
if (goog.isDef(features)) { if (goog.isDef(features)) {
return features; return features;
} else { } else {
return []; return [];
} }
} else if (node.localName == 'Placemark') { } else if (localName == 'Placemark') {
var feature = this.readPlacemark_(node, []); var feature = this.readPlacemark_(node, []);
if (goog.isDef(feature)) { if (goog.isDef(feature)) {
return [feature]; return [feature];
} else { } else {
return []; return [];
} }
} else if (node.localName == 'kml') { } else if (localName == 'kml') {
features = []; features = [];
var n; var n;
for (n = node.firstElementChild; !goog.isNull(n); for (n = node.firstElementChild; !goog.isNull(n);
@@ -1576,12 +1586,12 @@ ol.format.KML.prototype.readFeaturesFromNode = function(node) {
* @todo stability experimental * @todo stability experimental
*/ */
ol.format.KML.prototype.readName = function(source) { ol.format.KML.prototype.readName = function(source) {
if (source instanceof Document) { if (ol.xml.isDocument(source)) {
return this.readNameFromDocument(source); return this.readNameFromDocument(/** @type {Document} */ (source));
} else if (source instanceof Node) { } else if (ol.xml.isNode(source)) {
return this.readNameFromNode(source); return this.readNameFromNode(/** @type {Node} */ (source));
} else if (goog.isString(source)) { } else if (goog.isString(source)) {
var doc = goog.dom.xml.loadXml(source); var doc = ol.xml.load(source);
return this.readNameFromDocument(doc); return this.readNameFromDocument(doc);
} else { } else {
goog.asserts.fail(); goog.asserts.fail();
@@ -1622,12 +1632,13 @@ ol.format.KML.prototype.readNameFromNode = function(node) {
} }
} }
for (n = node.firstElementChild; !goog.isNull(n); n = n.nextElementSibling) { 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_, if (goog.array.indexOf(ol.format.KML.NAMESPACE_URIS_,
n.namespaceURI) != -1 && n.namespaceURI) != -1 &&
(n.localName == 'Document' || (localName == 'Document' ||
n.localName == 'Folder' || localName == 'Folder' ||
n.localName == 'Placemark' || localName == 'Placemark' ||
n.localName == 'kml')) { localName == 'kml')) {
var name = this.readNameFromNode(n); var name = this.readNameFromNode(n);
if (goog.isDef(name)) { if (goog.isDef(name)) {
return name; return name;

View File

@@ -3,9 +3,9 @@ goog.provide('ol.format.XML');
goog.require('goog.array'); goog.require('goog.array');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('goog.dom.NodeType'); goog.require('goog.dom.NodeType');
goog.require('goog.dom.xml');
goog.require('ol.format.Format'); goog.require('ol.format.Format');
goog.require('ol.format.FormatType'); goog.require('ol.format.FormatType');
goog.require('ol.xml');
@@ -31,12 +31,12 @@ ol.format.XML.prototype.getType = function() {
* @inheritDoc * @inheritDoc
*/ */
ol.format.XML.prototype.readFeature = function(source) { ol.format.XML.prototype.readFeature = function(source) {
if (source instanceof Document) { if (ol.xml.isDocument(source)) {
return this.readFeatureFromDocument(source); return this.readFeatureFromDocument(/** @type {Document} */ (source));
} else if (source instanceof Node) { } else if (ol.xml.isNode(source)) {
return this.readFeatureFromNode(source); return this.readFeatureFromNode(/** @type {Node} */ (source));
} else if (goog.isString(source)) { } else if (goog.isString(source)) {
var doc = goog.dom.xml.loadXml(source); var doc = ol.xml.load(source);
return this.readFeatureFromDocument(doc); return this.readFeatureFromDocument(doc);
} else { } else {
goog.asserts.fail(); goog.asserts.fail();
@@ -70,12 +70,12 @@ ol.format.XML.prototype.readFeatureFromNode = goog.abstractMethod;
* @inheritDoc * @inheritDoc
*/ */
ol.format.XML.prototype.readFeatures = function(source) { ol.format.XML.prototype.readFeatures = function(source) {
if (source instanceof Document) { if (ol.xml.isDocument(source)) {
return this.readFeaturesFromDocument(source); return this.readFeaturesFromDocument(/** @type {Document} */ (source));
} else if (source instanceof Node) { } else if (ol.xml.isNode(source)) {
return this.readFeaturesFromNode(source); return this.readFeaturesFromNode(/** @type {Node} */ (source));
} else if (goog.isString(source)) { } else if (goog.isString(source)) {
var doc = goog.dom.xml.loadXml(source); var doc = ol.xml.load(source);
return this.readFeaturesFromDocument(doc); return this.readFeaturesFromDocument(doc);
} else { } else {
goog.asserts.fail(); goog.asserts.fail();
@@ -114,12 +114,12 @@ ol.format.XML.prototype.readFeaturesFromNode = goog.abstractMethod;
* @inheritDoc * @inheritDoc
*/ */
ol.format.XML.prototype.readGeometry = function(source) { ol.format.XML.prototype.readGeometry = function(source) {
if (source instanceof Document) { if (ol.xml.isDocument(source)) {
return this.readGeometryFromDocument(source); return this.readGeometryFromDocument(/** @type {Document} */ (source));
} else if (source instanceof Node) { } else if (ol.xml.isNode(source)) {
return this.readGeometryFromNode(source); return this.readGeometryFromNode(/** @type {Node} */ (source));
} else if (goog.isString(source)) { } else if (goog.isString(source)) {
var doc = goog.dom.xml.loadXml(source); var doc = ol.xml.load(source);
return this.readGeometryFromDocument(doc); return this.readGeometryFromDocument(doc);
} else { } else {
goog.asserts.fail(); goog.asserts.fail();
@@ -148,12 +148,12 @@ ol.format.XML.prototype.readGeometryFromNode = goog.abstractMethod;
* @inheritDoc * @inheritDoc
*/ */
ol.format.XML.prototype.readProjection = function(source) { ol.format.XML.prototype.readProjection = function(source) {
if (source instanceof Document) { if (ol.xml.isDocument(source)) {
return this.readProjectionFromDocument(source); return this.readProjectionFromDocument(/** @type {Document} */ (source));
} else if (source instanceof Node) { } else if (ol.xml.isNode(source)) {
return this.readProjectionFromNode(source); return this.readProjectionFromNode(/** @type {Node} */ (source));
} else if (goog.isString(source)) { } else if (goog.isString(source)) {
var doc = goog.dom.xml.loadXml(source); var doc = ol.xml.load(source);
return this.readProjectionFromDocument(doc); return this.readProjectionFromDocument(doc);
} else { } else {
goog.asserts.fail(); goog.asserts.fail();

View File

@@ -4,12 +4,13 @@
goog.provide('ol.source.VectorFile'); goog.provide('ol.source.VectorFile');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('goog.dom.xml');
goog.require('goog.net.XhrIo'); goog.require('goog.net.XhrIo');
goog.require('goog.userAgent');
goog.require('ol.format.FormatType'); goog.require('ol.format.FormatType');
goog.require('ol.proj'); goog.require('ol.proj');
goog.require('ol.source.State'); goog.require('ol.source.State');
goog.require('ol.source.Vector'); 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) { } else if (type == ol.format.FormatType.TEXT) {
source = xhrIo.getResponseText(); source = xhrIo.getResponseText();
} else if (type == ol.format.FormatType.XML) { } else if (type == ol.format.FormatType.XML) {
if (!goog.userAgent.IE) {
source = xhrIo.getResponseXml(); source = xhrIo.getResponseXml();
if (goog.isNull(source)) { }
source = goog.dom.xml.loadXml(xhrIo.getResponseText()); if (!goog.isDefAndNotNull(source)) {
source = ol.xml.load(xhrIo.getResponseText());
} }
} else { } else {
goog.asserts.fail(); goog.asserts.fail();

View File

@@ -4,6 +4,7 @@ goog.require('goog.array');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('goog.dom.NodeType'); goog.require('goog.dom.NodeType');
goog.require('goog.object'); 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)} * @param {function(this: T, Node, Array.<*>): (Array.<*>|undefined)}
* valueReader Value reader. * valueReader Value reader.

View File

@@ -917,7 +917,7 @@ describe('ol.format.KML', function() {
expect(s.getFill().getColor()).to.eql([0, 0, 0, 0]); 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 = var text =
'<kml xmlns="http://earth.google.com/kml/2.2">' + '<kml xmlns="http://earth.google.com/kml/2.2">' +
' <Document>' + ' <Document>' +
@@ -1398,7 +1398,7 @@ describe('ol.format.KML', function() {
var features; var features;
before(function(done) { before(function(done) {
afterLoadXml('spec/ol/format/kml/states.kml', function(xml) { afterLoadText('spec/ol/format/kml/states.kml', function(xml) {
try { try {
features = format.readFeatures(xml); features = format.readFeatures(xml);
} catch (e) { } catch (e) {
@@ -1444,7 +1444,7 @@ describe('ol.format.KML', function() {
' <Folder>' + ' <Folder>' +
' <Placemark/>' + ' <Placemark/>' +
' </Folder>' + ' </Folder>' +
' <Document>' + ' </Document>' +
'</kml>'; '</kml>';
expect(format.readName(kml)).to.be(undefined); expect(format.readName(kml)).to.be(undefined);
}); });

View File

@@ -1,3 +1,5 @@
// FIXME remove afterLoadXml as it uses the wrong XML parser on IE9
// helper functions for async testing // helper functions for async testing
(function(global) { (function(global) {