From 5d8212e48fbb7b539c16ba8717e392b917d3267e Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Tue, 10 Nov 2020 13:31:44 +0000 Subject: [PATCH] Replace readURI with readStyleURL for StyleURLs readStyleURL ensures URL begins with # if it does not contain one Remove old partial fix Test handling of missing # in StyleURL --- src/ol/format/KML.js | 32 ++++++++++++++++++++++-------- test/spec/ol/format/kml.test.js | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/ol/format/KML.js b/src/ol/format/KML.js index 8775ecf583..84c9165075 100644 --- a/src/ol/format/KML.js +++ b/src/ol/format/KML.js @@ -126,7 +126,7 @@ const PLACEMARK_PARSERS = makeStructureNS( 'name': makeObjectPropertySetter(readString), 'open': makeObjectPropertySetter(readBoolean), 'phoneNumber': makeObjectPropertySetter(readString), - 'styleUrl': makeObjectPropertySetter(readURI), + 'styleUrl': makeObjectPropertySetter(readStyleURL), 'visibility': makeObjectPropertySetter(readBoolean), }, makeStructureNS(GX_NAMESPACE_URIS, { @@ -1074,12 +1074,6 @@ function findStyle(styleValue, defaultStyle, sharedStyles) { if (Array.isArray(styleValue)) { return styleValue; } else if (typeof styleValue === 'string') { - // KML files in the wild occasionally forget the leading `#` on styleUrls - // defined in the same document. Add a leading `#` if it enables to find - // a style. - if (!(styleValue in sharedStyles) && '#' + styleValue in sharedStyles) { - styleValue = '#' + styleValue; - } return findStyle(sharedStyles[styleValue], defaultStyle, sharedStyles); } else { return defaultStyle; @@ -1151,6 +1145,28 @@ function readURI(node) { } } +/** + * @param {Node} node Node. + * @return {string} URI. + */ +function readStyleURL(node) { + // KML files in the wild occasionally forget the leading + // `#` on styleUrlsdefined in the same document. + const s = getAllTextContent(node, false) + .trim() + .replace(/^(?!.*#)/, '#'); + let baseURI = node.baseURI; + if (!baseURI || baseURI == 'about:blank') { + baseURI = window.location.href; + } + if (baseURI) { + const url = new URL(s, baseURI); + return url.href; + } else { + return s; + } +} + /** * @param {Element} node Node. * @return {Vec2} Vec2. @@ -2021,7 +2037,7 @@ function regionParser(node, objectStack) { const PAIR_PARSERS = makeStructureNS(NAMESPACE_URIS, { 'Style': makeObjectPropertySetter(readStyle), 'key': makeObjectPropertySetter(readString), - 'styleUrl': makeObjectPropertySetter(readURI), + 'styleUrl': makeObjectPropertySetter(readStyleURL), }); /** diff --git a/test/spec/ol/format/kml.test.js b/test/spec/ol/format/kml.test.js index 0fe434e3f6..b92db81e39 100644 --- a/test/spec/ol/format/kml.test.js +++ b/test/spec/ol/format/kml.test.js @@ -3477,6 +3477,41 @@ describe('ol.format.KML', function () { expect(s.getFill().getColor()).to.eql([120, 86, 52, 18 / 255]); }); + it('can use Styles in StyleMaps if # is missing', function () { + const text = + '' + + ' ' + + ' ' + + ' ' + + ' normal' + + ' foo' + + ' ' + + ' ' + + ' ' + + ' ' + + ' fooMap' + + ' ' + + ' ' + + ''; + const fs = format.readFeatures(text); + expect(fs).to.have.length(1); + const f = fs[0]; + expect(f).to.be.an(Feature); + const styleFunction = f.getStyleFunction(); + expect(styleFunction).not.to.be(undefined); + const styleArray = styleFunction(f, 0); + expect(styleArray).to.be.an(Array); + expect(styleArray).to.have.length(1); + const s = styleArray[0]; + expect(s).to.be.an(Style); + expect(s.getFill()).not.to.be(null); + expect(s.getFill().getColor()).to.eql([120, 86, 52, 18 / 255]); + }); + it('can use IconStyles in StyleMaps before they are defined (and set the crossOrigin option)', function () { format = new KML({crossOrigin: null}); const text =