From 4896337bf775cb129c59ccc4c5ec6354005444b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Thu, 4 Jul 2019 17:44:18 +0200 Subject: [PATCH] Allows to have SVG URL Add an SVG to permalik crosshair Add an included logo Remove no more existing Add example --- .gitignore | 1 + Makefile | 2 +- buildtools/generate-xml-from-tokens.js | 98 +++++++++++++++++ buildtools/svg-viewbox-loader.js | 69 ++++++++++-- buildtools/webpack.commons.js | 14 --- buildtools/webpack.dev.js | 29 +++++ buildtools/webpack.prod.js | 39 +++++++ contribs/gmf/apps/desktop_alt/Controller.js | 20 +++- .../gmf/apps/desktop_alt/image/crosshair.svg | 17 +++ contribs/gmf/apps/desktop_alt/image/logo.png | Bin 7097 -> 0 bytes contribs/gmf/apps/desktop_alt/image/logo.svg | 104 ++++++++++++++++++ contribs/gmf/apps/desktop_alt/index.html.ejs | 2 +- examples/createfeature.js | 3 - examples/font.svg | 80 ++++++++++++++ examples/inline.svg | 79 +++++++++++++ examples/svg.css | 16 +++ examples/svg.html | 27 +++++ examples/svg.js | 75 +++++++++++++ examples/url.svg | 80 ++++++++++++++ 19 files changed, 724 insertions(+), 31 deletions(-) create mode 100644 buildtools/generate-xml-from-tokens.js create mode 100644 contribs/gmf/apps/desktop_alt/image/crosshair.svg delete mode 100644 contribs/gmf/apps/desktop_alt/image/logo.png create mode 100644 contribs/gmf/apps/desktop_alt/image/logo.svg create mode 100644 examples/font.svg create mode 100644 examples/inline.svg create mode 100644 examples/svg.css create mode 100644 examples/svg.html create mode 100644 examples/svg.js create mode 100644 examples/url.svg diff --git a/.gitignore b/.gitignore index b739568994de..ecc983f8e4ea 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ /contribs/gmf/build/ /contribs/gmf/examples/https.js /openlayers_src/ +/dist/ diff --git a/Makefile b/Makefile index c78010e24fc2..1d6edd76dd7c 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ NGEO_EXAMPLES_JS_FILES := $(NGEO_EXAMPLES_HTML_FILES:.html=.js) GMF_PARTIALS_FILES := $(shell find contribs/gmf/src/ -name *.html) GMF_JS_FILES := $(shell find contribs/gmf/src/ -type f -name '*.js') -GMF_ALL_SRC_FILES := $(shell find contribs/gmf/src/ -type f) $(shell find contribs/gmf/src/cursors/ -type f) $(NGEO_ALL_SRC_FILES) +GMF_ALL_SRC_FILES := $(shell find contribs/gmf/src/ -type f) $(NGEO_ALL_SRC_FILES) GMF_TEST_JS_FILES := $(shell find contribs/gmf/test/ -type f -name '*.js') GMF_EXAMPLES_HTML_FILES := $(shell ls -1 contribs/gmf/examples/*.html) GMF_EXAMPLES_JS_FILES := $(GMF_EXAMPLES_HTML_FILES:.html=.js) diff --git a/buildtools/generate-xml-from-tokens.js b/buildtools/generate-xml-from-tokens.js new file mode 100644 index 000000000000..4dcd0f62ad95 --- /dev/null +++ b/buildtools/generate-xml-from-tokens.js @@ -0,0 +1,98 @@ +// Initially get from https://github.com/tildeio/simple-html-tokenizer/blob/v0.1.1/lib/simple-html-tokenizer/generator.js + +const escape = (function() { + const test = /[&<>"'`]/; + const replace = /[&<>"'`]/g; + const map = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''', + '`': '`' + }; + function escapeChar(char) { + return map[char]; + } + return function escape(string) { + if (!test.test(string)) { + return string; + } + return string.replace(replace, escapeChar); + }; +}()); + +function Generator() { + this.escape = escape; +} + +Generator.prototype = { + generate: function(tokens) { + let buffer = ''; + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + buffer += this[token.type](token); + } + return buffer; + }, + + escape: function(text) { + const unsafeCharsMap = this.unsafeCharsMap; + return text.replace(this.unsafeChars, function(char) { + return unsafeCharsMap[char] || char; + }); + }, + + StartTag: function(token) { + let out = '<'; + out += token.tagName; + + if (token.attributes.length) { + out += ' ' + this.Attributes(token.attributes); + } + + out += token.selfClosing ? '/>' : '>'; + + return out; + }, + + EndTag: function(token) { + return ''; + }, + + Chars: function(token) { + return this.escape(token.chars); + }, + + Comment: function(token) { + return ''; + }, + + Attributes: function(attributes) { + const out = []; + + for (let i = 0, l = attributes.length; i < l; i++) { + const attribute = attributes[i]; + + out.push(this.Attribute(attribute[0], attribute[1])); + } + + return out.join(' '); + }, + + Attribute: function(name, value) { + let attrString = name; + + if (value) { + value = this.escape(value); + attrString += '="' + value + '"'; + } + + return attrString; + } +}; + +module.exports = function(tokens) { + const generator = new Generator(); + return generator.generate(tokens); +}; diff --git a/buildtools/svg-viewbox-loader.js b/buildtools/svg-viewbox-loader.js index 577d23e4cc38..95634d8634e2 100644 --- a/buildtools/svg-viewbox-loader.js +++ b/buildtools/svg-viewbox-loader.js @@ -1,32 +1,79 @@ const simpleHTMLTokenizer = require('simple-html-tokenizer'); +const generate = require('./generate-xml-from-tokens.js'); module.exports = function(source) { this.cacheable(true); let tokens = simpleHTMLTokenizer.tokenize(source); tokens = tokens.map((tag) => { - let width = undefined; - let height = undefined; if (tag.type === 'StartTag' && tag.tagName === 'svg') { + let width = undefined; + let height = undefined; + let x = 0; + let y = 0; for (const attribute of tag.attributes) { if (attribute[0] === 'width') { - width = parseFloat(attribute[1]); + try { + width = parseFloat(attribute[1]); + } catch (e) { + console.warn('Unable to read width: ' + attribute[1]); + } } if (attribute[0] === 'height') { - height = parseFloat(attribute[1]); + try { + height = parseFloat(attribute[1]); + } catch (e) { + console.warn('Unable to read height: ' + attribute[1]); + } + } + if (attribute[0] === 'x') { + try { + x = parseFloat(attribute[1]); + } catch (e) { + console.warn('Unable to read x: ' + attribute[1]); + } + } + if (attribute[0] === 'y') { + try { + y = parseFloat(attribute[1]); + } catch (e) { + console.warn('Unable to read y: ' + attribute[1]); + } + } + if (attribute[0] === 'viewBox') { + try { + const attrs = attribute[1].split(' '); + x = parseFloat(attrs[0]); + y = parseFloat(attrs[1]); + width = parseFloat(attrs[2]); + height = parseFloat(attrs[3]); + } catch (e) { + console.warn('Unable to read viewbox: ' + attribute[1]); + } } } if (width !== undefined && height != undefined) { tag.attributes = tag.attributes.filter((attribute) => { - return attribute[0] !== 'width' && attribute[0] != 'height' - }) - tag.attributes.push(['viewBox', `0 0 ${width} ${height}`, true]); - tag.attributes.push(['height', '1em', true]); - tag.attributes.push(['width', `${width / height}em`, true]); + return attribute[0] !== 'width' && attribute[0] != 'height' && attribute[0] != 'viewBox'; + }); + if (x) { + tag.attributes.push(['x', x, true]); + } + if (y) { + tag.attributes.push(['y', y, true]); + } + if (this.resourceQuery.search(/inline/) >= 0) { + tag.attributes.push(['width', width, true]); + tag.attributes.push(['height', height, true]); + } else { + tag.attributes.push(['viewBox', `0 0 ${width} ${height}`, true]); + tag.attributes.push(['height', '1em', true]); + tag.attributes.push(['width', `${width / height}em`, true]); + } } } return tag; - }) + }); - return simpleHTMLTokenizer.generate(tokens) + return generate(tokens); }; diff --git a/buildtools/webpack.commons.js b/buildtools/webpack.commons.js index b399607f9462..a7d0ca142ee8 100644 --- a/buildtools/webpack.commons.js +++ b/buildtools/webpack.commons.js @@ -61,19 +61,6 @@ const htmlRule = { use: 'ejs-loader', }; -const svgRule = { - test: /\.svg$/, - use: [ - { - loader: 'svg-inline-loader', - options: { - removeSVGTagAttrs: false, - }, - }, - './buildtools/svg-viewbox-loader', - 'svgo-loader', - ] -}; function get_comp(firsts, lasts) { return (f1, f2) => { @@ -142,7 +129,6 @@ const config = function(hardSourceConfig, babelLoaderCacheDirectory) { cssRule, sassRule, htmlRule, - svgRule, ngeoRule, otherRule, ] diff --git a/buildtools/webpack.dev.js b/buildtools/webpack.dev.js index db241759887d..313e6f9a0a32 100644 --- a/buildtools/webpack.dev.js +++ b/buildtools/webpack.dev.js @@ -12,6 +12,33 @@ const resourcesRule = { } }; +const svgRule = { + test: /\.svg$/, + oneOf: [{ + resourceQuery: /url/, + use: [ + { + loader: 'file-loader', + options: { + name: '[name].[ext]' + }, + }, + 'svgo-loader', + ] + }, { + use: [ + { + loader: 'svg-inline-loader', + options: { + removeSVGTagAttrs: false, + }, + }, + './buildtools/svg-viewbox-loader', + 'svgo-loader', + ] + }] +}; + new webpack.LoaderOptionsPlugin({ debug: false }); @@ -19,12 +46,14 @@ new webpack.LoaderOptionsPlugin({ module.exports = { mode: 'development', + // devtool: 'eval', output: { filename: '[name].js' }, module: { rules: [ resourcesRule, + svgRule, ] }, }; diff --git a/buildtools/webpack.prod.js b/buildtools/webpack.prod.js index 7b192008dc34..ba3a5386c613 100644 --- a/buildtools/webpack.prod.js +++ b/buildtools/webpack.prod.js @@ -12,6 +12,44 @@ const resourcesRule = { } }; +const svgRule = { + test: /\.svg$/, + oneOf: [{ + resourceQuery: /url/, + use: [ + { + loader: 'file-loader', + options: { + name: '[name].[hash:6].[ext]' + }, + }, + 'svgo-loader', + ] + }, { + resourceQuery: /inline/, + use: [ + { + loader: 'svg-inline-loader', + options: { + removeSVGTagAttrs: false, + }, + }, + 'svgo-loader', + ] + }, { + use: [ + { + loader: 'svg-inline-loader', + options: { + removeSVGTagAttrs: false, + }, + }, + './buildtools/svg-viewbox-loader', + 'svgo-loader', + ] + }] +}; + module.exports = function(TerserPluginCache) { return { mode: 'production', @@ -24,6 +62,7 @@ module.exports = function(TerserPluginCache) { module: { rules: [ resourcesRule, + svgRule, ] }, optimization: { diff --git a/contribs/gmf/apps/desktop_alt/Controller.js b/contribs/gmf/apps/desktop_alt/Controller.js index b7cb4a1bf62a..1cb553c01b86 100644 --- a/contribs/gmf/apps/desktop_alt/Controller.js +++ b/contribs/gmf/apps/desktop_alt/Controller.js @@ -20,7 +20,11 @@ import ngeoRoutingModule from 'ngeo/routing/module.js'; import EPSG2056 from '@geoblocks/proj/src/EPSG_2056.js'; import EPSG21781 from '@geoblocks/proj/src/EPSG_21781.js'; import ngeoStatemanagerWfsPermalink from 'ngeo/statemanager/WfsPermalink.js'; -import {Circle, Fill, Stroke, Style} from 'ol/style'; +import Style from 'ol/style/Style.js'; +import Circle from 'ol/style/Circle.js'; +import Fill from 'ol/style/Fill.js'; +import Stroke from 'ol/style/Stroke.js'; +import Icon from 'ol/style/Icon.js'; import Raven from 'raven-js/src/raven.js'; import RavenPluginsAngular from 'raven-js/plugins/angular.js'; @@ -194,4 +198,18 @@ const module = angular.module('Appdesktop_alt', [ module.controller('AlternativeDesktopController', Controller); + +module.value('gmfPermalinkOptions', /** @type {import('gmf/permalink/Permalink.js').PermalinkOptions} */ ({ + crosshairStyle: [ + new Style({ + image: new Icon({ + src: 'data:image/svg+xml;base64,' + btoa(require('./image/crosshair.svg?inline')), + // Also working + // src: require('./image/crosshair.svg?url'), + imgSize: [22, 22], + }) + }) + ] +})); + export default module; diff --git a/contribs/gmf/apps/desktop_alt/image/crosshair.svg b/contribs/gmf/apps/desktop_alt/image/crosshair.svg new file mode 100644 index 000000000000..ad2c93477f28 --- /dev/null +++ b/contribs/gmf/apps/desktop_alt/image/crosshair.svg @@ -0,0 +1,17 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/contribs/gmf/apps/desktop_alt/image/logo.png b/contribs/gmf/apps/desktop_alt/image/logo.png deleted file mode 100644 index a07d43d5b7a89b72c6b80c6e0500ff634f66055b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7097 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 + + +image/svg+xml diff --git a/contribs/gmf/apps/desktop_alt/index.html.ejs b/contribs/gmf/apps/desktop_alt/index.html.ejs index 8aecd7a461b0..99745c51fcd7 100644 --- a/contribs/gmf/apps/desktop_alt/index.html.ejs +++ b/contribs/gmf/apps/desktop_alt/index.html.ejs @@ -17,7 +17,7 @@
diff --git a/examples/createfeature.js b/examples/createfeature.js index c6048fc9b44b..d7b6e6e421e2 100644 --- a/examples/createfeature.js +++ b/examples/createfeature.js @@ -36,9 +36,6 @@ const module = angular.module('app', [ */ function MainController(ngeoToolActivateMgr) { - /** - * @type {import("ol/Collection.js").default} - */ this.features = new olCollection(); /** diff --git a/examples/font.svg b/examples/font.svg new file mode 100644 index 000000000000..99c8723bdd1a --- /dev/null +++ b/examples/font.svg @@ -0,0 +1,80 @@ + + + + + + + + + + image/svg+xml + + + + + + + + Font + + diff --git a/examples/inline.svg b/examples/inline.svg new file mode 100644 index 000000000000..caa3eeb90551 --- /dev/null +++ b/examples/inline.svg @@ -0,0 +1,79 @@ + + + + + + + + + + image/svg+xml + + + + + + + + Inline + + diff --git a/examples/svg.css b/examples/svg.css new file mode 100644 index 000000000000..5157c7e2617a --- /dev/null +++ b/examples/svg.css @@ -0,0 +1,16 @@ +#map { + width: 400px; + height: 150px; +} +#font2 svg { + font-size: 2rem +} +#font2 circle { + fill: #65b0ff +} +#font4 svg { + font-size: 4rem +} +#font4 circle { + fill: #65b0ff +} diff --git a/examples/svg.html b/examples/svg.html new file mode 100644 index 000000000000..b289c5278a8e --- /dev/null +++ b/examples/svg.html @@ -0,0 +1,27 @@ + + + + SVG example + + + + + +

This example shows different ways to include an SVG in the application using Webpack.

+

In a map:

+
+

In the HTML:

+

Font (2rem): <%=require("./font.svg")%>.

+

Font (4rem): <%=require("./font.svg")%>.

+

Inline (?inline): <%=require("./inline.svg?inline")%>.

+

URL (?url): " />

+

Note for Inkscape, in the document property - Page:

+
    +
  • The default unit should be px.
  • +
  • In Custom size the unit should be px.
  • +
  • The scale should be 1.
  • +
+

Note: in font, and in inline mode, CSS rules can be used.

+ + diff --git a/examples/svg.js b/examples/svg.js new file mode 100644 index 000000000000..81c374bccc43 --- /dev/null +++ b/examples/svg.js @@ -0,0 +1,75 @@ +import angular from 'angular'; +import './svg.css'; +import EPSG21781 from '@geoblocks/proj/src/EPSG_21781.js'; + +import Map from 'ol/Map.js'; +import View from 'ol/View.js'; +import LayerVector from 'ol/layer/Vector.js'; +import SourceVector from 'ol/source/Vector.js'; +import Feature from 'ol/Feature.js'; +import Point from 'ol/geom/Point.js'; +import Style from 'ol/style/Style.js'; +import Icon from 'ol/style/Icon.js'; + +import MapModule from 'ngeo/map/module.js'; + + +/** @type {!angular.IModule} **/ +const appmodule = angular.module('app', [ + MapModule.name, +]); + + +/** + * @constructor + * @ngInject + * @hidden + */ +function MainController() { + const source = new SourceVector(); + const feature1 = new Feature({ + geometry: new Point([599000, 200000]) + }); + feature1.setStyle([new Style({ + image: new Icon({ + // @ts-ignore: For Webpack + src: 'data:image/svg+xml;base64,' + btoa(require('./inline.svg?inline')), + // For IE compatibility + imgSize: [65, 65] + }) + })]); + source.addFeature(feature1); + + const feature2 = new Feature({ + geometry: new Point([601000, 200000]) + }); + feature2.setStyle([new Style({ + image: new Icon({ + // @ts-ignore: For Webpack + src: require('./url.svg?url'), + // For IE compatibility + imgSize: [65, 65] + }) + })]); + source.addFeature(feature2); + + this.map = new Map({ + layers: [ + new LayerVector({ + source + }) + ], + view: new View({ + projection: EPSG21781, + resolutions: [200, 100, 50, 20, 10, 5, 2.5, 2, 1], + center: [600000, 200000], + zoom: 4 + }) + }); +} + + +appmodule.controller('MainController', MainController); + + +export default module; diff --git a/examples/url.svg b/examples/url.svg new file mode 100644 index 000000000000..12e4593221f6 --- /dev/null +++ b/examples/url.svg @@ -0,0 +1,80 @@ + + + + + + + + + + image/svg+xml + + + + + + + + URL + +