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

PLANET-4811 Submenu WYSIWYG #363

Merged
merged 20 commits into from
Oct 27, 2020
Merged

Conversation

Inwerpsel
Copy link
Contributor

@Inwerpsel Inwerpsel commented Aug 14, 2020

  • Since we only need to watch for changes in the editor, we don't need
    to make the code that queries the DOM update the block when the DOM
    changes. Instead we can use useSelect to get the blocks and filter the
    headers (and potentially other blocks that can output a heading).
  • Decouple fetching the headers from creating a hierarchical
    representation.
  • Just fetch the headings in render of SubmenuFrontend. This component
    doesn't get re-rendered anyway, and also the headings won't change
    (unless other blocks still need to be rendered, we probably should check
    that).
  • Split functions into dedicated files.
  • Add backtop as an effect, which simply toggles the display of it. The
    backtop markup and style will be added to the base template in
    PLANET-4811 Add backtop markup to base template planet4-master-theme#1166
  • Use plain old links instead of implementing our own behavior. Mainly
    did this to remove (a lot of) complexity from the code while doing other
    changes. We should probably evaluate if we still want to do a transition,
    though this can probably still make use of anchors.

@Inwerpsel Inwerpsel requested a review from mleray August 14, 2020 11:37
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch from 446ec65 to 319bd90 Compare August 14, 2020 11:39
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch from 319bd90 to 70c3a39 Compare August 14, 2020 13:17
assets/src/blocks/Submenu/BackTop.js Outdated Show resolved Hide resolved
assets/src/blocks/Submenu/BackTop.js Outdated Show resolved Hide resolved
assets/src/blocks/Submenu/SubmenuFrontend.js Outdated Show resolved Hide resolved
assets/src/blocks/Submenu/BackTop.js Outdated Show resolved Hide resolved
assets/src/blocks/Submenu/SubmenuFrontend.js Outdated Show resolved Hide resolved
assets/src/blocks/Submenu/makeHierarchical.js Outdated Show resolved Hide resolved
assets/src/blocks/Submenu/makeHierarchical.js Outdated Show resolved Hide resolved
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch from 70c3a39 to 6614087 Compare August 24, 2020 14:35
@Inwerpsel Inwerpsel changed the title PLANET-4801 Only search DOM on frontend, useSelect in editor PLANET-4811 Only search DOM on frontend, useSelect in editor Aug 24, 2020
@sagarsdeshmukh sagarsdeshmukh force-pushed the planet-4811-use-get-blocks-in-editor branch from 48d7fc4 to 59b7636 Compare September 1, 2020 04:17
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch 3 times, most recently from 4d1337b to 5707528 Compare September 21, 2020 08:52
@Inwerpsel Inwerpsel changed the base branch from planet-4811 to master September 21, 2020 10:18
@sagarsdeshmukh
Copy link
Member

As we don't have inner block html content to edit, we could safely disable the Edit as HTML option for submenu block.
image

To disable it we need to add html:false in block support options -
supports: { html: false, },

@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch 2 times, most recently from ecbf147 to dd44782 Compare September 25, 2020 13:40
}

function onHeadingChange(index, value) {
let levels = JSON.parse(JSON.stringify(attributes.levels));
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a blocker: This should be safe given the content of levels but I personally prefer using LoDash's deepClone because it's safer for different types and faster, but also is more expressive when reading the code for someone that is not familiar with this technique.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes LoDash deepClone is better for this. But I actually didn't touch SubmenuLevel yet, it's still a class. Maybe it can be written in a way that doesn't require the index lookup, and maybe also doesn't need a deep clone. Then we can avoid adding a dependency on LoDash here.

Copy link
Contributor Author

@Inwerpsel Inwerpsel Oct 16, 2020

Choose a reason for hiding this comment

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

I made a function that has the same output as the JSON switcheroo has, and is a few times faster than it. It's not as "feature" complete as Lodash, in the sense that it doesn't preserve non-built in classes, but so doesn't the JSON approach we used 🤷 There are also some exotic or deprecated JavaScript peculiarities (like Boolean objects...) that don't behave the same way as in Lodash, but we don't use them and we probably never should 😄

Copy link
Contributor Author

@Inwerpsel Inwerpsel Oct 16, 2020

Choose a reason for hiding this comment

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

Did a quick benchmark

/usr/bin/node /home/pieter/deepclone/bm.js
JSON bytes:  18
matches JSON approach
JSON-switcheroo   :  x 1,306,315 ops/sec ±1.03% (85 runs sampled)
lodash            :  x 1,400,846 ops/sec ±1.91% (87 runs sampled)
Custom check refs :  x 5,385,561 ops/sec ±3.58% (83 runs sampled)
Fastest is Custom check refs : 
JSON bytes:  2824
matches JSON approach
JSON-switcheroo   :  x 41,676 ops/sec ±0.77% (88 runs sampled)
lodash            :  x 40,323 ops/sec ±1.27% (85 runs sampled)
Custom check refs :  x 91,897 ops/sec ±1.79% (90 runs sampled)
Fastest is Custom check refs : 
JSON bytes:  7374
matches JSON approach
JSON-switcheroo   :  x 13,925 ops/sec ±1.13% (91 runs sampled)
lodash            :  x 17,017 ops/sec ±1.41% (83 runs sampled)
Custom check refs :  x 40,898 ops/sec ±3.23% (83 runs sampled)
Fastest is Custom check refs : 
JSON bytes:  122662
matches JSON approach
JSON-switcheroo   :  x 762 ops/sec ±1.33% (85 runs sampled)
lodash            :  x 887 ops/sec ±1.30% (86 runs sampled)
Custom check refs :  x 1,873 ops/sec ±1.22% (86 runs sampled)
Fastest is Custom check refs : 
JSON bytes:  642680
matches JSON approach
JSON-switcheroo   :  x 176 ops/sec ±2.45% (69 runs sampled)
lodash            :  x 295 ops/sec ±1.61% (82 runs sampled)
Custom check refs :  x 243 ops/sec ±1.09% (81 runs sampled)
Fastest is lodash            : 

Process finished with exit code 0

@comzeradd comzeradd added the UAT Passed User Acceptance Tests passed label Oct 9, 2020
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch from 2b554e6 to 0c810c2 Compare October 9, 2020 11:14
@Inwerpsel
Copy link
Contributor Author

Rebasing seems to have confused GitHub, it's showing commits in the wrong order here. However locally git log does have the right order 🤔

@Inwerpsel Inwerpsel changed the title PLANET-4811 Only search DOM on frontend, useSelect in editor PLANET-4811 Submenu WYSIWYG Oct 13, 2020
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch from 06129b6 to 2ac319f Compare October 16, 2020 09:16
@Inwerpsel
Copy link
Contributor Author

Rebasing seems to have confused GitHub, it's showing commits in the wrong order here. However locally git log does have the right order

The last rebase has un-confused GitHub 🎉

ancestors.push(value);
clones.push(newObject);

Object.keys(value).forEach(k => newObject[k] = _deepClone(value[k], ancestors, clones));
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 initially used

return Object.assign({}, ...Object.keys(value).map(k => ({ [k]: deepClone(value[k]) })));

here, but it's actually 5 times slower than the above.

Copy link
Contributor

@lithrel lithrel left a comment

Choose a reason for hiding this comment

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

Good to me 👍

Minor thing I saw while looking at the Privacy & Cookies page, headings can be transformed to bold/italic (:shrug:) and the tags appear in the editor (doesn't seem to be a problem on the frontend so not blocking and probably not that frequent).
Screenshot from 2020-10-23 14-47-41

@Inwerpsel
Copy link
Contributor Author

Inwerpsel commented Oct 23, 2020

Good to me

Minor thing I saw while looking at the Privacy & Cookies page, headings can be transformed to bold/italic () and the tags appear in the editor (doesn't seem to be a problem on the frontend so not blocking and probably not that frequent).
Screenshot from 2020-10-23 14-47-41

Good catch 👌 Checking if I can improve that, maybe just stripping tags will do here .

Noticed another issue we probably want to fix first: the previews of the styles in the sidebar all look the same, because the block's output is based on the current headings of the post, but these don't seem to get used in the preview. I'll see if I can make it work with the current headings of the post. If not we'll have to rework the block so that it allows to be rendered from a list of static headings as well, so we can just include those literally in the example data of the block.
Screenshot from 2020-10-23 17-22-39

@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch from d13f5e0 to f80efb6 Compare October 26, 2020 10:17
mleray and others added 17 commits October 26, 2020 11:19
PLANET-4811 Remove shortcode code for Submenu block

PLANET-4811 Turn layout options into styles in the sidebar

PLANET-4811 Add more destructuring to SubmenuEditor

PLANET-4811 Remove more unnecessary Submenu code

PLANET-4811 Add frontend implementation for Submenu WYSIWYG

PLANET-4811 Rename and improve SubmenuLevel

PLANET-4811 Add tooltips to Submenu style labels

PLANET-4811 Retrieve submenu items

PLANET-4811 Fix className for SubmenuEditor

PLANET-4811 Add empty message

PLANET-4811 Hide Submenu block in the frontend if no menu items

PLANET-4811 Add back submenu_style attribute needed for existing blocks

PLANET-4811 Get postId in SubmenuFrontend and use hooks in SubmenuEditor

PLANET-4811 Add missing translations

PLANET-4811 Add recursive function to get menu items

PLANET-4811 Remove old conversion code

PLANET-4811 Add proper links and back-to-top behavior

PLANET-4811 Fix Submenu title color in the editor

PLANET-4811 Fix deprecated attributes

PLANET-4811 Add target links only when needed

PLANET-4811 Fix Submenu rendering

PLANET-4811 Simplify style registration

PLANET-4811 Remove jQuery code

PLANET-4811 Use wp.blockEditor instead of wp.editor to fix console warning

PLANET-4811 Remove css float in the editor

PLANET-4811 Create single file for all submenu functions

PLANET-4811 Remove unused SubmenuIcon
PLANET-4811 Remove endpoint and retrieve content in the frontend instead

PLANET-4811 Remove md5

PLANET-4811 Remove now unused postId prop

PLANET-4811 Add children behaviour to loadMenuItems function
PLANET-4811 Create SubmenuItems component and useSubmenuItemsLoad hook

PLANET-4811 Fix back to top button positioning

PLANET-4811 Make sure ids are unique

PLANET-4811 Fix scrolling animation
* Since we only need to watch for changes in the editor, we don't need
to make the code that queries the DOM update the block when the DOM
changes. Instead we can use `useSelect` to get the blocks and filter the
headers (and potentially other blocks that can output a heading).
* Decouple fetching the headers from creating a hierarchical
representation.
* Just fetch the headings in render of SubmenuFrontend. This component
doesn't get re-rendered anyway, and also the headings won't change
(unless other blocks still need to be rendered, we probably should check
that).
* Split functions into dedicated files.
* Add backtop as an effect, which simply toggles the display of it. The
backtop markup and style will be added to the base template in
greenpeace/planet4-master-theme#1166
* Use plain old links instead of implementing our own behavior. Mainly
did this to remove (a lot of) complexity from the code while doing other
changes.  We should probably evaluate if we still want to do a transition,
though this can probably still make use of anchors.

PLANET-4811 Move complex logic to separate function
* Setting scroll-behavior: smooth on html does a much better job at this
than custom js.
* Classic blocks aka "core/freeform" need to be parsed in order to
extract the same headers as would happen on the frontend. This parsing
is probably not very efficient, though the impact should only be when
there is a classic block in a post, which is discouraged.
* Move extractHeaders to a separate file.

PLANET-4811 Correct header to heading
* Otherwise it would have the same z-index as the paragraphs it's
floating next to, in the side style. That made the links unclickable.
* Prevents the navbar covering the element we're scrolling to. We
probably want to add this site-wide, but probably best handled
distinctly so we can check if this works everywhere.
* For now this padding is tuned for non-logged in users, as the admin
area needs some additional padding which is more tricky to detect. The
scroll-padding-top needs to be on html but on that element we can't know
if we're logged in or not.
* This was overriding the link hover styles, and is not needed when not
hovering.
* Pre populate the added level with the last level+1.
* Disable options that are a lower or equal level than the previous
level.
* Lodash's cloneDeep is reliable if you're interested in supporting
every single weird thing that you shouldn't use in JavaScript such as
Boolean objects, or copying objects with behavior. If you just need a
function that has the same output as `JSON.parse(JSON.stringify))`, then
the added deepClone function will do. It's a few times faster than both
Lodash and the JSON based approach.
* Convert SubmenuLevel to function component.
* More compact `useSelect` call, doesn't need to output an object, even
though it's intended to map to props.
* As we pass the value of the headings to a render function later on,
they will be escaped anyway, so we can safely unscape them. Otherwise it
would display the escape characters literally.
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch 2 times, most recently from ef10817 to a2d326c Compare October 26, 2020 11:52
@@ -63,23 +63,23 @@ export class GalleryBlock {
{
name: 'slider',
label: getStyleLabel(
'Slider',
'The slider is a carousel of images. For more than 5 images, consider using a grid.'
__('Slider', 'planet4-blocks-backend'),
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 noticed this issue for the Submenu block, so I made these changes here as well already.


const renderMenuItems = (items) => {
return items.map(({ anchor, text, style, shouldLink, children }) => (
<li key={anchor} className={`list-style-${style || 'none'} ${shouldLink ? "list-link" : "list-heading"}`}>
Copy link
Contributor

@lithrel lithrel Oct 26, 2020

Choose a reason for hiding this comment

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

Some of the examples don't have an anchor (I think ?), so react raises an error

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `SubmenuItems`. See https://fb.me/react-warning-keys for more information.
    in li (created by SubmenuItems)

Maybe if there's no anchor we can use the array index as a key

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch 👌

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 used the title as an anchor in the example attributes

* The block content is based on headings extracted from the current
post, which can't be done when rendering the example of the block, used
in the block's preview in the inserter, and the previews of the
different styles. To still display a preview with content this adds an
`exampleHeadings` attribute, which is only set in the example, along
with an `isExample` attribute (this could also have checked the presence
of `exampleHeadings`, but the boolean seems more clear.
* Wrap block register call in a function instead of a constructor.
* Otherwise these will be shown literally. Not needed on the frontend as
there it comes from a querySelector which already only gets the text.
@Inwerpsel Inwerpsel force-pushed the planet-4811-use-get-blocks-in-editor branch from a2d326c to b86985f Compare October 26, 2020 15:53
@Inwerpsel Inwerpsel merged commit 64ab908 into master Oct 27, 2020
@Inwerpsel Inwerpsel deleted the planet-4811-use-get-blocks-in-editor branch October 27, 2020 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review UAT Passed User Acceptance Tests passed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants