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

Upgrade DOM bricks to be root aware #4910

Merged
merged 8 commits into from
Jan 2, 2023
Merged

Conversation

twschiller
Copy link
Contributor

@twschiller twschiller commented Dec 29, 2022

What does this PR do?

Reviewer Tips

  • Start with rootAwareHelpers
  • Ensure the bricks have isRootAware() method overriden
  • Focus on the brick's run methods to double-check this wouldn't change the behavior of any existing bricks

Demo

Future Work

  • We'll need to figure out how to upgrade the Set Input Value brick to work directly on an element

Checklist

  • Add tests
  • Designate a primary reviewer: @BALEHOK

@codecov
Copy link

codecov bot commented Dec 29, 2022

Codecov Report

Merging #4910 (5e1dd2d) into main (a77694e) will increase coverage by 0.77%.
The diff coverage is 86.46%.

❗ Current head 5e1dd2d differs from pull request most recent head 36195d0. Consider uploading reports for the commit 36195d0 to get more accurate results

@@            Coverage Diff             @@
##             main    #4910      +/-   ##
==========================================
+ Coverage   57.97%   58.75%   +0.77%     
==========================================
  Files         960      962       +2     
  Lines       28752    28899     +147     
  Branches     5521     5545      +24     
==========================================
+ Hits        16670    16980     +310     
+ Misses      12082    11919     -163     
Impacted Files Coverage Δ
...s/form/widgets/switchButton/SwitchButtonWidget.tsx 100.00% <ø> (ø)
src/hooks/useTimeoutState.ts 100.00% <ø> (ø)
src/blocks/effects/tour.ts 34.09% <27.27%> (+34.09%) ⬆️
src/blocks/effects/event.ts 78.26% <70.00%> (+78.26%) ⬆️
src/blocks/effects/forms.ts 70.40% <73.68%> (+70.40%) ⬆️
src/pageEditor/tabs/effect/BlockConfiguration.tsx 93.65% <83.33%> (-1.18%) ⬇️
src/blocks/rootModeHelpers.ts 93.33% <93.33%> (ø)
src/blocks/effects/attachAutocomplete.ts 76.66% <100.00%> (+76.66%) ⬆️
src/blocks/effects/customEvent.ts 100.00% <100.00%> (+100.00%) ⬆️
src/blocks/effects/disable.ts 100.00% <100.00%> (+100.00%) ⬆️
... and 26 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@twschiller twschiller marked this pull request as ready for review December 29, 2022 15:43
@@ -43,17 +43,17 @@ class CustomEventEffect extends Effect {
required: ["eventName"],
};

override async isRootAware(): Promise<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.

It wasn't declaring itself as root aware even though it was using the root

@twschiller twschiller added this to the 1.7.16 milestone Dec 29, 2022
@twschiller twschiller changed the title Update DOM bricks to be root aware Upgrade DOM bricks to be root aware Dec 29, 2022
@vercel
Copy link

vercel bot commented Dec 29, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
pixiebrix-extension 🔄 Building (Inspect) Jan 2, 2023 at 1:11PM (UTC)

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2022 PixieBrix, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please update the year

Comment on lines 61 to 78
if (!isRootAware && isEmpty(selector)) {
throw new PropError(
"Selector is required",
blockId,
selectorProp,
selector
);
}

if (isRootAware) {
if (isEmpty(selector)) {
return $(root);
}

return $safeFind(selector, root);
}

return $safeFind(selector, document);
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: making it based on the isRootAware, check it once and have 2 branches for isRootAware == true and isRootAware == false:

Suggested change
if (!isRootAware && isEmpty(selector)) {
throw new PropError(
"Selector is required",
blockId,
selectorProp,
selector
);
}
if (isRootAware) {
if (isEmpty(selector)) {
return $(root);
}
return $safeFind(selector, root);
}
return $safeFind(selector, document);
if (isRootAware) {
if (isEmpty(selector)) {
return $(root);
}
return $safeFind(selector, root);
}
if (isEmpty(selector)) {
throw new PropError(
"Selector is required",
blockId,
selectorProp,
selector
);
}
return $safeFind(selector, document);

* Special prop used to upgrade DOM bricks to be root-aware
* @since 1.7.16
*/
export const IS_ROOT_AWARE_BRICK_PROPS = {
Copy link
Contributor

Choose a reason for hiding this comment

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

We could freeze the object, just to make sure it's never mutated.

Alternatively we can change the API , exporting a method which injects the isRootAware property into a properties object:

inputSchema: Schema = propertiesToSchema(
 addRootAwareProperty(
    {
      selector: {
	@@ -45,34 +51,50 @@ export class AttachAutocomplete extends Effect {
          type: "string",
        },
      },
    }),
    ["options"]
  );

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 I'll go ahead an freeze the object


const inputs = $elements
.toArray()
.filter((x) => !(x instanceof Document) && x.tagName === "INPUT");
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: Is !(x instanceof Document) added just to fix a type error?
Looks unnecessary and a little bit confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

$elements is a Document or HTMLElement. There's really no way of avoiding putting the check somewhere, and Typescript needs enough confidence that all of the array elements are HTMLElements

document.body.innerHTML = `
<html>
<body>
<div>
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: there's one extra space in the indent.

@@ -130,7 +142,7 @@ export class TourEffect extends Effect {
}

const [firstStep] = steps as Step[];
if ($safeFind(firstStep.element).length === 0) {
if ($safeFind(firstStep.element, $root).length === 0) {
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 use $safeFindElementsWithRootMode to be consistent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can't because the $safeFindElementsWithRootMode assumes in its error message that the selector is a top level prop.

Tours will generally have multiple tour stops, so it's expected that the user is providing a selector for each tour stop

In the future, the user would use the Display Temporary Information brick with location: popover to show a popover on a single element

{ selector, orientation = "infer" }: BlockArg,
{ root }: BlockOptions
): Promise<unknown> {
const table = selector ? requireSingleElement(selector, root) : root;
Copy link
Contributor

Choose a reason for hiding this comment

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

Using root implies that the Reader is root aware, doesn't it? If yes, it should provide the isRootAware property.

Copy link
Contributor Author

@twschiller twschiller Jan 2, 2023

Choose a reason for hiding this comment

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

The brick was already rootAware with isRootAware() returning true. This PR makes the selector optional. So we don't need to add an isRootAware prop to the brick inputs


// The DOM brick is running in legacy mode.
return (
<ConnectedFieldTemplate
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: This can be replaced by FieldTemplate, it will skip unnecessary re-renders triggered by the Formik updates.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd have to replicate the touched/error, etc. logic for it then. I think it's cleaner to use the connected component. We'll see if it has any impact on performance

src/components/fields/schemaFields/SchemaField.test.tsx Outdated Show resolved Hide resolved
@twschiller twschiller enabled auto-merge (squash) January 2, 2023 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants