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

Conversation

marlon-ionic
Copy link
Contributor

Pull request checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)
  • Build (npm run build) was run locally and any changes were pushed
  • Unit tests (npm test) were run locally and passed
  • E2E Tests (npm run test.karma.prod) were run locally and passed
  • Prettier (npm run prettier) was run locally and passed

Pull request type

Please check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

What is the current behavior?

Some methods and properties of SVGElement and its children elements are missing from mock-doc.

What is the new behavior?

Per request from ZenDesk ticket 41657:

  • Added following members were added to SVGElement: createSVGPoint(), getBBox(), getComputedTextLength(), getCTM(), getScreenCTM()
  • Added focus() and blur() to MockElement

Does this introduce a breaking change?

  • Yes
  • No

Testing

Added test suites for the new svg members, one for the matrix-based values and another for getComputedTextLength() since that's related to SVG text elements. The thought was that if additional mockdoc updates are needed in the future, separating the suites would help with code organization.

Other information

@marlon-ionic marlon-ionic requested a review from a team June 6, 2022 16:34
@@ -316,6 +320,10 @@ export class MockElement extends MockNode {
return this.children[0] || null;
}

focus() {
Copy link
Contributor

Choose a reason for hiding this comment

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

focus accepts an optional parameter, which is an object with a single optional field, preventScroll.

Although folks won't use it in this implementation (since we have an empty implementation here), it may be nice to provide folks the ability to conform to the function's definition. Can we add an unused, optional parameter like so?

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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

Since options is optional too right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep! Exactly

@@ -267,6 +267,27 @@ export class MockStyleElement extends MockHTMLElement {
}
}

//Based on deprecated SVGMatrix - http://html5index.org/SVG%20-%20SVGMatrix.html
export const defaultSVGMatrix = {
a: 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

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?

Comment on lines 327 to 335
getBBox() {
return { x: 0, y: 0, width: 10, height: 10 };
}
getCTM() {
return defaultSVGMatrix;
}
getScreenCTM() {
return defaultSVGMatrix;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

These methods appear to not exist on SVGElement, but rather it's child class SVGGraphicsElement. Can we please move these to a (new) MockSVGGraphicsElement class that extends MockSVGElement? The reason being is that these methods shouldn't be available on MockSVGElement (and by extension, any of its child classes except MockSVGGraphicsElement)

Comment on lines 320 to 335
createSVGPoint() {
return {
matrixTransform: defaultSVGMatrix,
x: 0,
y: 0,
};
}
getBBox() {
return { x: 0, y: 0, width: 10, height: 10 };
}
getCTM() {
return defaultSVGMatrix;
}
getScreenCTM() {
return defaultSVGMatrix;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add return types to the function signatures added here please, since they don't return undefined/void?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure but can I use named types like DOMMatrix, or DOMRect? or should the return types be anonymous? I'm not sure what's available while running in the testing context.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can, there's prior art here in this file for using types like DOMPoint and SVGSVGElement

getComputedTextLength(): number {
return 0;
}
createSVGPoint() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This method appears to not exist on SVGElement, but rather on SVGPoint. Can we please move these to a (new) SVGTextContentElement class that extends (a new) MockSSVGPoint? The reason being is that these methods shouldn't be available on MockSVGElement (and by extension, any of its child classes)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks like createSVGPoint() exists in SVGSVGElement so I created that instead

}
createSVGPoint() {
return {
matrixTransform: defaultSVGMatrix,
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at https://www.w3.org/TR/SVG11/coords.html#InterfaceSVGPoint, should this be a callable function rather than an attribute on the object?

Suggested change
matrixTransform: defaultSVGMatrix,
matrixTransform: () => defaultSVGMatrix,

return { x: 0, y: 0, width: 10, height: 10 };
}
getCTM() {
return defaultSVGMatrix;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the return value of getCTM needs to be a DOMMatrix. Although it's similar to an SVGMatrix, it looks like there are different properties/methods on the two

return defaultSVGMatrix;
}
getScreenCTM() {
return defaultSVGMatrix;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the return value of getScreenCTM needs to be a DOMMatrix. Although it's similar to an SVGMatrix, it looks like there are different properties/methods on the two

marlon-ionic and others added 4 commits June 8, 2022 15:12
Co-authored-by: Ryan Waskiewicz <ryanwaskiewicz@gmail.com>
Co-authored-by: Ryan Waskiewicz <ryanwaskiewicz@gmail.com>
@marlon-ionic marlon-ionic requested a review from rwaskiewicz June 10, 2022 21:59
Copy link
Contributor

@rwaskiewicz rwaskiewicz left a comment

Choose a reason for hiding this comment

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

Looks good! One outstanding question/comment

Comment on lines +265 to +268
a: number = 1;
b: number = 0;
c: number = 0;
d: number = 1;
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

Copy link
Contributor

@rwaskiewicz rwaskiewicz left a comment

Choose a reason for hiding this comment

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

Thanks @marlon-ionic! All in all this looks good to me.

The last thing to do is to is resolve a few strictNullChecks errors that this PR is introducing in our test suite. They're a bit hard to find at the moment, as it looks like our CI check for these isn't working correctly against forks. I took the time to find/fix the violations that our tests are introducing, which you can see in the diff below. Can you apply the changes to your fork please? (I've also included a patch file so that you can apply all of the changes all at once), see 'rm-null-errors.txt' attached to this comment)

diff --git a/src/mock-doc/test/html-parse.spec.ts b/src/mock-doc/test/html-parse.spec.ts
index e015311d8..eb3286ae9 100644
--- a/src/mock-doc/test/html-parse.spec.ts
+++ b/src/mock-doc/test/html-parse.spec.ts
@@ -96,7 +96,8 @@ describe('parseHtml', () => {
         </svg>
       </svg>
     `);
-    const svgElem: MockSVGSVGElement = doc.body.firstElementChild.firstElementChild as MockSVGSVGElement;
+    const svgElem: MockSVGSVGElement = doc.body.firstElementChild?.firstElementChild as MockSVGSVGElement;
+    expect(svgElem).toBeDefined();
     expect(svgElem.getBBox()).toEqual(new MockSVGRect());
     expect(svgElem.createSVGPoint()).toEqual(new MockDOMPoint());
     expect(svgElem.getScreenCTM()).toEqual(new MockDOMMatrix());
@@ -112,9 +113,12 @@ describe('parseHtml', () => {
         </text>
       </svg>
     `);
-    const tspan: MockSVGTextContentElement = doc.body.firstElementChild.firstElementChild
-      .firstElementChild as MockSVGTextContentElement;
-    expect(doc.body.firstElementChild.firstElementChild.tagName).toEqual('text');
+    const text: MockSVGTextContentElement = doc.body.firstElementChild?.firstElementChild as MockSVGTextContentElement;
+    expect(text).toBeDefined();
+    expect(text.tagName).toEqual('text');
+
+    const tspan: MockSVGTextContentElement = text.firstElementChild as MockSVGTextContentElement;
+    expect(tspan).toBeDefined();
     expect(tspan.getComputedTextLength()).toEqual(0);
   });

Patch File:
rm-null-errors.txt

@rwaskiewicz
Copy link
Contributor

I'm merging this as an admin - the tech debt burndown (download error files and report) has a bug in it where it doesn't work against forks of the repo. All other CI checks are passing, and no new strictNullChecks violations nor unused exports are being introduced in this PR.

@rwaskiewicz rwaskiewicz merged commit d3b93c1 into stenciljs:main Jun 13, 2022
@rwaskiewicz rwaskiewicz added the Resolution: Refine This PR is marked for Jira refinement. We're not working on it - we're talking it through. label Jun 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Refine This PR is marked for Jira refinement. We're not working on it - we're talking it through.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants