Source: control/control.js

  1. import OLControl from 'ol/control/Control';
  2. import VectorSource from 'ol/source/Vector';
  3. /**
  4. * OLE control base class.
  5. * @extends ol.control.Control
  6. * @alias ole.Control
  7. */
  8. class Control extends OLControl {
  9. /**
  10. * @inheritdoc
  11. * @param {Object} options Control options.
  12. * @param {HTMLElement} options.element Element which to substitute button.
  13. * @param {string} options.className Name of the control's HTML class.
  14. * @param {string} options.title Title of the control toolbar button.
  15. * @param {Image} options.image Control toolbar image.
  16. * @param {HTMLElement} [options.dialogTarget] Specify a target if you want
  17. * the dialog div used by the control to be rendered outside of the map's viewport.
  18. * @param {ol.source.Vector} [options.source] Vector source holding
  19. * edit features. If undefined, options.features must be passed.
  20. * @param {ol.Collection<ol.Feature>} [options.features] Collection of
  21. * edit features. If undefined, options.source must be set.
  22. * @param {function} [options.layerFilter] Filter editable layer.
  23. */
  24. constructor(options) {
  25. let button = null;
  26. if (!options.element) {
  27. button = document.createElement('button');
  28. button.className = `ole-control ${options.className}`;
  29. }
  30. super({
  31. element: options.element || button,
  32. });
  33. /**
  34. * Specify a target if you want the dialog div used by the
  35. * control to be rendered outside of the map's viewport.
  36. * @type {HTMLElement}
  37. * @private
  38. */
  39. this.dialogTarget = options.dialogTarget;
  40. /**
  41. * Control properties.
  42. * @type {object}
  43. * @private
  44. */
  45. this.properties = { ...options };
  46. /**
  47. * Html class name of the control button.
  48. * @type {string}
  49. * @private
  50. */
  51. this.className = options.className;
  52. /**
  53. * Control title.
  54. * @type {string}
  55. * @private
  56. */
  57. this.title = options.title;
  58. if (button) {
  59. const img = document.createElement('img');
  60. img.src = options.image;
  61. button.appendChild(img);
  62. button.title = this.title;
  63. button.addEventListener('click', this.onClick.bind(this));
  64. }
  65. /**
  66. * Source with edit features.
  67. * @type {ol.source.Vector}
  68. * @private
  69. */
  70. this.source =
  71. options.source ||
  72. new VectorSource({
  73. features: options.features,
  74. });
  75. /**
  76. * Filter editable layer. Used by select interactions instead of
  77. * the old source property.
  78. * @type {function}
  79. * @private
  80. */
  81. this.layerFilter =
  82. options.layerFilter ||
  83. ((layer) => !this.source || (layer && layer.getSource() === this.source));
  84. /**
  85. * ole.Editor instance.
  86. * @type {ole.Editor}
  87. * @private
  88. */
  89. this.editor = null;
  90. /**
  91. * @type {Boolean}
  92. * @private
  93. */
  94. this.standalone = true;
  95. }
  96. /**
  97. * Returns the control's element.
  98. * @returns {Element} the control element.
  99. */
  100. getElement() {
  101. return this.element;
  102. }
  103. /**
  104. * Click handler for the control element.
  105. * @private
  106. */
  107. onClick() {
  108. if (this.active) {
  109. this.deactivate();
  110. } else {
  111. this.activate();
  112. }
  113. }
  114. /**
  115. * Sets the map of the control.
  116. * @protected
  117. * @param {ol.Map} map The map object.
  118. */
  119. setMap(map) {
  120. this.map = map;
  121. super.setMap(this.map);
  122. }
  123. /**
  124. * Introduce the control to it's editor.
  125. * @param {ole.Editor} editor OLE Editor.
  126. * @protected
  127. */
  128. setEditor(editor) {
  129. this.editor = editor;
  130. }
  131. /**
  132. * Activate the control
  133. */
  134. activate(silent) {
  135. this.active = true;
  136. this.element.className += ' active';
  137. if (!silent) {
  138. this.dispatchEvent({
  139. type: 'change:active',
  140. target: this,
  141. detail: { control: this },
  142. });
  143. }
  144. this.openDialog();
  145. }
  146. /**
  147. * Dectivate the control
  148. * @param {boolean} [silent] Do not trigger an event.
  149. */
  150. deactivate(silent) {
  151. this.active = false;
  152. this.element.classList.remove('active');
  153. if (!silent) {
  154. this.dispatchEvent({
  155. type: 'change:active',
  156. target: this,
  157. detail: { control: this },
  158. });
  159. }
  160. this.closeDialog();
  161. }
  162. /**
  163. * Returns the active state of the control.
  164. * @returns {Boolean} Active state.
  165. */
  166. getActive() {
  167. return this.active;
  168. }
  169. /**
  170. * Open the control's dialog (if defined).
  171. */
  172. openDialog() {
  173. this.closeDialog();
  174. if (this.getDialogTemplate) {
  175. this.dialogDiv = document.createElement('div');
  176. this.dialogDiv.innerHTML = `
  177. <div class="ole-dialog">
  178. ${this.getDialogTemplate()}
  179. </div>
  180. `;
  181. (this.dialogTarget || this.map.getTargetElement()).appendChild(
  182. this.dialogDiv,
  183. );
  184. }
  185. }
  186. /**
  187. * Closes the control dialog.
  188. * @private
  189. */
  190. closeDialog() {
  191. if (this.dialogDiv) {
  192. (this.dialogTarget || this.map.getTargetElement()).removeChild(
  193. this.dialogDiv,
  194. );
  195. this.dialogDiv = null;
  196. }
  197. }
  198. /**
  199. * Set properties.
  200. * @param {object} properties New control properties.
  201. * @param {boolean} [silent] If true, no propertychange event is triggered.
  202. */
  203. setProperties(properties, silent) {
  204. this.properties = { ...this.properties, ...properties };
  205. if (!silent) {
  206. this.dispatchEvent({
  207. type: 'propertychange',
  208. target: this,
  209. detail: { properties: this.properties, control: this },
  210. });
  211. }
  212. }
  213. /**
  214. * Return properties.
  215. * @returns {object} Copy of control properties.
  216. */
  217. getProperties() {
  218. return { ...this.properties };
  219. }
  220. }
  221. export default Control;