rlayers
Version:
React Components for OpenLayers
152 lines • 5.32 kB
JavaScript
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