Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: LayoutTests/imported/web-platform-tests/uievents/resources/eventrecorder.js

Issue 1211973013: update-w3c-deps import using blink d42488bb63a5ac7fd6befd40a9b90fe85cebcc4a: (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add flaky/timeout to TestExpectations Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // interface EventRecorder {
2 // static void start();
3 // static void stop();
4 // static void clearRecords();
5 // static sequence<EventRecord> getRecords();
6 // static void configure(EventRecorderOptions options);
7 // };
8 // * getRecords
9 // * returns an array of EventRecord objects; the array represents the sequenc e of events captured at anytime after the last clear()
10 // call, between when the recorder was started and stopped (includin g multiple start/stop pairs)
11 // * configure
12 // * sets options that should apply to the recorder. If the recorder has any e xisting records, than this API throws an exception.
13 // * start
14 // * starts/un-pauses the recorder
15 // * stop
16 // * stops/pauses the recorder
17 // * clear
18 // * purges all recorded records
19
20 // ----------------------
21
22 // dictionary EventRecorderOptions {
23 // sequence<SupportedEventTypes> mergeEventTypes;
24 // ObjectNamedMap objectMap;
25 // };
26 // * mergeEventTypes
27 // * a list of event types that should be consolidated into one record when al l of the following conditions are true:
28 // 1) The events are of the same type and follow each other chronologically
29 // 2) The events' currentTarget is the same
30 // * The default is an empty list (no event types are merged).
31 // * objectMap
32 // * Sets up a series
33
34 // dictionary ObjectNamedMap {
35 // //<keys will be 'targetTestID' names, with values of the objects which the y label>
36 // };
37 // * targetTestID = the string identifier that the associated target object sh ould be known as (for purposes of unique identification. This
38 // need not be the same as the Node's id attribute if it has one. If no 'targetTestID' string mapping is provided via this
39 // map, but is encountered later when recording specific even ts, a generic targetTestID of 'UNKNOWN_OBJECT' is used.
40
41 // ----------------------
42
43 // dictionary EventRecord {
44 // unsigned long chronologicalOrder;
45 // unsigned long sequentialOccurrences;
46 // sequence<EventRecord>? nestedEvents;
47 // DOMString interfaceType;
48 // EventRecordDetails event;
49 // };
50 // * chronologicalOrder
51 // * Since some events may be dispatched re-entrantly (e.g., while existing ev ents are being dispatched), and others may be merged
52 // given the 'mergeEventTypes' option in the EventRecorder, this value is th e actual chronological order that the event fired
53 // * sequentialOccurrences
54 // * If this event was fired multiple times in a row (see the 'mergeEventTypes ' option), this value is the count of occurrences.
55 // A value of 1 means this was the only occurrence of this event (that no ev ents were merged with it). A value greater than 1
56 // indicates that the event occurred that many times in a row.
57 // * nestedEvents
58 // * The holds all the events that were sequentially dispatched synchronously while the current event was still being dispatched
59 // (e.g., between the time that this event listener was triggered and when i t returned).
60 // * Has the value null if no nested events were recorded during the invocatio n of this listener.
61 // * interfaceType
62 // * The string indicating which Event object (or derived Event object type) t he recorded event object instance is based on.
63 // * event
64 // * Access to the recorded event properties for the event instance (not the a ctual event instance itself). A snapshot of the
65 // enumerable properties of the event object instance at the moment the list ener was first triggered.
66
67 // ----------------------
68
69 // dictionary EventRecordDetails {
70 // //<recorded property names with their values for all enumerable properties of the event object instance>
71 // };
72 // * EventRecordDetails
73 // * For records with 'sequentialOccurrences' > 1, only the first occurence is recorded (subsequent event details are dropped).
74 // * Object reference values (e.g., event.target, event.currentTarget, etc.) a re replaced with their mapped 'targetTestID' string.
75 // If no 'targetTestID' string mapping is available for a particular object, the value 'UNKNOWN_OBJECT' is returned.
76
77 // ----------------------
78
79 // [NoInterfaceObject]
80 // interface EventRecorderRegistration {
81 // void addRecordedEventListener(SupportedEventTypes type, EventListener? han dler, optional boolean capturePhase = false);
82 // void removeRecordedEventListener(SupportedEventTypes type, EventListener? handler, optional boolean capturePhase = false);
83 // };
84 // Node implements EventRecorderRegistration;
85 //
86 // enum SupportedEventTypes = {
87 // "mousemove",
88 // etc...
89 // };
90 // * addRecordedEventListener
91 // * handler = pass null if you want only a default recording of the even t (and don't need any other special handling). Otherwise,
92 // the handler will be invoked normally as part of the event' s dispatch.
93 // * <other params> are the same as those defined on addEventListener/removeEv entListenter APIs (see DOM4)
94 // * Use this API *instead of* addEventListener to record your events for test ing purposes.
95
96 (function EventRecorderScope(global) {
97 "use strict";
98
99 if (global.EventRecorder)
100 return; // Already initialized.
101
102 // WeakMap polyfill
103 if (!global.WeakMap) {
104 throw new Error("EventRecorder depends on WeakMap! Please polyfill for com pleteness to run in this user agent!");
105 }
106
107 // Globally applicable variables
108 var allRecords = [];
109 var recording = false;
110 var rawOrder = 1;
111 var mergeTypesTruthMap = {}; // format of { eventType: true, ... }
112 var eventsInScope = []; // Tracks synchronous event dispatches
113 var handlerMap = new WeakMap(); // Keeps original handlers (so that they can be used to un-register for events.
114
115 // Find all Event Object Constructors on the global and add them to the map a long with their name (sans 'Event')
116 var eventConstructorsNameMap = new WeakMap(); // format of key: hostObject, v alue: alias to use.
117 var regex = /[A-Z][A-Za-z0-9]+Event$/;
118 Object.getOwnPropertyNames(global).forEach(function (propName) {
119 if (regex.test(propName))
120 eventConstructorsNameMap.set(global[propName], propName);
121 });
122 var knownObjectsMap = eventConstructorsNameMap;
123
124 Object.defineProperty(global, "EventRecorder", {
125 writable: true,
126 configurable: true,
127 value: Object.create(null, {
128 start: {
129 enumerable: true, configurable: true, writable: true, value: functio n start() { recording = true; }
130 },
131 stop: {
132 enumerable: true, configurable: true, writable: true, value: functio n stop() { recording = false; }
133 },
134 clearRecords: {
135 enumerable: true, configurable: true, writable: true, value: functio n clearRecords() {
136 rawOrder = 1;
137 allRecords = [];
138 }
139 },
140 getRecords: {
141 enumerable: true, configurable: true, writable: true, value: functio n getRecords() { return allRecords; }
142 },
143 configure: {
144 enumerable: true, configurable: true, writable: true, value: functio n configure(options) {
145 if (allRecords.length > 0)
146 throw new Error("Wrong time to call me: EventRecorder.configur e must only be called when no recorded events are present. Try 'clearRecords' fi rst.");
147
148 // Un-configure existing options by calling again with no options set...
149 mergeTypesTruthMap = {};
150 knownObjectsMap = eventConstructorsNameMap;
151
152 if (!(options instanceof Object))
153 return;
154 // Sanitize the passed object (tease-out getter functions)
155 var sanitizedOptions = {};
156 for (var x in options) {
157 sanitizedOptions[x] = options[x];
158 }
159 if (sanitizedOptions.mergeEventTypes && Array.isArray(sanitizedOp tions.mergeEventTypes)) {
160 sanitizedOptions.mergeEventTypes.forEach(function (eventType) {
161 if (typeof eventType == "string")
162 mergeTypesTruthMap[eventType] = true;
163 });
164 }
165 if (sanitizedOptions.objectMap && (sanitizedOptions.objectMap ins tanceof Object)) {
166 for (var y in sanitizedOptions.objectMap) {
167 knownObjectsMap.set(sanitizedOptions.objectMap[y], y);
168 }
169 }
170 }
171 }
172 })
173 });
174
175 function EventRecord(rawEvent) {
176 this.chronologicalOrder = rawOrder++;
177 this.sequentialOccurrences = 1;
178 this.nestedEvents = null; // potentially a []
179 this.interfaceType = knownObjectsMap.get(rawEvent.constructor);
180 if (!this.interfaceType) // In case (somehow) this event's constructor is not named something with an 'Event' suffix...
181 this.interfaceType = rawEvent.constructor.toString();
182 this.event = new CloneObjectLike(rawEvent);
183 }
184
185 // Only enumerable props including prototype-chain (non-recursive), w/no func tions.
186 function CloneObjectLike(object) {
187 for (var prop in object) {
188 var val = object[prop];
189 if (Array.isArray(val))
190 this[prop] = CloneArray(val);
191 else if (typeof val == "function")
192 continue;
193 else if ((typeof val == "object") && (val != null)) {
194 this[prop] = knownObjectsMap.get(val);
195 if (this[prop] === undefined)
196 this[prop] = "UNKNOWN_OBJECT (" + val.toString() + ")";
197 }
198 else
199 this[prop] = val;
200 }
201 }
202
203 function CloneArray(array) {
204 var dup = [];
205 for (var i = 0, len = array.length; i < len; i++) {
206 var val = array[i]
207 if (typeof val == "undefined")
208 throw new Error("Ugg. Sparce arrays are not supported. Sorry!");
209 else if (Array.isArray(val))
210 dup[i] = "UNKNOWN_ARRAY";
211 else if (typeof val == "function")
212 dup[i] = "UNKNOWN_FUNCTION";
213 else if ((typeof val == "object") && (val != null)) {
214 dup[i] = knownObjectsMap.get(val);
215 if (dup[i] === undefined)
216 dup[i] = "UNKNOWN_OBJECT (" + val.toString() + ")";
217 }
218 else
219 dup[i] = val;
220 }
221 return dup;
222 }
223
224 function generateRecordedEventHandlerWithCallback(callback) {
225 return function(e) {
226 if (recording) {
227 // Setup the scope for any synchronous events
228 eventsInScope.push(recordEvent(e));
229 callback.call(this, e);
230 eventsInScope.pop();
231 }
232 }
233 }
234
235 function recordedEventHandler(e) {
236 if (recording)
237 recordEvent(e);
238 }
239
240 function recordEvent(e) {
241 var record = new EventRecord(e);
242 var recordList = allRecords;
243 // Adjust which sequential list to use depending on scope
244 if (eventsInScope.length > 0) {
245 recordList = eventsInScope[eventsInScope.length - 1].nestedEvents;
246 if (recordList == null) // This top-of-stack event record hasn't had an y nested events yet.
247 recordList = eventsInScope[eventsInScope.length - 1].nestedEvents = [];
248 }
249 if (mergeTypesTruthMap[e.type] && (recordList.length > 0)) {
250 var tail = recordList[recordList.length-1];
251 // Same type and currentTarget?
252 if ((tail.event.type == record.event.type) && (tail.event.currentTarget == record.event.currentTarget)) {
253 tail.sequentialOccurrences++;
254 return;
255 }
256 }
257 recordList.push(record);
258 return record;
259 }
260
261 Object.defineProperties(Node.prototype, {
262 addRecordedEventListener: {
263 enumerable: true, writable: true, configurable: true,
264 value: function addRecordedEventListener(type, handler, capture) {
265 if (handler == null)
266 this.addEventListener(type, recordedEventHandler, capture);
267 else {
268 var subvertedHandler = generateRecordedEventHandlerWithCallback(h andler);
269 handlerMap.set(handler, subvertedHandler);
270 this.addEventListener(type, subvertedHandler, capture);
271 }
272 }
273 },
274 removeRecordedEventListener: {
275 enumerable: true, writable: true, configurable: true,
276 value: function addRecordedEventListener(type, handler, capture) {
277 var alternateHandlerUsed = handlerMap.get(handler);
278 this.removeEventListenter(type, alternateHandlerUsed ? alternateHand lerUsed : recordedEventHandler, capture);
279 }
280 }
281 });
282
283 })(window);
OLDNEW
« no previous file with comments | « LayoutTests/imported/web-platform-tests/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698