Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mock-doc): add matrix and tspan props for svgelement #3408

Merged
merged 12 commits into from
Jun 13, 2022
141 changes: 135 additions & 6 deletions src/mock-doc/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,28 @@ export function createElementNS(ownerDocument: any, namespaceURI: string, tagNam
if (namespaceURI === 'http://www.w3.org/1999/xhtml') {
return createElement(ownerDocument, tagName);
} else if (namespaceURI === 'http://www.w3.org/2000/svg') {
return new MockSVGElement(ownerDocument, tagName);
switch (tagName.toLowerCase()) {
case 'text':
case 'tspan':
case 'tref':
case 'altglyph':
case 'textpath':
return new MockSVGTextContentElement(ownerDocument, tagName);
case 'circle':
case 'ellipse':
case 'image':
case 'line':
case 'path':
case 'polygon':
case 'polyline':
case 'rect':
case 'use':
return new MockSVGGraphicsElement(ownerDocument, tagName);
case 'svg':
return new MockSVGSVGElement(ownerDocument, tagName);
default:
return new MockSVGElement(ownerDocument, tagName);
}
} else {
return new MockElement(ownerDocument, tagName);
}
Expand Down Expand Up @@ -237,6 +258,95 @@ patchPropAttributes(MockScriptElement.prototype, {
type: String,
});

export class MockDOMMatrix {
static fromMatrix() {
return new MockDOMMatrix();
}
a: number = 1;
b: number = 0;
c: number = 0;
d: number = 1;
Comment on lines +265 to +268
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this question in the original implementation that I think still stands

For my own understanding, why do a and d get assigned a value of 1, but the other single letter properties of the matrix are assigned a value of 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I missed responding to this one! I don't know. I simply used the default values returned when a DOMMatrix is instantiated (see screenshot).
Screen Shot 2022-06-13 at 11 18 30 AM

e: number = 0;
f: number = 0;
m11: number = 1;
m12: number = 0;
m13: number = 0;
m14: number = 0;
m21: number = 0;
m22: number = 1;
m23: number = 0;
m24: number = 0;
m31: number = 0;
m32: number = 0;
m33: number = 1;
m34: number = 0;
m41: number = 0;
m42: number = 0;
m43: number = 0;
m44: number = 1;
is2D: boolean = true;
isIdentity: boolean = true;
inverse() {
return new MockDOMMatrix();
}
flipX() {
return new MockDOMMatrix();
}
flipY() {
return new MockDOMMatrix();
}
multiply() {
return new MockDOMMatrix();
}
rotate() {
return new MockDOMMatrix();
}
rotateAxisAngle() {
return new MockDOMMatrix();
}
rotateFromVector() {
return new MockDOMMatrix();
}
scale() {
return new MockDOMMatrix();
}
scaleNonUniform() {
return new MockDOMMatrix();
}
skewX() {
return new MockDOMMatrix();
}
skewY() {
return new MockDOMMatrix();
}
toJSON() {}
toString() {}
transformPoint() {
return new MockDOMPoint();
}
translate() {
return new MockDOMMatrix();
}
}

export class MockDOMPoint {
w: number = 1;
x: number = 0;
y: number = 0;
z: number = 0;
toJSON() {}
matrixTransform() {
return new MockDOMMatrix();
}
}

export class MockSVGRect {
height: number = 10;
width: number = 10;
x: number = 0;
y: number = 0;
}

export class MockStyleElement extends MockHTMLElement {
sheet: MockCSSStyleSheet;

Expand Down Expand Up @@ -266,7 +376,6 @@ export class MockStyleElement extends MockHTMLElement {
setStyleElementText(this, value);
}
}

export class MockSVGElement extends MockElement {
// SVGElement properties and methods
get ownerSVGElement(): SVGSVGElement {
Expand All @@ -275,10 +384,6 @@ export class MockSVGElement extends MockElement {
get viewportElement(): SVGElement {
return null;
}

focus() {
/**/
}
onunload() {
/**/
}
Expand All @@ -299,6 +404,30 @@ export class MockSVGElement extends MockElement {
}
}

export class MockSVGGraphicsElement extends MockSVGElement {
getBBox(_options?: { clipped: boolean; fill: boolean; markers: boolean; stroke: boolean }): MockSVGRect {
return new MockSVGRect();
}
getCTM(): MockDOMMatrix {
return new MockDOMMatrix();
}
getScreenCTM(): MockDOMMatrix {
return new MockDOMMatrix();
}
}

export class MockSVGSVGElement extends MockSVGGraphicsElement {
createSVGPoint(): MockDOMPoint {
return new MockDOMPoint();
}
}

export class MockSVGTextContentElement extends MockSVGGraphicsElement {
getComputedTextLength(): number {
return 0;
}
}

export class MockBaseElement extends MockHTMLElement {
constructor(ownerDocument: any) {
super(ownerDocument, 'base');
Expand Down
6 changes: 6 additions & 0 deletions src/mock-doc/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ export class MockElement extends MockNode {
return shadowRoot;
}

blur() {
/**/
}

get shadowRoot() {
return this.__shadowRoot || null;
}
Expand Down Expand Up @@ -316,6 +320,8 @@ export class MockElement extends MockNode {
return this.children[0] || null;
}

focus(_options?: { preventScroll?: boolean }) {}

getAttribute(attrName: string) {
if (attrName === 'style') {
if (this.__style != null && this.__style.length > 0) {
Expand Down
31 changes: 31 additions & 0 deletions src/mock-doc/test/html-parse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createFragment } from '../document';
import { MockDocument } from '../document';
import { NODE_TYPES } from '../constants';
import { parseHtmlToDocument, parseHtmlToFragment } from '../parse-html';
import { MockDOMMatrix, MockDOMPoint, MockSVGRect, MockSVGSVGElement, MockSVGTextContentElement } from '../element';

describe('parseHtml', () => {
let doc: MockDocument;
Expand Down Expand Up @@ -87,6 +88,36 @@ describe('parseHtml', () => {
expect(doc.body.firstElementChild.attributes.item(0).name).toEqual('viewBox');
});

it('svg matrix members', () => {
doc = new MockDocument(`
<svg viewBox="0 0 100 100">
<svg>
<rect x="0" y="0" width="10" height="10"></rect>
</svg>
</svg>
`);
const svgElem: MockSVGSVGElement = doc.body.firstElementChild.firstElementChild as MockSVGSVGElement;
expect(svgElem.getBBox()).toEqual(new MockSVGRect());
expect(svgElem.createSVGPoint()).toEqual(new MockDOMPoint());
expect(svgElem.getScreenCTM()).toEqual(new MockDOMMatrix());
expect(svgElem.getCTM()).toEqual(new MockDOMMatrix());
});

it('svg text members', () => {
doc = new MockDocument(`
<svg viewBox="0 0 100 100">
<text x="10" y="10">
Hello
<tspan>world</tspan>
</text>
</svg>
`);
const tspan: MockSVGTextContentElement = doc.body.firstElementChild.firstElementChild
.firstElementChild as MockSVGTextContentElement;
expect(doc.body.firstElementChild.firstElementChild.tagName).toEqual('text');
expect(tspan.getComputedTextLength()).toEqual(0);
});

it('template', () => {
doc = new MockDocument(`
<template>text</template>
Expand Down
2 changes: 1 addition & 1 deletion src/testing/puppeteer/puppeteer-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class E2EElement extends MockHTMLElement implements pd.E2EElementInternal
await this._page.waitForChanges();
}

async focus() {
override async focus() {
await this._elmHandle.focus();
await this._page.waitForChanges();
}
Expand Down