3
0
Fork 0
mirror of https://github.com/farmOS/farmOS.git synced 2024-02-23 11:37:38 +01:00

Refactor most of farm_map.js into factory method #436

**Why?** Allow JS in contrib modules to take advantage of
now decoupled map instantiation code to create canonically
extensible/styled maps where the life-cycle of those maps
is controlled by the contrib module JS code.

For example, a contrib module's controller can return;

```php
return [
  'map-prototype' => [
    '#type' => 'farm_map',
    '#attributes' => [
        'id' => 'example-tool-map-prototype',
        'data-map-instantiator' => 'example-tool',
    ],
  ],
];
```

Then create map instances from custom JS like this;

```js
const mapPrototypeElement = document.getElementById('example-tool-map-prototype');

const mapElement = mapPrototypeElement.cloneNode();
mapElement.removeAttribute('id');

myParentContainer.appendChild(mapElement);

const mapInstance = Drupal.behaviors.farm_map.createMapInstance(mapElement, mapElement, 'example-tool-map-prototype', {});
```
This commit is contained in:
Symbioquine 2021-08-18 10:56:35 -07:00 committed by Michael Stenta
parent 6ce9ec2480
commit c92fe90985

View file

@ -2,66 +2,17 @@
Drupal.behaviors.farm_map = {
attach: function (context, settings) {
// Get the units.
let units = 'metric';
if (!!drupalSettings.farm_map.units) {
units = drupalSettings.farm_map.units;
}
// Build default options.
const defaultOptions = {
units,
interactions: {
onFocusOnly: true
},
};
context.querySelectorAll('[data-map-instantiator="farm_map"]').forEach(function (element) {
// Only create a map once per element.
if (element.getAttribute('processed')) return;
element.setAttribute('processed', true);
// Only create a map once per element.
if (element.getAttribute('processed')) return;
element.setAttribute('processed', true);
element.setAttribute('tabIndex', 0);
const drupalSettingsKey = element.getAttribute('id');
const mapOptions = { ...defaultOptions, ...drupalSettings.farm_map[drupalSettingsKey].instance};
const instance = farmOS.map.create(element, mapOptions);
element.setAttribute('tabIndex', 0);
// Expose settings on the instance so other behaviors don't need to know how to look them up in drupalSettings
instance.farmMapSettings = drupalSettings.farm_map[drupalSettingsKey] || {};
context.querySelectorAll('.ol-popup-closer').forEach(function (element) {
element.onClick = function (element) {
element.focus();
};
});
// If the map is rendered as part of a form field, update the map size
// when the field's visible state changes,
const formWrapper = element.closest('div.form-wrapper');
if (formWrapper != null) {
const formWrapperObserver = new MutationObserver((mutations) => {
// Only update the map size if the wrapper was previously hidden.
if (mutations.some((mutation) => { return mutation.oldValue.includes('display: none')})) {
instance.map.updateSize();
}
});
// Observe the style attribute.
formWrapperObserver.observe(formWrapper, {
attributeFilter: ["style"],
attributeOldValue: true
})
}
// If the map is inside a details element, update the map size when
// the details element is toggled.
const details = element.closest('details');
if (details != null) {
details.addEventListener('toggle', function() {
instance.map.updateSize();
});
}
const drupalSettingsKey = element.getAttribute('id');
const mapInstanceOptions = {};
Drupal.behaviors.farm_map.createMapInstance(context, element, drupalSettingsKey, mapInstanceOptions);
});
// Add an event listener to update the map size when the Gin toolbar is toggled.
@ -83,6 +34,71 @@
}
});
}
},
createMapInstance: function(context, element, drupalSettingsKey, mapInstanceOptions) {
// Get the units.
let units = 'metric';
if (!!drupalSettings.farm_map.units) {
units = drupalSettings.farm_map.units;
}
// Build default options.
const defaultOptions = {
units,
interactions: {
onFocusOnly: true
},
};
const mapOptions = {
...defaultOptions,
...drupalSettings.farm_map[drupalSettingsKey].instance,
...mapInstanceOptions
};
const instance = farmOS.map.create(element, mapOptions);
// Expose settings on the instance so other behaviors don't need to know how to look them up in drupalSettings
instance.farmMapSettings = drupalSettings.farm_map[drupalSettingsKey] || {};
context.querySelectorAll('.ol-popup-closer').forEach(function (element) {
element.onClick = function (element) {
element.focus();
};
});
// If the map is rendered as part of a form field, update the map size
// when the field's visible state changes,
const formWrapper = element.closest('div.form-wrapper');
if (formWrapper != null) {
const formWrapperObserver = new MutationObserver((mutations) => {
// Only update the map size if the wrapper was previously hidden.
if (mutations.some((mutation) => { return mutation.oldValue.includes('display: none')})) {
instance.map.updateSize();
}
});
// Observe the style attribute.
formWrapperObserver.observe(formWrapper, {
attributeFilter: ["style"],
attributeOldValue: true
})
}
// If the map is inside a details element, update the map size when
// the details element is toggled.
const details = element.closest('details');
if (details != null) {
details.addEventListener('toggle', function() {
instance.map.updateSize();
});
}
return instance;
}
};
}(Drupal));