Spaces:
Sleeping
Sleeping
| import { mac } from "./browser" | |
| import { indexOf } from "./misc" | |
| // EVENT HANDLING | |
| // Lightweight event framework. on/off also work on DOM nodes, | |
| // registering native DOM handlers. | |
| const noHandlers = [] | |
| export let on = function(emitter, type, f) { | |
| if (emitter.addEventListener) { | |
| emitter.addEventListener(type, f, false) | |
| } else if (emitter.attachEvent) { | |
| emitter.attachEvent("on" + type, f) | |
| } else { | |
| let map = emitter._handlers || (emitter._handlers = {}) | |
| map[type] = (map[type] || noHandlers).concat(f) | |
| } | |
| } | |
| export function getHandlers(emitter, type) { | |
| return emitter._handlers && emitter._handlers[type] || noHandlers | |
| } | |
| export function off(emitter, type, f) { | |
| if (emitter.removeEventListener) { | |
| emitter.removeEventListener(type, f, false) | |
| } else if (emitter.detachEvent) { | |
| emitter.detachEvent("on" + type, f) | |
| } else { | |
| let map = emitter._handlers, arr = map && map[type] | |
| if (arr) { | |
| let index = indexOf(arr, f) | |
| if (index > -1) | |
| map[type] = arr.slice(0, index).concat(arr.slice(index + 1)) | |
| } | |
| } | |
| } | |
| export function signal(emitter, type /*, values...*/) { | |
| let handlers = getHandlers(emitter, type) | |
| if (!handlers.length) return | |
| let args = Array.prototype.slice.call(arguments, 2) | |
| for (let i = 0; i < handlers.length; ++i) handlers[i].apply(null, args) | |
| } | |
| // The DOM events that CodeMirror handles can be overridden by | |
| // registering a (non-DOM) handler on the editor for the event name, | |
| // and preventDefault-ing the event in that handler. | |
| export function signalDOMEvent(cm, e, override) { | |
| if (typeof e == "string") | |
| e = {type: e, preventDefault: function() { this.defaultPrevented = true }} | |
| signal(cm, override || e.type, cm, e) | |
| return e_defaultPrevented(e) || e.codemirrorIgnore | |
| } | |
| export function signalCursorActivity(cm) { | |
| let arr = cm._handlers && cm._handlers.cursorActivity | |
| if (!arr) return | |
| let set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []) | |
| for (let i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) | |
| set.push(arr[i]) | |
| } | |
| export function hasHandler(emitter, type) { | |
| return getHandlers(emitter, type).length > 0 | |
| } | |
| // Add on and off methods to a constructor's prototype, to make | |
| // registering events on such objects more convenient. | |
| export function eventMixin(ctor) { | |
| ctor.prototype.on = function(type, f) {on(this, type, f)} | |
| ctor.prototype.off = function(type, f) {off(this, type, f)} | |
| } | |
| // Due to the fact that we still support jurassic IE versions, some | |
| // compatibility wrappers are needed. | |
| export function e_preventDefault(e) { | |
| if (e.preventDefault) e.preventDefault() | |
| else e.returnValue = false | |
| } | |
| export function e_stopPropagation(e) { | |
| if (e.stopPropagation) e.stopPropagation() | |
| else e.cancelBubble = true | |
| } | |
| export function e_defaultPrevented(e) { | |
| return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false | |
| } | |
| export function e_stop(e) {e_preventDefault(e); e_stopPropagation(e)} | |
| export function e_target(e) {return e.target || e.srcElement} | |
| export function e_button(e) { | |
| let b = e.which | |
| if (b == null) { | |
| if (e.button & 1) b = 1 | |
| else if (e.button & 2) b = 3 | |
| else if (e.button & 4) b = 2 | |
| } | |
| if (mac && e.ctrlKey && b == 1) b = 3 | |
| return b | |
| } | |