-
Notifications
You must be signed in to change notification settings - Fork 20
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
Conversation
446ec65
to
319bd90
Compare
319bd90
to
70c3a39
Compare
70c3a39
to
6614087
Compare
48d7fc4
to
59b7636
Compare
4d1337b
to
5707528
Compare
ecbf147
to
dd44782
Compare
} | ||
|
||
function onHeadingChange(index, value) { | ||
let levels = JSON.parse(JSON.stringify(attributes.levels)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 😄
There was a problem hiding this comment.
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
2b554e6
to
0c810c2
Compare
Rebasing seems to have confused GitHub, it's showing commits in the wrong order here. However locally git log does have the right order 🤔 |
06129b6
to
2ac319f
Compare
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)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
d13f5e0
to
f80efb6
Compare
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.
ef10817
to
a2d326c
Compare
@@ -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'), |
There was a problem hiding this comment.
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"}`}> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch 👌
There was a problem hiding this comment.
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.
a2d326c
to
b86985f
Compare
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 theheaders (and potentially other blocks that can output a heading).
representation.
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).
backtop markup and style will be added to the base template in
PLANET-4811 Add backtop markup to base template planet4-master-theme#1166
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.