Skip to content

Commit 00566da

Browse files
authored
Merge pull request #415 from saschanaz/touch
Add Touch Events
2 parents 022bb3d + 97feb09 commit 00566da

File tree

8 files changed

+170
-54
lines changed

8 files changed

+170
-54
lines changed

baselines/dom.generated.d.ts

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,30 @@ interface TextDecoderOptions {
15131513
ignoreBOM?: boolean;
15141514
}
15151515

1516+
interface TouchEventInit extends EventModifierInit {
1517+
changedTouches?: Touch[];
1518+
targetTouches?: Touch[];
1519+
touches?: Touch[];
1520+
}
1521+
1522+
interface TouchInit {
1523+
altitudeAngle?: number;
1524+
azimuthAngle?: number;
1525+
clientX?: number;
1526+
clientY?: number;
1527+
force?: number;
1528+
identifier?: number;
1529+
pageX?: number;
1530+
pageY?: number;
1531+
radiusX?: number;
1532+
radiusY?: number;
1533+
rotationAngle?: number;
1534+
screenX?: number;
1535+
screenY?: number;
1536+
target?: EventTarget;
1537+
touchType?: TouchType;
1538+
}
1539+
15161540
interface TrackEventInit extends EventInit {
15171541
track?: VideoTrack | AudioTrack | TextTrack | null;
15181542
}
@@ -13270,46 +13294,43 @@ declare var TimeRanges: {
1327013294
};
1327113295

1327213296
interface Touch {
13297+
readonly altitudeAngle: number;
13298+
readonly azimuthAngle: number;
1327313299
readonly clientX: number;
1327413300
readonly clientY: number;
13301+
readonly force: number;
1327513302
readonly identifier: number;
1327613303
readonly pageX: number;
1327713304
readonly pageY: number;
13305+
readonly radiusX: number;
13306+
readonly radiusY: number;
13307+
readonly rotationAngle: number;
1327813308
readonly screenX: number;
1327913309
readonly screenY: number;
1328013310
readonly target: EventTarget;
13311+
readonly touchType: TouchType;
1328113312
}
1328213313

1328313314
declare var Touch: {
1328413315
prototype: Touch;
13285-
new(): Touch;
13316+
new(touchInitDict: TouchInit): Touch;
1328613317
};
1328713318

1328813319
interface TouchEvent extends UIEvent {
1328913320
readonly altKey: boolean;
1329013321
readonly changedTouches: TouchList;
13291-
readonly charCode: number;
1329213322
readonly ctrlKey: boolean;
13293-
readonly keyCode: number;
1329413323
readonly metaKey: boolean;
1329513324
readonly shiftKey: boolean;
1329613325
readonly targetTouches: TouchList;
1329713326
readonly touches: TouchList;
13298-
/** @deprecated */
13299-
readonly which: number;
1330013327
}
1330113328

1330213329
declare var TouchEvent: {
1330313330
prototype: TouchEvent;
13304-
new(type: string, touchEventInit?: TouchEventInit): TouchEvent;
13331+
new(type: string, eventInitDict?: TouchEventInit): TouchEvent;
1330513332
};
1330613333

13307-
interface TouchEventInit extends EventModifierInit {
13308-
changedTouches?: Touch[];
13309-
targetTouches?: Touch[];
13310-
touches?: Touch[];
13311-
}
13312-
1331313334
interface TouchList {
1331413335
readonly length: number;
1331513336
item(index: number): Touch | null;
@@ -16057,6 +16078,7 @@ type ScopedCredentialType = "ScopedCred";
1605716078
type ServiceWorkerState = "installing" | "installed" | "activating" | "activated" | "redundant";
1605816079
type TextTrackKind = "subtitles" | "captions" | "descriptions" | "chapters" | "metadata";
1605916080
type TextTrackMode = "disabled" | "hidden" | "showing";
16081+
type TouchType = "direct" | "stylus";
1606016082
type Transport = "usb" | "nfc" | "ble";
1606116083
type VRDisplayEventReason = "mounted" | "navigation" | "requested" | "unmounted";
1606216084
type VREye = "left" | "right";

inputfiles/addedTypes.json

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,31 +1473,6 @@
14731473
}
14741474
}
14751475
},
1476-
"TouchEventInit": {
1477-
"name": "TouchEventInit",
1478-
"flavor": "Web",
1479-
"extends": "EventModifierInit",
1480-
"properties": {
1481-
"property": {
1482-
"touches": {
1483-
"name": "touches",
1484-
"override-type": "Touch[]",
1485-
"required": 0
1486-
},
1487-
"targetTouches": {
1488-
"name": "targetTouches",
1489-
"override-type": "Touch[]",
1490-
"required": 0
1491-
},
1492-
"changedTouches": {
1493-
"name": "changedTouches",
1494-
"override-type": "Touch[]",
1495-
"required": 0
1496-
}
1497-
}
1498-
},
1499-
"no-interface-object": "1"
1500-
},
15011476
"ValidityState": {
15021477
"name": "ValidityState",
15031478
"properties": {

inputfiles/idl/Touch Events.widl

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
enum TouchType {
2+
"direct",
3+
"stylus"
4+
};
5+
6+
dictionary TouchInit {
7+
required long identifier;
8+
required EventTarget target;
9+
double clientX = 0;
10+
double clientY = 0;
11+
double screenX = 0;
12+
double screenY = 0;
13+
double pageX = 0;
14+
double pageY = 0;
15+
float radiusX = 0;
16+
float radiusY = 0;
17+
float rotationAngle = 0;
18+
float force = 0;
19+
double altitudeAngle = 0;
20+
double azimuthAngle = 0;
21+
TouchType touchType = "direct";
22+
};
23+
24+
[Constructor(TouchInit touchInitDict), Exposed=Window]
25+
interface Touch {
26+
readonly attribute long identifier;
27+
readonly attribute EventTarget target;
28+
readonly attribute double screenX;
29+
readonly attribute double screenY;
30+
readonly attribute double clientX;
31+
readonly attribute double clientY;
32+
readonly attribute double pageX;
33+
readonly attribute double pageY;
34+
readonly attribute float radiusX;
35+
readonly attribute float radiusY;
36+
readonly attribute float rotationAngle;
37+
readonly attribute float force;
38+
readonly attribute float altitudeAngle;
39+
readonly attribute float azimuthAngle;
40+
readonly attribute TouchType touchType;
41+
};
42+
43+
interface TouchList {
44+
readonly attribute unsigned long length;
45+
getter Touch? item (unsigned long index);
46+
};
47+
48+
dictionary TouchEventInit : EventModifierInit {
49+
sequence<Touch> touches = [];
50+
sequence<Touch> targetTouches = [];
51+
sequence<Touch> changedTouches = [];
52+
};
53+
54+
[Constructor(DOMString type, optional TouchEventInit eventInitDict), Exposed=Window]
55+
interface TouchEvent : UIEvent {
56+
readonly attribute TouchList touches;
57+
readonly attribute TouchList targetTouches;
58+
readonly attribute TouchList changedTouches;
59+
readonly attribute boolean altKey;
60+
readonly attribute boolean metaKey;
61+
readonly attribute boolean ctrlKey;
62+
readonly attribute boolean shiftKey;
63+
};
64+
65+
partial interface GlobalEventHandlers {
66+
attribute EventHandler ontouchstart;
67+
attribute EventHandler ontouchend;
68+
attribute EventHandler ontouchmove;
69+
attribute EventHandler ontouchcancel;
70+
};
71+
72+
partial interface Document {
73+
// Deprecated in this specification
74+
Touch createTouch (WindowProxy view, EventTarget target, long identifier, double pageX, double pageY, double screenX, double screenY);
75+
// Deprecated in this specification
76+
TouchList createTouchList (Touch... touches);
77+
};

inputfiles/idlSources.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
"url": "https://encoding.spec.whatwg.org/",
44
"title": "Encoding"
55
},
6+
{
7+
"url": "https://w3c.github.io/touch-events/",
8+
"title": "Touch Events"
9+
},
610
{
711
"url": "https://heycam.github.io/webidl/",
812
"title": "Web IDL"

inputfiles/overridingTypes.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,14 +1511,6 @@
15111511
}
15121512
}
15131513
},
1514-
"TouchEvent": {
1515-
"name": "TouchEvent",
1516-
"constructor": {
1517-
"override-signatures": [
1518-
"new(type: string, touchEventInit?: TouchEventInit): TouchEvent"
1519-
]
1520-
}
1521-
},
15221514
"Text": {
15231515
"name": "Text",
15241516
"constructor": {

src/emitter.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ export function emitWebIDl(webidl: Browser.WebIdl, flavor: Flavor) {
273273
function convertDomTypeToTsTypeWorker(obj: Browser.Typed): { name: string; nullable: boolean } {
274274
let type;
275275
if (typeof obj.type === "string") {
276-
type = { name: covertDomTypeToTsTypeSimple(obj.type), nullable: !!obj.nullable };
276+
type = { name: convertDomTypeToTsTypeSimple(obj.type), nullable: !!obj.nullable };
277277
}
278278
else {
279279
const types = obj.type.map(convertDomTypeToTsTypeWorker);
@@ -309,7 +309,7 @@ export function emitWebIDl(webidl: Browser.WebIdl, flavor: Flavor) {
309309
return elementType.includes("|") ? `(${elementType})[]` : `${elementType}[]`;
310310
}
311311

312-
function covertDomTypeToTsTypeSimple(objDomType: string): string {
312+
function convertDomTypeToTsTypeSimple(objDomType: string): string {
313313
switch (objDomType) {
314314
case "AbortMode": return "String";
315315
case "bool":
@@ -351,7 +351,7 @@ export function emitWebIDl(webidl: Browser.WebIdl, flavor: Flavor) {
351351
if (allTypeDefsMap.has(objDomType)) return objDomType;
352352
// Union types
353353
if (objDomType.includes(" or ")) {
354-
const allTypes: string[] = decomposeTypes(objDomType).map(t => covertDomTypeToTsTypeSimple(t.replace("?", "")));
354+
const allTypes: string[] = decomposeTypes(objDomType).map(t => convertDomTypeToTsTypeSimple(t.replace("?", "")));
355355
return allTypes.includes("any") ? "any" : allTypes.join(" | ");
356356
}
357357
else {
@@ -360,12 +360,12 @@ export function emitWebIDl(webidl: Browser.WebIdl, flavor: Flavor) {
360360
const genericMatch = /^(\w+)<([\w, <>]+)>$/;
361361
const match = genericMatch.exec(unescaped);
362362
if (match) {
363-
const tName: string = covertDomTypeToTsTypeSimple(match[1]);
364-
const paramName: string = covertDomTypeToTsTypeSimple(match[2]);
363+
const tName: string = convertDomTypeToTsTypeSimple(match[1]);
364+
const paramName: string = convertDomTypeToTsTypeSimple(match[2]);
365365
return tName === "Array" ? paramName + "[]" : tName + "<" + paramName + ">";
366366
}
367367
if (objDomType.endsWith("[]")) {
368-
return covertDomTypeToTsTypeSimple(objDomType.replace("[]", "").trim()) + "[]";
368+
return convertDomTypeToTsTypeSimple(objDomType.replace("[]", "").trim()) + "[]";
369369
}
370370
}
371371
}
@@ -1110,4 +1110,4 @@ export function emitWebIDl(webidl: Browser.WebIdl, flavor: Flavor) {
11101110

11111111
return printer.getResult();
11121112
}
1113-
}
1113+
}

src/fetcher.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,46 @@ async function fetchIDL(source: IDLSource) {
2626
throw new Error("Found no IDL code");
2727
}
2828
const last = elements[elements.length - 1];
29-
if (last.previousElementSibling!.textContent!.includes("IDL Index")) {
29+
if (last.previousElementSibling &&
30+
last.previousElementSibling.textContent!.includes("IDL Index")
31+
) {
3032
// IDL Index includes all IDL codes
3133
return last.textContent!.trim();
3234
}
3335

34-
return elements.map(element => element.textContent!.trim()).join('\n\n');
36+
return elements.map(element => trimCommonIndentation(element.textContent!).trim()).join('\n\n');
37+
}
38+
39+
/**
40+
* Remove common indentation:
41+
* <pre>
42+
* typedef Type = "type";
43+
* dictionary Dictionary {
44+
* "member"
45+
* };
46+
* </pre>
47+
* Here the textContent has 6 common preceding whitespaces that can be unindented.
48+
*/
49+
function trimCommonIndentation(text: string) {
50+
const lines = text.split("\n");
51+
if (!lines[0].trim()) {
52+
lines.shift();
53+
}
54+
if (!lines[lines.length - 1].trim()) {
55+
lines.pop();
56+
}
57+
const commonIndentation = Math.min(...lines.map(getIndentation));
58+
return lines.map(line => line.slice(commonIndentation)).join("\n");
59+
}
60+
61+
/** Count preceding whitespaces */
62+
function getIndentation(line: string) {
63+
let count = 0;
64+
for (const ch of line) {
65+
if (ch !== " ") {
66+
break;
67+
}
68+
count++;
69+
}
70+
return count;
3571
}

src/widlprocess.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ export function convert(text: string) {
2929
else if (rootType.type === "dictionary") {
3030
browser.dictionaries!.dictionary[rootType.name] = convertDictionary(rootType);
3131
}
32+
else if (rootType.type === "enum") {
33+
browser.enums!.enum[rootType.name] = convertEnum(rootType);
34+
}
3235
else if (rootType.type === "typedef") {
3336
browser.typedefs!.typedef.push(convertTypedef(rootType));
3437
}
@@ -201,6 +204,13 @@ function convertDictionaryMember(member: webidl2.DictionaryMemberType): Browser.
201204
}
202205
}
203206

207+
function convertEnum(en: webidl2.EnumType): Browser.Enum {
208+
return {
209+
name: en.name,
210+
value: en.values.map(value => value.value)
211+
}
212+
}
213+
204214
function convertTypedef(typedef: webidl2.TypedefType): Browser.TypeDef {
205215
return {
206216
"new-type": typedef.name,

0 commit comments

Comments
 (0)