UNPKG

jsdom

Version:

A JavaScript implementation of many web standards

104 lines (81 loc) • 2.99 kB
"use strict"; const { appendHandler, createEventAccessor } = require("../helpers/create-event-accessor"); const isWindow = require("../helpers/is-window"); const { globalEventHandlersEvents, windowEventHandlersEvents } = require("../../../generated/event-sets"); const { mixin } = require("../../utils"); // These events are specified on GlobalEventHandlers but, per the HTML spec, are reflected on the Window from the body // element. They are not derivable from the IDL alone. const windowReflectingBodyElementEvents = new Set(["blur", "error", "focus", "load", "resize", "scroll"]); class GlobalEventHandlerHelpers { _initGlobalEvents() { this._eventHandlers = null; } _getEventHandlerTarget(event) { // https://html.spec.whatwg.org/multipage/webappapis.html#determining-the-target-of-an-event-handler // Step 1 if (this._localName !== "body" && this._localName !== "frameset") { return this; } // Step 2 if (!windowEventHandlersEvents.has(event) && !windowReflectingBodyElementEvents.has(event)) { return this; } // Step 3 + 4 const window = this._ownerDocument._defaultView; return window || null; } _getEventHandlerFor(event) { const target = this._getEventHandlerTarget(event); if (!target) { return null; } if (target._eventHandlers === null) { return null; } return target._eventHandlers[event]; } _setEventHandlerFor(event, handler) { const target = this._getEventHandlerTarget(event); if (!target) { return; } const isRegistered = target._eventHandlers !== null && event in target._eventHandlers; if (!isRegistered) { if (handler === null) { return; } if (target._eventHandlers === null) { target._eventHandlers = Object.create(null); } appendHandler(target, event); } target._eventHandlers[event] = handler; } _globalEventChanged(event) { const propName = "on" + event; if (!(propName in this)) { return; } // Only translate attribute changes into properties when runScripts: "dangerously" is set. // Documents without a browsing context (i.e. without a _defaultView) never run scripts. const window = isWindow(this) ? this : this._ownerDocument._defaultView; if (!window || window._settings.runScripts !== "dangerously") { return; } const val = this.getAttributeNS(null, propName); const handler = val === null ? null : { body: val }; this._setEventHandlerFor(event, handler); } } function installGlobalEventHandlerHelpers(target) { mixin(target, GlobalEventHandlerHelpers.prototype); } class GlobalEventHandlersImpl {} installGlobalEventHandlerHelpers(GlobalEventHandlersImpl.prototype); for (const event of globalEventHandlersEvents) { createEventAccessor(GlobalEventHandlersImpl.prototype, event); } module.exports = { implementation: GlobalEventHandlersImpl, installGlobalEventHandlerHelpers };