UNPKG

rlayers

Version:

React Components for OpenLayers

152 lines 5.32 kB
import React from 'react'; import { RContext } from './context'; import debug from './debug'; export const handlersSymbol = '_rlayers_handlers'; export class RlayersBase extends React.PureComponent { static getOLObject(prop, ol) { let handlers = ol.get(prop); if (handlers === undefined) { handlers = {}; ol.set(prop, handlers); } return handlers; } get handlers() { return RlayersBase.getOLObject(handlersSymbol, this.ol); } /** * Get the lowercase names of the currently installed handlers */ getCurrentEvents() { return Object.keys(this.props) .filter((p) => p.startsWith('on')) .map((ev) => ({ event: ev.toLowerCase().slice(2), prop: ev })) .reduce((a, x) => (Object.assign(Object.assign({}, a), { [x.event]: this.props[x.prop] })), {}); } /** * Get the uppercase name of this event */ getHandlerProp(event) { for (const p of Object.keys(this.props)) if (p.toLowerCase() === 'on' + event) return p; } incrementHandlers(ev) { return; } decrementHandlers(ev) { return; } attachEventHandlers() { var _a; const handlers = this.handlers; const handlersList = Object.keys(handlers !== null && handlers !== void 0 ? handlers : {}); const eventSources = (_a = this.eventSources) !== null && _a !== void 0 ? _a : [this.ol]; const newEvents = this.getCurrentEvents(); const newEventsList = Object.keys(newEvents); const eventsToCheck = newEventsList.concat(handlersList.filter((ev) => !newEventsList.includes(ev))); for (const p of eventsToCheck) { if (handlers[p] !== undefined && newEvents[p] === undefined) { debug('removing previously installed handler', this, p, handlers[p]); for (const source of eventSources) source.un(p, handlers[p]); handlers[p] = undefined; this.decrementHandlers(p); } if (handlers[p] === undefined && newEvents[p] !== undefined) { debug('installing handler', this, p, newEvents[p]); const prop = this.getHandlerProp(p); if (!prop) throw new Error('Internal error'); handlers[p] = (e) => this.props[prop].call(this, e); for (const source of eventSources) source.on(p, handlers[p]); this.incrementHandlers(p); } } } // Used when replacing a source attachOldEventHandlers(newSource) { const handlers = this.handlers; const events = this.getCurrentEvents(); for (const e of Object.keys(events)) { if (events[e]) { debug('reinstalling existing handler', this, e, events[e]); newSource.on(e, handlers[e]); } } } refresh(prevProps) { this.attachEventHandlers(); } /** * Programmatically add an event handler to an RLayers component. * * @param {string} ev OpenLayers event * @param {Handler} cb Callback */ on(ev, cb) { this.ol.on(ev, cb); this.incrementHandlers(ev); } /** * Programmatically add an event handler to an RLayers component. * * Although public, use of this method is discouraged as it lacks * any safety against calling un on a method that has not been * registered. * * @param {string} ev OpenLayers event * @param {Handler} cb Callback */ un(ev, cb) { this.decrementHandlers(ev); this.ol.un(ev, cb); } componentDidMount() { debug('didMount', this); this.refresh(); } /* istanbul ignore next */ propsDiff(prev) { if (this.props === null || prev === null) { if (this.props !== prev) { debug('null props differ', this.props, prev); return true; } return false; } for (const k of Object.keys(this.props)) if (this.props[k] !== prev[k]) { debug('because of', k, this.props[k], prev[k]); return true; } return false; } componentDidUpdate(prevProps, prev, snap) { if (this.props !== prevProps) { debug('willRefresh', this, prevProps, this.props); this.refresh(prevProps); } } componentWillUnmount() { var _a; const handlers = this.handlers; debug('willUnmount', this, handlers); const eventSources = (_a = this.eventSources) !== null && _a !== void 0 ? _a : [this.ol]; for (const h of Object.keys(handlers !== null && handlers !== void 0 ? handlers : {})) { debug('cleaning up handler', this, h, handlers[h]); if (handlers[h]) { for (const source of eventSources) source.un(h, handlers[h]); handlers[h] = undefined; this.decrementHandlers(h); } } } render() { return null; } } RlayersBase.contextType = RContext; //# sourceMappingURL=REvent.js.map