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

Improve narrow width iframes #273

Conversation

GioSensation
Copy link
Member

@GioSensation GioSensation commented Mar 15, 2023

Reviewer: @alistairjcbrown
Asana: https://app.asana.com/0/0/1204100616987020/f

Description

On extensions, our tooltip could be cut off in iframes. This attempts to mitigate the issue by centering the tooltip when the left border is out of the visible frame and when it's overflowing from the right side it just moves it slightly inwards.

Steps to test

Automated tests added. To see it in action you can check the iframe signup form at reddit.com and https://gravida.pro/nytimes/New%20York%20Times%20Checkout (note that I uploaded the form to one of my sites because nytimes is pretty aggressive with bot blocking and I wasn't able to test after just a couple of refreshes).

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
…b.com:duckduckgo/duckduckgo-autofill into ema/improve-narrow-width-iframes

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>

# Conflicts:
#	dist/autofill-debug.js
#	dist/autofill.css
#	dist/autofill.js
#	swift-package/Resources/assets/autofill-debug.js
#	swift-package/Resources/assets/autofill.css
#	swift-package/Resources/assets/autofill.js
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
@@ -14,7 +14,7 @@
<p id="demo"></p>

<div>
Small inputs should be ignored: <input id="email" type="email" style="width: 30px;">
Small inputs should be ignored: <input id="emailSmall" type="email" style="width: 30px;">
Copy link
Member Author

Choose a reason for hiding this comment

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

Nothing to see. Just two elements with the same id.

@@ -35,7 +35,7 @@
"@babel/preset-env": "^7.16.11",
"@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#1.3.0",
"@duckduckgo/content-scope-utils": "github:duckduckgo/content-scope-utils#1.0.1",
"@playwright/test": "^1.24.1",
"@playwright/test": "^1.31.2",
Copy link
Member Author

Choose a reason for hiding this comment

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

Had to bump playwright to use expect.toBeInViewport().

@@ -22,6 +22,8 @@ input[type=email],
input[type=text][aria-label*=email i]:not([aria-label*=search i]),
input:not([type])[aria-label*=email i]:not([aria-label*=search i]),
input[name=username][type=email],
input[autocomplete=username][type=email],
input[autocomplete=username][placeholder*=email i],
Copy link
Member Author

@GioSensation GioSensation Mar 15, 2023

Choose a reason for hiding this comment

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

Unrelated, but while testing I noticed a regression on tripadvisor (form in iframe) and fixed it.

@@ -24,6 +24,7 @@ ${this.options.css}
<span class="tooltip__button--email__secondary-text">Blocks email trackers and hides your address</span>
</button>
</div>
<div class="tooltip--email__caret"></div>
Copy link
Member Author

Choose a reason for hiding this comment

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

The caret used to be a pseudo element, but now that we're positioning them independently, I created a separate element.

},
tooltip: {
getRuleString: this.options.tooltipPositionClass,
index: null
Copy link
Member Author

Choose a reason for hiding this comment

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

This allows us to keep two separate indexes for the rules we add to the stylesheet, so we can delete them appropriately.

shadow.styleSheets[0].insertRule(cssRule, ruleObj.index)
}

if (this.options.hasCaret) {
Copy link
Member Author

Choose a reason for hiding this comment

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

We only check overflowing if the tooltip has the caret, because on desktop apps the tooltip sits on top of the page so is not influenced by iframes and such.

const overriddenLeftPosition = left - Math.abs(rightOverflow) - 5

this.updatePosition(element, {left: overriddenLeftPosition, top})
}
Copy link
Member Author

Choose a reason for hiding this comment

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

I tried several combinations of these and they work pretty decently. It's certainly an improvement over the previous state. It never gets into an infinite loop because we constrain the width to the viewport so it can never overflow both ends. I tried removing the rule and the test fails so we're covered.

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
@@ -14,8 +14,6 @@
BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
/* move it offscreen to avoid flashing */
transform: translate(-1000px);
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think this was needed any longer because now the tooltip is hidden before it's positioned so we should be good. I tried testing slowing down the CPU as well, so I think we're fine, but let me know if you notice anything weird.

@GioSensation GioSensation self-assigned this Mar 15, 2023
@GioSensation GioSensation marked this pull request as ready for review March 15, 2023 12:42
Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Copy link
Member

@alistairjcbrown alistairjcbrown left a comment

Choose a reason for hiding this comment

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

A couple of comments, but nothing blocking. LGTM :shipit:

const input = await page.frameLocator('iframe').locator('input#email')
const box = await input.boundingBox()
if (!box) throw new Error('unreachable')
await input.click({position: {x: box.width - (box.height / 2), y: box.height / 2}})
Copy link
Member

@alistairjcbrown alistairjcbrown Mar 15, 2023

Choose a reason for hiding this comment

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

NAB: Worth updating the existing clickDirectlyOnDax helper to take an optional input parameter to keep the position logic in one place?

async assertTooltipWithinFrame () {
const tooltip = await page.frameLocator('iframe').locator('.tooltip--email')
await expect(tooltip).toBeVisible()
await expect(tooltip).toBeInViewport({ ratio: 1 })
Copy link
Member

Choose a reason for hiding this comment

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

Nice assertion!

@@ -93,13 +119,22 @@ export class HTMLTooltip {
const {left, bottom} = this.getPosition()

if (left !== this.left || bottom !== this.top) {
this.updatePosition({left, top: bottom})
this.updatePositions({left, top: bottom})
Copy link
Member

Choose a reason for hiding this comment

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

NAB: may be worth just inlining updatePositions here for readability, and avoid having two very similarly named functions

Comment on lines 177 to 178
const rightOverflow = window.innerWidth - tooltipBoundingBox.right
const overriddenLeftPosition = left - Math.abs(rightOverflow) - 5
Copy link
Member

Choose a reason for hiding this comment

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

NAB: We can remove the Math.abs call by flipping the subtraction

Suggested change
const rightOverflow = window.innerWidth - tooltipBoundingBox.right
const overriddenLeftPosition = left - Math.abs(rightOverflow) - 5
const rightOverflow = tooltipBoundingBox.right - window.innerWidth
const paddingSpace = 5
const overriddenLeftPosition = left - rightOverflow - paddingSpace

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
@GioSensation GioSensation merged commit fa21349 into abrown/changes-to-in-context-signup-treatment Mar 17, 2023
@GioSensation GioSensation deleted the ema/improve-narrow-width-iframes branch March 17, 2023 08:48
alistairjcbrown added a commit that referenced this pull request Mar 23, 2023
* Prevent in-context signup showing on local or invalid domain pages (#263)

* Don't open in-context signup on input click (#264)

* Show grayscale Dax icon for in-context signup (#265)

* Remove initial dismissal in favor of single permanent dismissal (#266)

* Only show in-context signup if recently installed (#267)

* Adds a close X button to the top right of the tooltip (#268)

* Fix grayscale dax logo (#271)

* Ema/prevent focus extensions (#270)

* Update icon asset to fix grayscale version (#276)

* Improve narrow width iframes (#273)

* Add Email Protection tooltip pixel (#277)

* Fade Dax icon in on hover for in-context signup (#278)

* Fade Dax icon in on hover for in-context signup

* Keep Dax icon with active styles when tooltip open

* Prevent icon flicker when clicking Dax icon for open tooltip

* Move style management into form

* Position tooltip above input when no space below (#282)

* Position tooltip above input when no space below

* Preload webfonts before showing tooltip

This prevents the fonts loading in once the tooltip is shown and causing
a layout shift. This is more important when the tooltip is showing above
the input, as it can cause the tooltip to jump up.

* Check tooltip position after revealed and bail if called before

When running on slower devices, the tooltip position may be checked
before the tooltip is revealed. When this happens, we now bail early
without updating the position. Check position is now called after styles
have loaded, when we know the tooltip is visible.

* Hide caret initially and reduce position calculation calls

* Read hidden attribute from DOM

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>

* Fix linting issue with playwright report

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>

* Rename typoed file

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>

---------

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Co-authored-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>

---------

Signed-off-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
Co-authored-by: Emanuele Feliziani <feliziani.emanuele@gmail.com>
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.

2 participants