diff --git a/Makefile b/Makefile index abac268a71a8..675798de9118 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ ANGULAR_VERSION := $(shell buildtools/get-version.sh angular) -FONTAWESOME_WEBFONT = $(addprefix contribs/gmf/src/fonts/fontawesome-webfont., eot ttf woff woff2) ESLINT_CONFIG_FILES := $(shell find * -not -path 'node_modules/*' -type f -name '.eslintrc*') WEBPACK_CONFIG_FILES := $(shell find . -not -path './node_modules/*' -name 'webpack.*.js') @@ -96,12 +95,7 @@ help: @echo "- help Display this help message" @echo "- serve-ngeo Run a development web server for running the ngeo examples" @echo "- serve-gmf Run a development web server for running the gmf examples" - @echo "- serve-gmf-apps-desktop Run a development web server for running the gmf app desktop" - @echo "- serve-gmf-apps-desktopalt Run a development web server for running the gmf app desktop_alt" - @echo "- serve-gmf-apps-mobile Run a development web server for running the gmf app mobile" - @echo "- serve-gmf-apps-mobilealt Run a development web server for running the gmf app mobile_alt" - @echo "- serve-gmf-apps-oeedit Run a development web server for running the gmf app oeedit" - @echo "- serve-gmf-apps-oeview Run a development web server for running the gmf app oeview" + @echo "- serve-gmf-apps Run a development web server for running the gmf apps" @echo "- examples-hosted Build the hosted examples" @echo "- examples-hosted-ngeo Build the ngeo hosted examples" @echo "- examples-hosted-gmf Build the gmf hosted examples" @@ -174,36 +168,16 @@ test-debug: .build/node_modules.timestamp .build/node_modules_karma-chrome-launc touch $@ .PHONY: serve-ngeo -serve-ngeo: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) +serve-ngeo: .build/node_modules.timestamp $(ANGULAR_LOCALES_FILES) npm run serve-ngeo-examples .PHONY: serve-gmf -serve-gmf: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) +serve-gmf: .build/node_modules.timestamp $(ANGULAR_LOCALES_FILES) npm run serve-gmf-examples -.PHONY: serve-gmf-apps-desktop -serve-gmf-apps-desktop: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=desktop npm run serve-gmf-apps - -.PHONY: serve-gmf-apps-desktopalt -serve-gmf-apps-desktopalt: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=desktop_alt npm run serve-gmf-apps - -.PHONY: serve-gmf-apps-mobile -serve-gmf-apps-mobile: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=mobile npm run serve-gmf-apps - -.PHONY: serve-gmf-apps-mobilealt -serve-gmf-apps-mobilealt: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=mobile_alt npm run serve-gmf-apps - -.PHONY: serve-gmf-apps-oeedit -serve-gmf-apps-oeedit: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=oeedit npm run serve-gmf-apps - -.PHONY: serve-gmf-apps-oeview -serve-gmf-apps-oeview: .build/node_modules.timestamp $(FONTAWESOME_WEBFONT) $(ANGULAR_LOCALES_FILES) - APP=oeview npm run serve-gmf-apps +.PHONY: serve-gmf-apps +serve-gmf-apps: .build/node_modules.timestamp $(ANGULAR_LOCALES_FILES) + npm run serve-gmf-apps .PHONY: examples-hosted examples-hosted: \ @@ -229,12 +203,7 @@ examples-hosted-gmf: .build/examples-gmf.timestamp .build/examples-hosted/contri examples-hosted-apps: .build/gmf-apps.timestamp .build/examples-hosted-gmf-apps-deps.timestamp .build/gmf-apps.timestamp: $(GMF_APPS_ALL_SRC_FILES) $(WEBPACK_CONFIG_FILES) .build/node_modules.timestamp - APP=desktop npm run build-gmf-apps - APP=desktop_alt npm run build-gmf-apps - APP=mobile npm run build-gmf-apps - APP=mobile_alt npm run build-gmf-apps - APP=oeedit npm run build-gmf-apps - APP=oeview npm run build-gmf-apps + npm run build-gmf-apps touch $@ .PHONY: gh-pages @@ -260,7 +229,7 @@ gh-pages: .build/python-venv.timestamp # We need the files for each app # To simplify processing, we first copy them in gmfappsdeps directory, then from there to each app $(foreach f,$^,mkdir -p .build/examples-hosted/gmfappsdeps/`dirname $(f)`; cp $(f) .build/examples-hosted/gmfappsdeps/$(f);) - $(foreach app, $(GMF_APPS), rsync --recursive .build/examples-hosted/gmfappsdeps/contribs/gmf/ .build/examples-hosted/contribs/gmf/apps/$(app)/;) + rsync --recursive .build/examples-hosted/gmfappsdeps/contribs/gmf/ .build/examples-hosted/contribs/gmf/apps/;) touch $@ .build/examples-hosted/index.html: \ @@ -307,7 +276,7 @@ gh-pages: .build/python-venv.timestamp ./node_modules/.bin/phantomjs --local-to-remote-url-access=true buildtools/check-example.js $< touch $@ -.build/contribs/gmf/apps/%.check.timestamp: .build/examples-hosted/contribs/gmf/apps/%/index.html +.build/contribs/gmf/apps/%.check.timestamp: .build/examples-hosted/contribs/gmf/apps/%.html mkdir -p $(dir $@) ./node_modules/.bin/phantomjs --local-to-remote-url-access=true buildtools/check-example.js $< touch $@ @@ -317,14 +286,6 @@ gh-pages: .build/python-venv.timestamp mkdir -p $(dir $@) touch $@ -.PRECIOUS: node_modules/font-awesome/fonts/fontawesome-webfont.% -node_modules/font-awesome/fonts/fontawesome-webfont.%: .build/node_modules.timestamp - touch -c $@ - -contribs/gmf/src/fonts/fontawesome-webfont.%: node_modules/font-awesome/fonts/fontawesome-webfont.% - mkdir -p $(dir $@) - cp $< $@ - contribs/gmf/build/angular-locale_%.js: package.json mkdir -p $(dir $@) wget -O $@ https://raw.githubusercontent.com/angular/angular.js/v$(ANGULAR_VERSION)/src/ngLocale/angular-locale_$*.js @@ -470,8 +431,6 @@ clean: rm -f .build/locale/demo.pot rm -rf contribs/gmf/build rm -f $(ANGULAR_LOCALES_FILES) - rm -f contribs/gmf/src/fonts/FontAwesome.otf - rm -f contribs/gmf/src/fonts/fontawesome-webfont.* rm -f contribs/gmf/src/fonts/gmf-icons.eot rm -f contribs/gmf/src/fonts/gmf-icons.ttf rm -f contribs/gmf/src/fonts/gmf-icons.woff diff --git a/buildtools/webpack.commons.js b/buildtools/webpack.commons.js index d9526000d2c9..608c586d9565 100644 --- a/buildtools/webpack.commons.js +++ b/buildtools/webpack.commons.js @@ -144,9 +144,33 @@ const config = { plugins: [ providePlugin, new SassPlugin({ - //filename: devMode ? '[name].css' : '[name].[hash:6].css', - filename: devMode ? 'all.css' : '[name].[hash:6].css', + filename: devMode ? '[name].css' : '[name].[hash:6].css', assetname: '[name].[hash:6].[ext]', + //tempfile: '/tmp/t.scss', + blacklistedChunks: ['commons'], + filesOrder: (chunk, chunksFiles) => { + const files = chunksFiles.commons + ? chunksFiles[chunk.name].concat(chunksFiles.commons) + : chunksFiles[chunk.name]; + files.sort((f1, f2) => { + for (const reg of [ + '/apps/', + '/controllers/', + '/vars.scss', + '/vars_only.scss', + '/common_dependencies.scss', + ]) { + if (f1.indexOf(reg) >= 0) { + return -1; + } + if (f2.indexOf(reg) >= 0) { + return 1; + } + } + return 0; + }); + return files; + } }), new webpack.IgnorePlugin(/^\.\/locale$/, /node_modules\/moment\/src\/lib\/locale$/), ], diff --git a/buildtools/webpack.gmfapps.js b/buildtools/webpack.gmfapps.js index b924ed5cbc28..62b58ae7cd9c 100644 --- a/buildtools/webpack.gmfapps.js +++ b/buildtools/webpack.gmfapps.js @@ -1,31 +1,26 @@ const path = require('path'); +const ls = require('ls'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -const HtmlWebpackIncludeAssetsPlugin = require('html-webpack-include-assets-plugin'); const plugins = []; const entry = {}; const filenamePrefix = process.env.DEV_SERVER ? 'contribs/gmf/apps/' : ''; -const name = process.env.APP; - -const folder = `contribs/gmf/apps/${name}`; -entry[name] = `./${folder}/Controller.js`; -plugins.push( - new HtmlWebpackPlugin({ - template: `${folder}/index.html.ejs`, - inject: false, - chunksSortMode: 'manual', - filename: `${filenamePrefix}${name}.html`, - chunks: ['commons', name] - }) -); -plugins.push( - new HtmlWebpackIncludeAssetsPlugin({ - assets: ['all.css'], - append: true, - }) -); +for (const filename of ls('contribs/gmf/apps/*/index.html.ejs')) { + const name = path.basename(filename.path); + const folder = `contribs/gmf/apps/${name}`; + entry[name] = `./${folder}/Controller.js`; + plugins.push( + new HtmlWebpackPlugin({ + template: `${folder}/index.html.ejs`, + inject: false, + chunksSortMode: 'manual', + filename: `${filenamePrefix}${name}.html`, + chunks: ['commons', name] + }) + ); +} module.exports = { entry: entry, diff --git a/buildtools/webpack.plugin.js b/buildtools/webpack.plugin.js index 3cfbf3613d12..75c8a5d75671 100644 --- a/buildtools/webpack.plugin.js +++ b/buildtools/webpack.plugin.js @@ -55,7 +55,7 @@ function getImportsToResolve(original, includePaths, transformers) { } -const cache = []; +let cache; function * mergeSources(opts, entry, resolve, level) { level = level || 0; @@ -208,175 +208,223 @@ function resolver(ctx) { }; } -class SassPlugin { - constructor(options) { - this.options = options; - } - - apply(compiler) { - compiler.plugin('emit', (compilation, callback) => { - let usedContext; - const promise = new Promise((resolve, reject) => { - try { - const contents = []; - const browse = function(position) { - if (position < sassLoader.entries.length) { - const entry = sassLoader.entries[position]; - if (!usedContext) { - usedContext = entry.ctx; - } - - const merged = mergeSources(entry.options, { - file: entry.entry, - content: entry.content - }, resolver(entry.ctx)); - const merged2 = []; - for (const content of merged) { - merged2.push(content); - } - assert.strictEqual(merged2.length, 1); - merged2[0].then((content) => { - contents.push(content); - position++; - browse(position); - }, () => { - reject(`${position}, ${entry.entry}`); - }); +function fillDependency(pluginOptions, usedContext, compilation, assetName, assetUrl, queryString, replacements) { + return (resolve, reject) => { + if (assetUrl.startsWith('~')) { + usedContext.resolve(usedContext.resourcePath, assetName, (err, resolvedFile) => { + if (err) { + console.log(err); + reject(err); + } else { + fs.readFile(resolvedFile, 'utf8', (err, data) => { + if (err) { + console.log(err); + reject(err); } else { - resolve(contents); + usedContext.resourcePath = assetName; + const name = loaderUtils.interpolateName(usedContext, pluginOptions.assetname, { + content: data + }); + compilation.assets[name] = { + source: () => data, + size: () => data.length + }; + replacements[assetUrl] = name + queryString; + resolve(); } + }); + } + }); + } else { + fs.readFile(assetName, 'utf8', (err, data) => { + if (err) { + console.log(err); + reject(err); + } else { + usedContext.resourcePath = assetName; + const name = loaderUtils.interpolateName(usedContext, pluginOptions.assetname, { + content: data + }); + compilation.assets[name] = { + source: () => data, + size: () => data.length }; - browse(0); - } catch (e) { - console.error(e.stack || e); - reject(e); + replacements[assetUrl] = name + queryString; + resolve(); } }); + } + }; +} - const pluginOptions = this.options; - promise.then(async (contents) => { - if (pluginOptions.tempfile) { - fs.writeFile(pluginOptions.tempfile, contents.join('\n')); - } +function manageContent(pluginOptions, usedContext, compilation, chunk, resolve) { + return async (contents) => { + if (pluginOptions.tempfile) { + fs.writeFile(pluginOptions.tempfile, contents); + } + try { + const replacements = {}; + const promises = []; + const options = Object.assign( + {}, pluginOptions.sassConfig, { + data: contents, + functions: {}, + } + ); + // Double parse the Sass files to be able to return in a synchronous function things + // that we can only get asynchronously. + const preparseOptions = Object.assign({}, options); + preparseOptions.functions['url($url)'] = function(url) { + if (url.getValue().startsWith('data:')) { + return url; + } try { - const replacements = {}; - const promises = []; - const options = Object.assign( - {}, pluginOptions.sassConfig, { - data: contents.join('\n'), - functions: {}, - } - ); - // Double parse the Sass files to be able to return in a synchronous function things - // that we can only get asynchronously. - const preparseOptions = Object.assign({}, options); - preparseOptions.functions['url($url)'] = function(url) { - if (url.getValue().startsWith('data:')) { - return url; - } - try { - const assetUrl = url.getValue(); - let assetName = url.getValue().substr(1); - let queryString = ''; - const questionMarkIndex = assetName.indexOf('?'); - if (questionMarkIndex > 0) { - queryString = assetName.substr(questionMarkIndex); - assetName = assetName.substr(0, questionMarkIndex); - } else { - const sharpIndex = assetName.indexOf('#'); - if (sharpIndex > 0) { - queryString = assetName.substr(sharpIndex); - assetName = assetName.substr(0, sharpIndex); - } - } - - promises.push(new Promise((resolve, reject) => { - if (assetUrl.startsWith('~')) { - usedContext.resolve(usedContext.resourcePath, assetName, (err, resolvedFile) => { - if (err) { - console.log(err); - reject(err); - } else { - fs.readFile(resolvedFile, 'utf8', (err, data) => { - if (err) { - console.log(err); - reject(err); - } else { - usedContext.resourcePath = assetName; - const name = loaderUtils.interpolateName(usedContext, pluginOptions.assetname, { - content: data - }); - compilation.assets[name] = { - source: () => data, - size: () => data.length - }; - replacements[assetUrl] = name + queryString; - resolve(); - } - }); - } - }); - } else { - fs.readFile(assetName, 'utf8', (err, data) => { - if (err) { - console.log(err); - reject(err); - } else { - usedContext.resourcePath = assetName; - const name = loaderUtils.interpolateName(usedContext, pluginOptions.assetname, { - content: data - }); - compilation.assets[name] = { - source: () => data, - size: () => data.length - }; - replacements[assetUrl] = name + queryString; - resolve(); - } - }); - } - })); - } catch (e) { - console.error(e.stack || e); - } - return url; - }; - const originalResourcePath = usedContext.resourcePath; - nodeSass.renderSync(preparseOptions); - usedContext.resourcePath = originalResourcePath; - await Promise.all(promises); - const parseOptions = Object.assign({}, options); - parseOptions.functions['url($url)'] = function(url) { - const assetUrl = url.getValue(); - if (assetUrl.startsWith('data:')) { - return url; + const assetUrl = url.getValue(); + let assetName = url.getValue().substr(1); + let queryString = ''; + const questionMarkIndex = assetName.indexOf('?'); + if (questionMarkIndex > 0) { + queryString = assetName.substr(questionMarkIndex); + assetName = assetName.substr(0, questionMarkIndex); + } else { + const sharpIndex = assetName.indexOf('#'); + if (sharpIndex > 0) { + queryString = assetName.substr(sharpIndex); + assetName = assetName.substr(0, sharpIndex); } - return nodeSass.types.String(`url(${replacements[assetUrl]})`); - }; - const result = nodeSass.renderSync(parseOptions); - const content = result.css; - const srcmap = result.map; - const asset = { - source: () => content, - size: () => content.length - }; - const assetName = loaderUtils.interpolateName(usedContext, pluginOptions.filename, asset); - compilation.assets[assetName] = asset; - if (srcmap) { - compilation.assets[`${assetName}.map`] = { - source: () => srcmap, - size: () => srcmap.length - }; } - callback(); + + promises.push(new Promise(fillDependency(pluginOptions, usedContext, compilation, assetName, assetUrl, queryString, replacements))); } catch (e) { console.error(e.stack || e); - callback(); } - }, (error) => { - callback(`SCSS dependencies error, ${error}`); + return url; + }; + const originalResourcePath = usedContext.resourcePath; + nodeSass.renderSync(preparseOptions); + await Promise.all(promises); + const parseOptions = Object.assign({}, options); + parseOptions.functions['url($url)'] = function(url) { + const assetUrl = url.getValue(); + if (assetUrl.startsWith('data:')) { + return url; + } + return nodeSass.types.String(`url(${replacements[assetUrl]})`); + }; + const result = nodeSass.renderSync(parseOptions); + const content = result.css; + const srcmap = result.map; + const asset = { + source: () => content, + size: () => content.length + }; + usedContext.resourcePath = `/${chunk.name}`; + const assetName = loaderUtils.interpolateName(usedContext, pluginOptions.filename, { + content: content, }); + compilation.assets[assetName] = asset; + chunk.files.push(assetName); + if (srcmap) { + compilation.assets[`${assetName}.map`] = { + source: () => srcmap, + size: () => srcmap.length + }; + chunk.files.push(`${assetName}.map`); + } + usedContext.resourcePath = originalResourcePath; + resolve(); + } catch (e) { + console.error(e.stack || e); + } + }; +} + +function processAsset(files) { + return (resolve, reject) => { + try { + const contents = []; + const browse = function(position) { + if (position < files.length) { + const file = files[position]; + const entry = sassLoader.entries[file]; + if (entry) { + const merged = mergeSources(entry.options, { + file: file, + content: entry.content + }, resolver(entry.ctx)); + const merged2 = []; + for (const content of merged) { + merged2.push(content); + } + assert.strictEqual(merged2.length, 1); + merged2[0].then((content) => { + contents.push(content); + position++; + browse(position); + }, () => { + reject(`${position}, ${file}`); + }); + } + } else { + resolve(contents.join('\n')); + } + }; + browse(0); + } catch (e) { + console.error(e.stack || e); + reject(e); + } + }; +} + +class SassPlugin { + constructor(options) { + this.options = options; + } + + apply(compiler) { + // compiler.hooks.emit.taplAsync('SassPlugin', async (compilation, callback) => { + compiler.plugin('emit', async (compilation, callback) => { + const chunksFiles = {}; + for (const chunk of compilation.chunks) { + chunksFiles[chunk.name] = []; + const files = chunksFiles[chunk.name]; + const browse = (module) => { + if (module.children) { + for (const child of module.children) { + browse(child); + } + } else { + if (module.resource && module.resource.endsWith('.scss')) { + files.push(module.resource); + } + } + }; + for (const module of chunk.modulesIterable) { + browse(module); + } + } + for (const chunk of compilation.chunks) { + cache = []; + const pluginOptions = this.options; + const files = pluginOptions.filesOrder + ? pluginOptions.filesOrder(chunk, chunksFiles) + : chunksFiles[chunk.name]; + if ((!pluginOptions.blacklistedChunks || pluginOptions.blacklistedChunks.indexOf(chunk.name) < 0) + && files.length > 0) { + const promise = new Promise((resolve, reject) => { + const usedContext = files.length > 0 ? sassLoader.entries[files[0]].ctx : undefined; + const promise = new Promise(processAsset(files)); + + promise.then(manageContent(pluginOptions, usedContext, compilation, chunk, resolve), (error) => { + callback(`SCSS dependencies error, ${error}`); + }); + }); + await Promise.all([promise]); + } + } + callback(); }); } } diff --git a/buildtools/webpack.scss-loader.js b/buildtools/webpack.scss-loader.js index af6d4ef4e890..c678b00b08f1 100644 --- a/buildtools/webpack.scss-loader.js +++ b/buildtools/webpack.scss-loader.js @@ -1,6 +1,6 @@ 'use strict'; -const entries = []; +const entries = {}; const loaderUtils = require('loader-utils'); const path = require('path'); @@ -43,12 +43,12 @@ function getLoaderConfig(ctx) { } module.exports = function(content) { - entries.push({ + entries[this.resourcePath] = { 'content': content, - 'entry': this.resourcePath, 'options': getLoaderConfig(this), 'ctx': this, - }); + }; + this.dependency(this.resourcePath); return ''; }; diff --git a/contribs/gmf/apps/desktop/Controller.js b/contribs/gmf/apps/desktop/Controller.js index 8a346db86098..04c2814c46c7 100644 --- a/contribs/gmf/apps/desktop/Controller.js +++ b/contribs/gmf/apps/desktop/Controller.js @@ -8,8 +8,8 @@ * by the HTML page and the controller to provide the configuration. */ -import gmfControllersAbstractDesktopController from 'gmf/controllers/AbstractDesktopController.js'; import 'gmf/controllers/desktop.scss'; +import gmfControllersAbstractDesktopController from 'gmf/controllers/AbstractDesktopController.js'; import appBase from '../appmodule.js'; import ngeoProjEPSG2056 from 'ngeo/proj/EPSG2056.js'; import ngeoProjEPSG21781 from 'ngeo/proj/EPSG21781.js'; diff --git a/contribs/gmf/examples/common_dependencies.js b/contribs/gmf/examples/common_dependencies.js index bbe01498fcff..575be6b45a52 100644 --- a/contribs/gmf/examples/common_dependencies.js +++ b/contribs/gmf/examples/common_dependencies.js @@ -1,3 +1,4 @@ +import 'gmf/sass/vars.scss' import 'jquery'; import 'angular'; import 'angular-gettext'; diff --git a/contribs/gmf/src/contextualdata/contextualdata.scss b/contribs/gmf/src/contextualdata/contextualdata.scss index c609ef056754..cbedeb70cd50 100644 --- a/contribs/gmf/src/contextualdata/contextualdata.scss +++ b/contribs/gmf/src/contextualdata/contextualdata.scss @@ -1,3 +1,4 @@ +@import '~gmf/sass/vars.scss'; .popover.gmf-contextualdata { width: 25rem; diff --git a/contribs/gmf/src/controllers/desktop.scss b/contribs/gmf/src/controllers/desktop.scss index 6edbc295f9cc..3f8d6819b4c3 100644 --- a/contribs/gmf/src/controllers/desktop.scss +++ b/contribs/gmf/src/controllers/desktop.scss @@ -13,7 +13,7 @@ $padding-base-horizontal: 0.62rem !default; $form-group-margin-bottom: 0.62rem !default; $search-results-max-height: calc(100vh - $topbar-height + $map-tools-size + (2 * $app-margin)) !default; -@import '~gmf/sass/vars.scss'; +@import '~gmf/sass/vars_only.scss'; $border-color: darken($brand-primary, $standard-variation) !default; diff --git a/contribs/gmf/src/controllers/mobile.scss b/contribs/gmf/src/controllers/mobile.scss index 027286ce8e5a..e804ca3ddb42 100644 --- a/contribs/gmf/src/controllers/mobile.scss +++ b/contribs/gmf/src/controllers/mobile.scss @@ -3,10 +3,9 @@ */ $map-tools-size: 2.50rem !default; -$search-width: 6 * $map-tools-size !default; $border-color: black !default; -@import '~gmf/sass/vars.scss'; +@import '~gmf/sass/vars_only.scss'; @import "~bootstrap/scss/_functions.scss"; @import "~bootstrap/scss/_variables.scss"; diff --git a/contribs/gmf/src/import/import.scss b/contribs/gmf/src/import/import.scss index 05348fbe09e3..d2c87ec711c4 100644 --- a/contribs/gmf/src/import/import.scss +++ b/contribs/gmf/src/import/import.scss @@ -1,4 +1,4 @@ -@import "~font-awesome/scss/_variables.scss"; +@import '~gmf/sass/vars.scss'; @import "~gmf/sass/typeahead.scss"; gmf-importdatasource { diff --git a/contribs/gmf/src/layertree/timeslider.scss b/contribs/gmf/src/layertree/timeslider.scss index 989c03931cc5..a75c725c3603 100644 --- a/contribs/gmf/src/layertree/timeslider.scss +++ b/contribs/gmf/src/layertree/timeslider.scss @@ -1,3 +1,4 @@ +@import '~gmf/sass/vars.scss'; @import '~gmf/sass/input-range.scss'; .gmf-time-slider { diff --git a/contribs/gmf/src/query/grid.scss b/contribs/gmf/src/query/grid.scss index 60a281d9c2cd..9969f97f1908 100644 --- a/contribs/gmf/src/query/grid.scss +++ b/contribs/gmf/src/query/grid.scss @@ -1,3 +1,4 @@ +@import '~gmf/sass/vars.scss'; $grid-height: 15.62rem; $table-height: $grid-height - $app-margin - 2 * $map-tools-size; diff --git a/contribs/gmf/src/query/window.scss b/contribs/gmf/src/query/window.scss index be46d03c3e47..88badb739154 100644 --- a/contribs/gmf/src/query/window.scss +++ b/contribs/gmf/src/query/window.scss @@ -1,3 +1,4 @@ +@import '~gmf/sass/vars.scss'; $displayquerywindow-tablet-width: 8 * $map-tools-size; $displayquerywindow-detailed-header-height: 3.12rem; diff --git a/contribs/gmf/src/sass/font.scss b/contribs/gmf/src/sass/font.scss index b929c9c42194..199672d2c197 100644 --- a/contribs/gmf/src/sass/font.scss +++ b/contribs/gmf/src/sass/font.scss @@ -1,3 +1,5 @@ +@import '~gmf/sass/vars.scss'; + /** * Fonts definition */ @@ -12,5 +14,4 @@ font-style: normal; } -$fa-font-path: "~font-awesome/fonts"; @import "~font-awesome/scss/font-awesome.scss"; diff --git a/contribs/gmf/src/sass/fullscreenpopup.scss b/contribs/gmf/src/sass/fullscreenpopup.scss index e41e92f27fdf..091cac4981dc 100644 --- a/contribs/gmf/src/sass/fullscreenpopup.scss +++ b/contribs/gmf/src/sass/fullscreenpopup.scss @@ -1,3 +1,5 @@ +@import '~gmf/sass/vars.scss'; + [ngeo-popup] { &.popover { position: fixed; diff --git a/contribs/gmf/src/sass/iphone.scss b/contribs/gmf/src/sass/iphone.scss index 8a268316d74b..ee1bd6af1547 100644 --- a/contribs/gmf/src/sass/iphone.scss +++ b/contribs/gmf/src/sass/iphone.scss @@ -1,3 +1,5 @@ +@import '~gmf/sass/vars.scss'; + // Hack for ios Safari browser (UI overlapping on iOS 10) @media all and (orientation: landscape) { $ios-margin: 3.12rem; diff --git a/contribs/gmf/src/sass/map.scss b/contribs/gmf/src/sass/map.scss index d9aa31ee3cfb..ea02134d4893 100644 --- a/contribs/gmf/src/sass/map.scss +++ b/contribs/gmf/src/sass/map.scss @@ -1,3 +1,5 @@ +@import '~gmf/sass/vars.scss'; + /** * Styles for the map and OL3 controls. */ diff --git a/contribs/gmf/src/sass/popover.scss b/contribs/gmf/src/sass/popover.scss index 06745ba50a5d..d88a409cfd26 100644 --- a/contribs/gmf/src/sass/popover.scss +++ b/contribs/gmf/src/sass/popover.scss @@ -1,3 +1,5 @@ +@import '~gmf/sass/vars.scss'; + $popover-nb-col : 12; $popover-icon-max-width : ($popover-max-width / $popover-nb-col) * 3; $popover-action-name-max-width : ($popover-max-width / $popover-nb-col) * 5; diff --git a/contribs/gmf/src/sass/typeahead.scss b/contribs/gmf/src/sass/typeahead.scss index 577582b11065..05a2c7c45dbb 100644 --- a/contribs/gmf/src/sass/typeahead.scss +++ b/contribs/gmf/src/sass/typeahead.scss @@ -1,3 +1,4 @@ +@import '~gmf/sass/vars.scss'; .twitter-typeahead { width: 100%; diff --git a/contribs/gmf/src/sass/vars.scss b/contribs/gmf/src/sass/vars.scss index 798d129d5c49..ccf0afc9ce6f 100644 --- a/contribs/gmf/src/sass/vars.scss +++ b/contribs/gmf/src/sass/vars.scss @@ -1,46 +1,5 @@ -$brand-primary: #94ac9a !default; -$brand-secondary: #d3e5d7 !default; -$primary: $brand-primary; -$secondary: $brand-secondary; -$font-size-small: 0.9em !default; +@import '~gmf/sass/vars_only.scss'; -$app-margin: 0.62rem !default; -$half-app-margin: 0.31rem !default; -$micro-app-margin: 0.12rem !default; -$standard-variation: 15% !default; -$nav-bg: white !default; -$color: #555 !default; -$color-light: lighten($color, $standard-variation); -$nav-header-bg: darken($nav-bg, 50%) !default; -$link-color: hsl(hue($brand-primary), 40%, 60%) !default; -$map-tools-bg-color: white !default; -$map-tools-color: black !default; -$onhover-color: darken($nav-bg, $standard-variation) !default; -$main-bg-color: #e2e3df !default; // grey light - - -// Z-indexes -$below-content-index: 1; -$content-index: 2; -$above-content-index: 3; -$above-menus-index: 4; -$search-index: 5; -$above-search-index: 6; -$zindex-navbar-fixed: 7; -$above-all: 9999; - - -$nav-width: 20rem !default; - -$border-radius-base: 2px !default; -$border-radius-small: 1px !default; -$input-border-focus: darken($brand-primary, $standard-variation) !default; - -// Bootstrap 3 compatibility layer -$gray-base: #000 !default; -$gray-dark: lighten($gray-base, 20%) !default; // #333 -$padding-small-vertical: 0.36rem !default; -$padding-small-horizontal: 0.72rem !default; -$input-height-base: 1.5rem !default; -$btn-default-border: #ccc !default; -$text-color: $gray-dark !default; +@import "~bootstrap/scss/_functions.scss"; +@import "~bootstrap/scss/_variables.scss"; +@import "~font-awesome/scss/_variables.scss"; diff --git a/contribs/gmf/src/sass/vars_only.scss b/contribs/gmf/src/sass/vars_only.scss new file mode 100644 index 000000000000..f3d48bce833d --- /dev/null +++ b/contribs/gmf/src/sass/vars_only.scss @@ -0,0 +1,50 @@ +$brand-primary: #94ac9a !default; +$brand-secondary: #d3e5d7 !default; +$primary: $brand-primary; +$secondary: $brand-secondary; +$font-size-small: 0.9em !default; + +$app-margin: 0.62rem !default; +$half-app-margin: 0.31rem !default; +$micro-app-margin: 0.12rem !default; +$standard-variation: 15% !default; +$nav-bg: white !default; +$color: #555 !default; +$color-light: lighten($color, $standard-variation); +$nav-header-bg: darken($nav-bg, 50%) !default; +$link-color: hsl(hue($brand-primary), 40%, 60%) !default; +$map-tools-size: 2rem !default; +$map-tools-bg-color: white !default; +$map-tools-color: black !default; +$onhover-color: darken($nav-bg, $standard-variation) !default; +$main-bg-color: #e2e3df !default; // grey light +$search-width: 6 * $map-tools-size !default; + + +// Z-indexes +$below-content-index: 1; +$content-index: 2; +$above-content-index: 3; +$above-menus-index: 4; +$search-index: 5; +$above-search-index: 6; +$zindex-navbar-fixed: 7; +$above-all: 9999; + + +$nav-width: 20rem !default; + +$border-radius-base: 2px !default; +$border-radius-small: 1px !default; +$input-border-focus: darken($brand-primary, $standard-variation) !default; + +$fa-font-path: "~font-awesome/fonts"; + +// Bootstrap 3 compatibility layer +$gray-base: #000 !default; +$gray-dark: lighten($gray-base, 20%) !default; // #333 +$padding-small-vertical: 0.36rem !default; +$padding-small-horizontal: 0.72rem !default; +$input-height-base: 1.5rem !default; +$btn-default-border: #ccc !default; +$text-color: $gray-dark !default; diff --git a/contribs/gmf/src/search/search.scss b/contribs/gmf/src/search/search.scss index e51918ff2284..d6236527cb24 100644 --- a/contribs/gmf/src/search/search.scss +++ b/contribs/gmf/src/search/search.scss @@ -1,4 +1,4 @@ -@import "~font-awesome/scss/_variables.scss"; +@import '~gmf/sass/vars.scss'; @import "~gmf/sass/typeahead.scss"; $search-results-max-height: calc(100vh - 6 * $app-margin); diff --git a/contribs/gmf/test/spec/all.js b/contribs/gmf/test/spec/all.js index 532665071438..e629e75fb8bd 100644 --- a/contribs/gmf/test/spec/all.js +++ b/contribs/gmf/test/spec/all.js @@ -1,3 +1,4 @@ +import 'gmf/sass/vars.scss'; import './beforeeach.js'; import './controllers/gmfprintcontroller.spec.js'; import './services/share.spec.js'; diff --git a/examples/common_dependencies.js b/examples/common_dependencies.js index 21c47d2b4d76..7f32b4be1d13 100644 --- a/examples/common_dependencies.js +++ b/examples/common_dependencies.js @@ -1,3 +1,4 @@ +import './common_dependencies.scss' import 'jquery'; import 'angular'; import 'angular-gettext'; diff --git a/examples/common_dependencies.scss b/examples/common_dependencies.scss new file mode 100644 index 000000000000..2b49d44234e5 --- /dev/null +++ b/examples/common_dependencies.scss @@ -0,0 +1 @@ +$fa-font-path: "~font-awesome/fonts";