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

Add text highlight mode for text background #684

Merged
merged 30 commits into from
Apr 1, 2020
Merged

Conversation

obetomuniz
Copy link
Contributor

@obetomuniz obetomuniz commented Mar 20, 2020

Resolves #468

Kapture-2020-03-20-at-18 46 16

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2020

Size Change: +1.56 kB (0%)

Total Size: 509 kB

Filename Size Change
assets/js/edit-story.js 438 kB +1.56 kB (0%)
ℹ️ View Unchanged
Filename Size Change
assets/css/edit-story.css 3.01 kB 0 B
assets/css/stories-dashboard.css 206 B 0 B
assets/js/stories-dashboard.js 67.3 kB 0 B

compressed-size-action

@swissspidy swissspidy added the Type: Enhancement New feature or improvement of an existing feature label Mar 22, 2020
Copy link
Contributor

@barklund barklund 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. I just need to understand the need for the clone in particular.

assets/src/edit-story/components/panels/textStyle/color.js Outdated Show resolved Hide resolved
assets/src/edit-story/components/panels/textStyle/color.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/display.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/display.js Outdated Show resolved Hide resolved
assets/src/edit-story/components/panels/textStyle/color.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/output.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/display.js Outdated Show resolved Hide resolved
* master: (81 commits)
  Bump webpack from 4.42.0 to 4.42.1 (#740)
  Lint fixes
  Move DEFAULT_LINK declaration to within LinkPanel
  Bump lint-staged from 10.0.8 to 10.0.9 (#728)
  Fix clip path on iOS Chrome (#727)
  Bump @wordpress/components from 9.2.4 to 9.2.5 (#722)
  Performance & aesthetic improvements for drop targets (#687)
  Fix LinkType default arg hack due to module loading errors
  Temp fix for LinkType problem
  lints
  Bump prettier from 2.0.1 to 2.0.2 (#721)
  Lots and lots and lots of tests
  fixed tests
  transparent color formatting
  Color migrated
  Migrated most of the panels, except for color
  Save on selection change
  News tests for DesignPanel and related features
  Auto-submit for all forms
  Text style support
  ...
assets/src/edit-story/components/panels/textStyle/color.js Outdated Show resolved Hide resolved
assets/src/edit-story/components/panels/textStyle/color.js Outdated Show resolved Hide resolved
@@ -103,10 +123,24 @@ function TextDisplay({
: '';
});

if (backgroundType === BACKGROUND_TEXT_MODE.HIGHLIGHT) {
return (
<HighlightElement ref={ref} {...props}>
Copy link
Contributor

Choose a reason for hiding this comment

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

It's really underseriable to change refs. Any way this can be done differently? Some top-level container? Or we can apply the exact same DOM structure of p > span, but customize the CSS for both p and span when a specific background mode is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting. I will try this top-level container approach for this case. Thanks, @dvoytenko !

Copy link
Contributor

Choose a reason for hiding this comment

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

I did not address this one, though. Is it necessary?

Copy link
Contributor

Choose a reason for hiding this comment

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

@dvoytenko @barklund what's the resolution here? Dima, can you advise on whether this should still be addressed before merging?

assets/src/edit-story/elements/text/output.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/output.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/index.js Outdated Show resolved Hide resolved
@pbakaus
Copy link
Contributor

pbakaus commented Mar 25, 2020

hi Beto, excited to see this taking shape! A couple of issues that I'd love to get addressed:

  1. When "Highlight" fill style is active, the padding input should affect the inner padding of the span, not the bounding box. While this is technically a different padding, it should feel the most intuitive.
  2. I think we should try to calculate the line-height in this mode based on how I've done it in the codepen (see highlight spacing). A line height of "1", in highlight fill mode, shall mean "no spacing between lines". This is a little tricky to figure out, so can be a follow up PR.
  3. In my codepen, I purposely clone the element and stack it on top of each other at the exact same position (it's a little too hacky in my codepen, obviously for your purposes use some sort of wrapper). This is important, as with overlapping lines (a desired effect, see codepen and set spacing to -0.3em), the letters otherwise get cut off.
  4. Because 3) will be a common effect people use, we should not allow them to lower the opacity when the lines overlap - so please include some logic that disables opacity temporarily (disables the opacity field, but keeps the value) in that case.

Feel free to ping me if you have any questions.

@googlebot
Copy link

All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter.

We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only @googlebot I consent. in this pull request.

Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the cla label to yes (if enabled on your project).

ℹ️ Googlers: Go here for more info.

@barklund
Copy link
Contributor

@googlebot I consent.

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@googlebot googlebot removed the cla: no label Mar 25, 2020
Morten Barklund added 2 commits March 27, 2020 22:33
# Conflicts:
#	assets/src/edit-story/elements/text/display.js
#	assets/src/edit-story/elements/text/output.js
#	assets/src/edit-story/utils/textMeasurements.js
@barklund
Copy link
Contributor

barklund commented Mar 28, 2020

I been struggling with this one all afternoon. I simply cannot get the word breaks to align in different calculations. It just can't happen. A scaled text box does not break at the same breakpoints - fonts just don't work like that.

In this video here:
https://youtu.be/l1ZP2ttOxzE

the left-most box is a visualization of the output render at 30% scale (it's calculated at the full 1080x1920 px size, then scaled down using transform:scale(.3)). The middle render use scaled pixel values (that scale to the current canvas size, which is some fraction of the full 1080x1920). Even though the pixels aren't rounded, there's still a difference. Notice how some word break happen in the right place, and some happen slightly earlier on the left version (the transformed one). I even found some instances where the word breaks happened first on the left for some lines and first on the middle for other lines.

The right-most version is the rendered story using percentages of the whole story width - directly calculated from the 1080x1920px valued just by ratios instead.

As you can see, there will be cases where the calculated height doesn't match the visual height. I can make sure it errs on either side though, so it's always guaranteed that all the lines will fit inside the visual box (but the box might be a line or two too long), or that the box will never be too long (but might cut off the last line or two).

And this isn't only an issue for highlight text of course. I can find the same pixel-tight deviations for regular text as well.

The only "real" solution as I see it is to manually find line breaks in one of these instances and calculate number of lines from that - and then use explicit line breaks in the real output to match this calculation. We can calculate line breaks by pasting word for word into a fixed-width box and see when the height shifts or we can leverage CanvasRenderingContext2D.measureText().

@pbakaus, what's your call here? Do you have prior experience? Should we manually split the lines to ensure similarity or can we live with the slight shifts? The cut-off text is probably a big no-go here, right?

@pbakaus
Copy link
Contributor

pbakaus commented Mar 28, 2020

@barklund my condolences, this is indeed a tricky thing to do, and I've faced similar issues before. The browser's layout process works in mysterious ways sometimes.. So a couple things:

  1. cut-off text is definitely a big no-go.
  2. I think you are on the right track. The minuscule differences are usually related to scaling and rounding, and so slightly correcting the output in either direction should do the job.

Here's what I'd do: After resizing etc. (when you're ready to 'commit' a value), measure the total height of the span (fine to use offsetHeight or something here, causes layout but that's the lesser evil in this scenario) to find out how many lines you got, compare it to the total height of the percentage-based/resized 'finalized state' off screen, then, if the line count if off by one in either direction, add a 'padding' to the calculated float (experiment here, ~0.1 or ~0.01% might be enough) to correct.

If it helps, I'm happy to jump on a call for a pair programming / troubleshooting session or whatever. Good luck!

@barklund
Copy link
Contributor

@pbakaus, the trick is though, that I can't test render the final story. At least we don't do that right now. I can only story some variables, that will be used to render the final story, but I can't actually "test run" it and see how long the text will be, how many lines will fit.

Also, this won't ever be static anyway, as the rendered story has width, height and font size in percent of the overall page size. Though these will relatively stay the same as the page resizes, the line breaks will change in the rendered story when the page resizes - that's unavoidable. I don't think we can find some magic relative width and height, that'll make all texts break correctly for all page sizes.

As far as I can see, we can only do two things to "fix" this:

  1. Insert manual line breaks to make sure the lines always break exactly where we want them to break.
  2. Remember the number of lines that's supposed to be in the output, send that to the rendered story and as an attribute of the textfield and in the rendered story add some AMP-compatible script, that'll for initial render and any resize validate, that the text field does in deed contain the required number of lines (and if not decrement/increment the width slightly until it does).

@pbakaus
Copy link
Contributor

pbakaus commented Mar 30, 2020

@barklund I'd be very surprised if 1) doesn't produce an accessibility / screen reader nightmare.. so I'm definitely leaning towards 2. But I'm not convinced that we can't simulate the final output under the hood in the editor. What stops us from recreating the conditions in the final output?

@barklund
Copy link
Contributor

I'd be very surprised if 1) doesn't produce an accessibility / screen reader nightmare.

I actually just want to insert \n and do white-space: pre. That shouldn't impact accessibility at all, should it?

What stops us from recreating the conditions in the final output?

The output is not just one size. The output can be rendered in any size, and we'd have to check that the line breaks are correct for all of them - or at least a representative number of them. That sounds expensive!

@barklund
Copy link
Contributor

What stops us from recreating the conditions in the final output?

The output is not just one size. The output can be rendered in any size, and we'd have to check that the line breaks are correct for all of them - or at least a representative number of them. That sounds expensive!

@pbakaus Hm, it seems the rendered story will always break lines at the same points at various viewport sizes - or at least I can't seem to find any combination of text size, font and width that'll make any line break differently at different viewport sizes. So that's a huge first step at least.

But in order to test how a rendered story will render a given text field, we need to create an iframe with an AMP story inside and measure it here? Or can we create "normal" html elements and assume they'd render identically?

I'm not completely aware how much "magic" (if any) that AMP adds to the browser rendering engine.

@pbakaus
Copy link
Contributor

pbakaus commented Mar 30, 2020

@barklund I don't think there's a crazy amount of magic, it depends more on the way resizing is done (transforms vs. pecentage vs. font-size vs. zoom). At this point, I'd say edge cases are OK, I'm mostly looking for a good enough approximation. Let's merge this soon and then polish later?

@dvoytenko I'd say ok to go ahead and review again.

assets/src/edit-story/elements/text/display.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/display.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/display.js Outdated Show resolved Hide resolved
@@ -41,7 +41,7 @@ const Element = styled.p`
${elementWithFont}
${elementWithTextParagraphStyle}

opacity: 0;
opacity: 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any special highlight work in frame? We use an invisible text to figure out which part of an element is selected for editor.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not completely sure what you mean here. Currently there's no special handling in the frame for a highlight text element. What should happen in the frame, if things were done correctly?

Copy link
Contributor

Choose a reason for hiding this comment

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

It'd be ok to move it to a separate pull request, as long as we don't forget about this entirely. But this is actually originally your code. We generally try to make sure the text in the frame is displayed (but not visible) the same way as display component to ensure that selection logic is correct. See this: https://github.com/google/web-stories-wp/blob/c6af16cfc77e8fc02efe215358a20e8dc8fd3f64/assets/src/edit-story/elements/text/frame.js#L111-L114

assets/src/edit-story/elements/text/output.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/output.js Outdated Show resolved Hide resolved
assets/src/edit-story/elements/text/output.js Outdated Show resolved Hide resolved
@barklund barklund requested a review from dvoytenko March 31, 2020 17:25
@barklund
Copy link
Contributor

I feel this is working pretty well now. There are many cases where line breaks occur differently in the editor preview vs the rendered story, but that's very hard to do anything about IMO. I've made sure that the text field is always at least as big as the contents, but sometimes it's too big (the test render has an extra line, thus room for an extra line in the preview), but that's erring on the right side, I feel.

I'll fix the edit component for highlight now. I don't really understand the purpose of the frame component, so not sure what needs fixing for this one.

@dvoytenko, PTAL again.

@barklund
Copy link
Contributor

I simply cannot get highlight stying to work inside the editor component (draft.js). I don't really know what to do here. I have now made sure the edit component uses more or less the same line height as the display one, but there's still a lot of visual differences between editing and the resulting look. It's not a good user experience. but I recommend we merge this as-is and follow up asap.

Maybe someone else has better ideas for how to solve these last remaining issues?

Copy link
Contributor

@dvoytenko dvoytenko left a comment

Choose a reason for hiding this comment

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

I'm ok with this merging. IMHO let's look into edit mode and frame in separate pull requests. Please file the bugs though. Also, v0010 migration should now be bumped +1.

Morten Barklund added 2 commits March 31, 2020 15:28
@barklund barklund changed the title [WIP] Add text highlight mode for text background Add text highlight mode for text background Mar 31, 2020
@pbakaus pbakaus merged commit 09abe97 into master Apr 1, 2020
@swissspidy swissspidy deleted the add/text-highlighting branch September 24, 2020 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Enhancement New feature or improvement of an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Text - Highlight
7 participants