Added logging, changed some directory structure

This commit is contained in:
2018-01-13 21:33:40 -05:00
parent f079a5f067
commit 8e72ffb917
73656 changed files with 35284 additions and 53718 deletions

View File

@@ -0,0 +1,18 @@
"use strict";
const EventImpl = require("./Event-impl").implementation;
class CustomEventImpl extends EventImpl {
initCustomEvent(type, bubbles, cancelable, detail) {
if (this._dispatchFlag) {
return;
}
this.initEvent(type, bubbles, cancelable);
this.detail = detail;
}
}
module.exports = {
implementation: CustomEventImpl
};

View File

@@ -0,0 +1,11 @@
"use strict";
const EventImpl = require("./Event-impl").implementation;
class ErrorEventImpl extends EventImpl {
}
module.exports = {
implementation: ErrorEventImpl
};

View File

@@ -0,0 +1,87 @@
"use strict";
const EventInit = require("../generated/EventInit");
class EventImpl {
constructor(args, privateData) {
const type = args[0]; // TODO: Replace with destructuring
const eventInitDict = args[1] || EventInit.convert(undefined);
this.type = type;
const wrapper = privateData.wrapper;
for (const key in eventInitDict) {
if (key in wrapper) {
this[key] = eventInitDict[key];
}
}
this.target = null;
this.currentTarget = null;
this.eventPhase = 0;
this._initializedFlag = true;
this._stopPropagationFlag = false;
this._stopImmediatePropagationFlag = false;
this._canceledFlag = false;
this._dispatchFlag = false;
this.isTrusted = privateData.isTrusted || false;
this.timeStamp = Date.now();
}
get defaultPrevented() {
return this._canceledFlag;
}
stopPropagation() {
this._stopPropagationFlag = true;
}
get cancelBubble() {
return this._stopPropagationFlag;
}
set cancelBubble(v) {
if (v) {
this._stopPropagationFlag = true;
}
}
stopImmediatePropagation() {
this._stopPropagationFlag = true;
this._stopImmediatePropagationFlag = true;
}
preventDefault() {
if (this.cancelable) {
this._canceledFlag = true;
}
}
_initialize(type, bubbles, cancelable) {
this.type = type;
this._initializedFlag = true;
this._stopPropagationFlag = false;
this._stopImmediatePropagationFlag = false;
this._canceledFlag = false;
this.isTrusted = false;
this.target = null;
this.bubbles = bubbles;
this.cancelable = cancelable;
}
initEvent(type, bubbles, cancelable) {
if (this._dispatchFlag) {
return;
}
this._initialize(type, bubbles, cancelable);
}
}
module.exports = {
implementation: EventImpl
};

View File

@@ -0,0 +1,303 @@
"use strict";
const DOMException = require("../../web-idl/DOMException");
const reportException = require("../helpers/runtime-script-errors");
const domSymbolTree = require("../helpers/internal-constants").domSymbolTree;
const idlUtils = require("../generated/utils");
const EventImpl = require("./Event-impl").implementation;
const Event = require("../generated/Event").interface;
class EventTargetImpl {
constructor() {
this._eventListeners = Object.create(null);
}
addEventListener(type, callback, options) {
// webidl2js currently can't handle neither optional arguments nor callback interfaces
if (callback === undefined || callback === null) {
callback = null;
} else if (typeof callback !== "object" && typeof callback !== "function") {
throw new TypeError("Only undefined, null, an object, or a function are allowed for the callback parameter");
}
options = normalizeEventHandlerOptions(options, ["capture", "once"]);
if (callback === null) {
return;
}
if (!this._eventListeners[type]) {
this._eventListeners[type] = [];
}
for (let i = 0; i < this._eventListeners[type].length; ++i) {
const listener = this._eventListeners[type][i];
if (listener.options.capture === options.capture && listener.callback === callback) {
return;
}
}
this._eventListeners[type].push({
callback,
options
});
}
removeEventListener(type, callback, options) {
if (callback === undefined || callback === null) {
callback = null;
} else if (typeof callback !== "object" && typeof callback !== "function") {
throw new TypeError("Only undefined, null, an object, or a function are allowed for the callback parameter");
}
options = normalizeEventHandlerOptions(options, ["capture"]);
if (callback === null) {
// Optimization, not in the spec.
return;
}
if (!this._eventListeners[type]) {
return;
}
for (let i = 0; i < this._eventListeners[type].length; ++i) {
const listener = this._eventListeners[type][i];
if (listener.callback === callback && listener.options.capture === options.capture) {
this._eventListeners[type].splice(i, 1);
break;
}
}
}
dispatchEvent(eventImpl) {
if (!(eventImpl instanceof EventImpl)) {
throw new TypeError("Argument to dispatchEvent must be an Event");
}
if (eventImpl._dispatchFlag || !eventImpl._initializedFlag) {
throw new DOMException(DOMException.INVALID_STATE_ERR, "Tried to dispatch an uninitialized event");
}
if (eventImpl.eventPhase !== Event.NONE) {
throw new DOMException(DOMException.INVALID_STATE_ERR, "Tried to dispatch a dispatching event");
}
eventImpl.isTrusted = false;
return this._dispatch(eventImpl);
}
_dispatch(eventImpl, targetOverride) {
eventImpl._dispatchFlag = true;
eventImpl.target = targetOverride || this;
const eventPath = [];
let targetParent = domSymbolTree.parent(eventImpl.target);
let target = eventImpl.target;
while (targetParent) {
eventPath.push(targetParent);
target = targetParent;
targetParent = domSymbolTree.parent(targetParent);
}
if (eventImpl.type !== "load" && target._defaultView) {
// https://html.spec.whatwg.org/#events-and-the-window-object
eventPath.push(idlUtils.implForWrapper(target._defaultView));
}
eventImpl.eventPhase = Event.CAPTURING_PHASE;
for (let i = eventPath.length - 1; i >= 0; --i) {
if (eventImpl._stopPropagationFlag) {
break;
}
const object = eventPath[i];
const objectImpl = idlUtils.implForWrapper(object) || object; // window :(
const eventListeners = objectImpl._eventListeners[eventImpl.type];
invokeEventListeners(eventListeners, object, eventImpl);
}
eventImpl.eventPhase = Event.AT_TARGET;
if (!eventImpl._stopPropagationFlag) {
invokeInlineListeners(eventImpl.target, eventImpl);
if (this._eventListeners[eventImpl.type]) {
const eventListeners = this._eventListeners[eventImpl.type];
invokeEventListeners(eventListeners, eventImpl.target, eventImpl);
}
}
if (eventImpl.bubbles) {
eventImpl.eventPhase = Event.BUBBLING_PHASE;
for (let i = 0; i < eventPath.length; ++i) {
if (eventImpl._stopPropagationFlag) {
break;
}
const object = eventPath[i];
const objectImpl = idlUtils.implForWrapper(object) || object; // window :(
const eventListeners = objectImpl._eventListeners[eventImpl.type];
invokeInlineListeners(object, eventImpl);
invokeEventListeners(eventListeners, object, eventImpl);
}
}
eventImpl._dispatchFlag = false;
eventImpl._stopPropagationFlag = false;
eventImpl._stopImmediatePropagationFlag = false;
eventImpl.eventPhase = Event.NONE;
eventImpl.currentTarget = null;
return !eventImpl._canceledFlag;
}
}
module.exports = {
implementation: EventTargetImpl
};
function invokeInlineListeners(object, event) {
const wrapper = idlUtils.wrapperForImpl(object);
const inlineListener = getListenerForInlineEventHandler(wrapper, event.type);
if (inlineListener) {
const document = object._ownerDocument || (wrapper && (wrapper._document || wrapper._ownerDocument));
// Will be falsy for windows that have closed
if (document && (!object.nodeName || document.implementation._hasFeature("ProcessExternalResources", "script"))) {
invokeEventListeners([{
callback: inlineListener,
options: normalizeEventHandlerOptions(false, ["capture", "once"])
}], object, event);
}
}
}
function invokeEventListeners(listeners, target, eventImpl) {
const wrapper = idlUtils.wrapperForImpl(target);
const document = target._ownerDocument || (wrapper && (wrapper._document || wrapper._ownerDocument));
// Will be falsy for windows that have closed
if (!document) {
return;
}
// workaround for events emitted on window (window-proxy)
// the wrapper is the root window instance, but we only want to expose the vm proxy at all times
if (wrapper._document) {
target = idlUtils.implForWrapper(wrapper._document)._defaultView;
}
eventImpl.currentTarget = target;
if (!listeners) {
return;
}
const handlers = listeners.slice();
for (let i = 0; i < handlers.length; ++i) {
if (eventImpl._stopImmediatePropagationFlag) {
return;
}
const listener = handlers[i];
const capture = listener.options.capture;
const once = listener.options.once;
// const passive = listener.options.passive;
if (listeners.indexOf(listener) === -1 ||
(eventImpl.eventPhase === Event.CAPTURING_PHASE && !capture) ||
(eventImpl.eventPhase === Event.BUBBLING_PHASE && capture)) {
continue;
}
if (once) {
listeners.splice(listeners.indexOf(listener), 1);
}
try {
if (typeof listener.callback === "object") {
if (typeof listener.callback.handleEvent === "function") {
listener.callback.handleEvent(idlUtils.wrapperForImpl(eventImpl));
}
} else {
listener.callback.call(idlUtils.wrapperForImpl(eventImpl.currentTarget), idlUtils.wrapperForImpl(eventImpl));
}
} catch (e) {
let window = null;
if (wrapper && wrapper._document) {
// Triggered by Window
window = wrapper;
} else if (target._ownerDocument) {
// Triggered by most webidl2js'ed instances
window = target._ownerDocument._defaultView;
} else if (wrapper._ownerDocument) {
// Currently triggered by XHR and some other non-webidl2js things
window = wrapper._ownerDocument._defaultView;
}
if (window) {
reportException(window, e);
}
// Errors in window-less documents just get swallowed... can you think of anything better?
}
}
}
const wrappedListener = Symbol("inline event listener wrapper");
/**
* Normalize the event listeners options argument in order to get always a valid options object
* @param {Object} options - user defined options
* @param {Array} defaultBoolKeys - boolean properties that should belong to the options object
* @returns {Object} object containing at least the "defaultBoolKeys"
*/
function normalizeEventHandlerOptions(options, defaultBoolKeys) {
const returnValue = {};
// no need to go further here
if (typeof options === "boolean" || options === null || typeof options === "undefined") {
returnValue.capture = Boolean(options);
return returnValue;
}
// non objects options so we typecast its value as "capture" value
if (typeof options !== "object") {
returnValue.capture = Boolean(options);
// at this point we don't need to loop the "capture" key anymore
defaultBoolKeys = defaultBoolKeys.filter(k => k !== "capture");
}
for (const key of defaultBoolKeys) {
returnValue[key] = Boolean(options[key]);
}
return returnValue;
}
function getListenerForInlineEventHandler(target, type) {
const callback = target["on" + type];
if (!callback) { // TODO event handlers: only check null
return null;
}
if (!callback[wrappedListener]) {
// https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm
callback[wrappedListener] = function (E) {
const isWindowError = E.constructor.name === "ErrorEvent" && type === "error"; // TODO branding
let returnValue;
if (isWindowError) {
returnValue = callback.call(E.currentTarget, E.message, E.filename, E.lineno, E.colno, E.error);
} else {
returnValue = callback.call(E.currentTarget, E);
}
if (type === "mouseover" || isWindowError) {
if (returnValue === true) {
E.preventDefault();
}
} else if (returnValue === false) {
E.preventDefault();
}
};
}
return callback[wrappedListener];
}

View File

@@ -0,0 +1,4 @@
"use strict";
const EventImpl = require("./Event-impl").implementation;
exports.implementation = class FocusEventImpl extends EventImpl { };

View File

@@ -0,0 +1,11 @@
"use strict";
const EventImpl = require("./Event-impl").implementation;
class HashChangeEventImpl extends EventImpl {
}
module.exports = {
implementation: HashChangeEventImpl
};

View File

@@ -0,0 +1,21 @@
"use strict";
const UIEventImpl = require("./UIEvent-impl").implementation;
class KeyboardEventImpl extends UIEventImpl {
initKeyboardEvent(type, bubbles, cancelable, view, key, location, modifiersList, repeat, locale) {
if (this._dispatchFlag) {
return;
}
this.initUIEvent(type, bubbles, cancelable, view, key);
this.location = location;
this.modifiersList = modifiersList;
this.repeat = repeat;
this.locale = locale;
}
}
module.exports = {
implementation: KeyboardEventImpl
};

View File

@@ -0,0 +1,22 @@
"use strict";
const EventImpl = require("./Event-impl").implementation;
class MessageEventImpl extends EventImpl {
initMessageEvent(type, bubbles, cancelable, data, origin, lastEventId, source, ports) {
if (this._dispatchFlag) {
return;
}
this.initEvent(type, bubbles, cancelable);
this.data = data;
this.origin = origin;
this.lastEventId = lastEventId;
this.source = source;
this.ports = ports;
}
}
module.exports = {
implementation: MessageEventImpl
};

View File

@@ -0,0 +1,28 @@
"use strict";
const UIEventImpl = require("./UIEvent-impl").implementation;
class MouseEventImpl extends UIEventImpl {
initMouseEvent(type, bubbles, cancelable, view, detail, screenX, screenY, clientX, clientY,
ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) {
if (this._dispatchFlag) {
return;
}
this.initUIEvent(type, bubbles, cancelable, view, detail);
this.screenX = screenX;
this.screenY = screenY;
this.clientX = clientX;
this.clientY = clientY;
this.ctrlKey = ctrlKey;
this.altKey = altKey;
this.shiftKey = shiftKey;
this.metaKey = metaKey;
this.button = button;
this.relatedTarget = relatedTarget;
}
}
module.exports = {
implementation: MouseEventImpl
};

View File

@@ -0,0 +1,4 @@
"use strict";
const EventImpl = require("./Event-impl.js").implementation;
exports.implementation = class PopStateEventImpl extends EventImpl {};

View File

@@ -0,0 +1,11 @@
"use strict";
const EventImpl = require("./Event-impl").implementation;
class ProgressEventImpl extends EventImpl {
}
module.exports = {
implementation: ProgressEventImpl
};

View File

@@ -0,0 +1,11 @@
"use strict";
const UIEventImpl = require("./UIEvent-impl").implementation;
class TouchEventImpl extends UIEventImpl {
}
module.exports = {
implementation: TouchEventImpl
};

View File

@@ -0,0 +1,19 @@
"use strict";
const EventImpl = require("./Event-impl").implementation;
class UIEventImpl extends EventImpl {
initUIEvent(type, bubbles, cancelable, view, detail) {
if (this._dispatchFlag) {
return;
}
this.initEvent(type, bubbles, cancelable);
this.view = view;
this.detail = detail;
}
}
module.exports = {
implementation: UIEventImpl
};