From eea0c297bfad3d0c01d566fe09240f4ba1526e54 Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Tue, 17 Sep 2024 18:15:33 +0800 Subject: [PATCH] added leaflet service to manage loading and initialization of leaflet to prevent duplicate initializations --- addon/services/leaflet.js | 42 +++++++++++++++++++++++++++++ addon/utils/load-assets.js | 6 ++++- addon/utils/load-leaflet-plugins.js | 4 +-- app/services/leaflet.js | 1 + index.js | 24 ++++++++++++++++- package.json | 2 +- tests/unit/services/leaflet-test.js | 12 +++++++++ 7 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 addon/services/leaflet.js create mode 100644 app/services/leaflet.js create mode 100644 tests/unit/services/leaflet-test.js diff --git a/addon/services/leaflet.js b/addon/services/leaflet.js new file mode 100644 index 0000000..7786acb --- /dev/null +++ b/addon/services/leaflet.js @@ -0,0 +1,42 @@ +import Service from '@ember/service'; +import { tracked } from '@glimmer/tracking'; +import { debug } from '@ember/debug'; + +export default class LeafletService extends Service { + @tracked instances = []; + @tracked initialized = false; + @tracked instance; + @tracked initializationId; + + load() { + let intervals = 0; + this.initializationId = setInterval(() => { + const Leaflet = window.L || window.leaflet; + // Check if Leaflet global object `L` is present + if (Leaflet && typeof Leaflet === 'object') { + if (!this.initialized) { + // First initialization + debug('Leaflet has been initialized.'); + if (this.instance === undefined) { + this.instance = Leaflet; + window.L = Leaflet; + } + this.initialized = true; + } else if (Leaflet !== this.instance && !this.instances.includes(Leaflet)) { + // Subsequent re-initializations + debug('Leaflet has been re-initialized!'); + this.instances.push(window.L); + } + } + + intervals++; + if (intervals === 5) { + clearTimeout(this.initializationId); + } + }, 100); + } + + getInstance() { + return this.instance || window.L || window.leaflet; + } +} diff --git a/addon/utils/load-assets.js b/addon/utils/load-assets.js index ce07383..6220a3c 100644 --- a/addon/utils/load-assets.js +++ b/addon/utils/load-assets.js @@ -1,6 +1,6 @@ import { later } from '@ember/runloop'; -export default function loadAssets(assets = { basePath: '', scripts: [], stylesheets: [], globalIndicatorKey: null }) { +export default function loadAssets(assets = { basePath: '', scripts: [], stylesheets: [], globalIndicatorKey: null }, callback = null) { // Set global indicator key if applicable if (assets.globalIndicatorKey && typeof assets.globalIndicatorKey === 'string') { window[assets.globalIndicatorKey] = false; @@ -36,6 +36,10 @@ export default function loadAssets(assets = { basePath: '', scripts: [], stylesh if (assets.globalIndicatorKey && typeof assets.globalIndicatorKey === 'string') { window[assets.globalIndicatorKey] = true; } + + if (typeof callback === 'function') { + callback(); + } }, 300 ); diff --git a/addon/utils/load-leaflet-plugins.js b/addon/utils/load-leaflet-plugins.js index 87f087e..3e14214 100644 --- a/addon/utils/load-leaflet-plugins.js +++ b/addon/utils/load-leaflet-plugins.js @@ -1,6 +1,6 @@ import loadAssets from './load-assets'; -export default function loadLeafletPlugins(assets = { basePath: null, scripts: [], stylesheets: [], globalIndicatorKey: null }) { +export default function loadLeafletPlugins(assets = { basePath: null, scripts: [], stylesheets: [], globalIndicatorKey: null }, callback = null) { const basePath = assets.basePath ?? 'engines-dist/leaflet'; - loadAssets({ basePath, ...assets }); + loadAssets({ basePath, ...assets }, callback); } diff --git a/app/services/leaflet.js b/app/services/leaflet.js new file mode 100644 index 0000000..c7d36b7 --- /dev/null +++ b/app/services/leaflet.js @@ -0,0 +1 @@ +export { default } from '@fleetbase/ember-ui/services/leaflet'; diff --git a/index.js b/index.js index 723112f..5c05bf7 100644 --- a/index.js +++ b/index.js @@ -53,10 +53,18 @@ module.exports = { included: function (app) { this._super.included.apply(this, arguments); + // Get host application + if (typeof this._findHost === 'function') { + app = this._findHost(); + } else { + app = this._findHostFallback(); + } + // PostCSS app.options = app.options || {}; app.options.postcssOptions = postcssOptions; + // Import leaflet-src if (!app.__leafletIncluded) { app.__leafletIncluded = true; this.import('node_modules/leaflet/dist/leaflet-src.js'); @@ -72,7 +80,7 @@ module.exports = { const trees = [ new Funnel(leafletImagesPath, { srcDir: '/', - destDir: '/leaflet-images', + destDir: '/assets/images', allowEmpty: true, }), ]; @@ -120,6 +128,20 @@ module.exports = { return path.dirname(resolve.sync(packageName + '/package.json', { basedir: __dirname })); }, + _findHostFallback() { + let current = this; + let app = current; + do { + if (current.lazyLoading === true || (current.lazyLoading && current.lazyLoading.enabled === true)) { + app = current; + break; + } + app = current.app || app; + } while (current.parent.parent && (current = current.parent)); + + return app; + }, + isDevelopingAddon: function () { return true; }, diff --git a/package.json b/package.json index 9a50ba8..92124ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fleetbase/ember-ui", - "version": "0.2.28", + "version": "0.2.29", "description": "Fleetbase UI provides all the interface components, helpers, services and utilities for building a Fleetbase extension into the Console.", "keywords": [ "fleetbase-ui", diff --git a/tests/unit/services/leaflet-test.js b/tests/unit/services/leaflet-test.js new file mode 100644 index 0000000..553d3a2 --- /dev/null +++ b/tests/unit/services/leaflet-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'dummy/tests/helpers'; + +module('Unit | Service | leaflet', function (hooks) { + setupTest(hooks); + + // TODO: Replace this with your real tests. + test('it exists', function (assert) { + let service = this.owner.lookup('service:leaflet'); + assert.ok(service); + }); +});