-
Notifications
You must be signed in to change notification settings - Fork 896
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
Implement annotations for Gutenberg #10265
Conversation
; Conflicts: ; js/dist/analysis-80-RC1.js ; js/dist/analysis-80-RC1.min.js ; js/dist/commons-80-RC1.js ; js/dist/commons-80-RC1.min.js ; js/dist/configuration-wizard-80-RC1.js ; js/dist/configuration-wizard-80-RC1.min.js ; js/dist/search-appearance-80-RC1.js ; js/dist/search-appearance-80-RC1.min.js ; js/dist/wp-seo-admin-80-RC1.js ; js/dist/wp-seo-admin-80-RC1.min.js ; js/dist/wp-seo-admin-global-80-RC1.js ; js/dist/wp-seo-admin-global-80-RC1.min.js ; js/dist/wp-seo-admin-gsc-80-RC1.js ; js/dist/wp-seo-admin-gsc-80-RC1.min.js ; js/dist/wp-seo-admin-media-80-RC1.js ; js/dist/wp-seo-admin-media-80-RC1.min.js ; js/dist/wp-seo-api-80-RC1.js ; js/dist/wp-seo-api-80-RC1.min.js ; js/dist/wp-seo-bulk-editor-80-RC1.js ; js/dist/wp-seo-bulk-editor-80-RC1.min.js ; js/dist/wp-seo-dashboard-widget-80-RC1.js ; js/dist/wp-seo-dashboard-widget-80-RC1.min.js ; js/dist/wp-seo-edit-page-80-RC1.js ; js/dist/wp-seo-edit-page-80-RC1.min.js ; js/dist/wp-seo-featured-image-80-RC1.js ; js/dist/wp-seo-featured-image-80-RC1.min.js ; js/dist/wp-seo-filter-explanation-80-RC1.js ; js/dist/wp-seo-filter-explanation-80-RC1.min.js ; js/dist/wp-seo-help-center-80-RC1.js ; js/dist/wp-seo-help-center-80-RC1.min.js ; js/dist/wp-seo-metabox-80-RC1.js ; js/dist/wp-seo-metabox-80-RC1.min.js ; js/dist/wp-seo-metabox-category-80-RC1.js ; js/dist/wp-seo-metabox-category-80-RC1.min.js ; js/dist/wp-seo-modal-80-RC1.js ; js/dist/wp-seo-modal-80-RC1.min.js ; js/dist/wp-seo-network-admin-80-RC1.js ; js/dist/wp-seo-network-admin-80-RC1.min.js ; js/dist/wp-seo-post-scraper-80-RC1.js ; js/dist/wp-seo-post-scraper-80-RC1.min.js ; js/dist/wp-seo-quick-edit-handler-80-RC1.js ; js/dist/wp-seo-quick-edit-handler-80-RC1.min.js ; js/dist/wp-seo-recalculate-80-RC1.js ; js/dist/wp-seo-recalculate-80-RC1.min.js ; js/dist/wp-seo-reindex-links-80-RC1.js ; js/dist/wp-seo-reindex-links-80-RC1.min.js ; js/dist/wp-seo-replacevar-plugin-80-RC1.js ; js/dist/wp-seo-replacevar-plugin-80-RC1.min.js ; js/dist/wp-seo-shortcode-plugin-80-RC1.js ; js/dist/wp-seo-shortcode-plugin-80-RC1.min.js ; js/dist/wp-seo-structured-data-blocks-80-RC1.js ; js/dist/wp-seo-structured-data-blocks-80-RC1.min.js ; js/dist/wp-seo-term-scraper-80-RC1.js ; js/dist/wp-seo-term-scraper-80-RC1.min.js ; js/dist/wp-seo-wp-globals-backport-80-RC1.js ; js/dist/wp-seo-wp-globals-backport-80-RC1.min.js ; js/src/edit.js ; js/src/wp-seo-post-scraper.js
@atimmer I checked https://github.com/Yoast/wordpress-seo/releases/tag/9.2-RC1 and I don't see any mention of the eye markers. Does this mean it's not yet ready for testing in 9.2-RC1 but may be included in an 9.2-RC2 or in the final 9.2 release? |
@designsimply We're planning on including this PR in at least one RC before the final 9.2 release. The first RC including it will either be RC2 or RC3. You can find the changelog for each RC on our releases page. |
The error was "Cannot read property 'getBlocks' of undefined". We need to actually check if the `core/editor` store is registered before checking if a certain method is available on that object.
Missing () made the code always try the Gutenberg method for marking.
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.
CR 👍 Only some documentation questions/requests. All other issues I found were already fixed in the previous 3 commits.
js/src/decorator/gutenberg.js
Outdated
const startOffset = marked.indexOf( startMark ); | ||
let endOffset = marked.indexOf( endMark ); | ||
|
||
endOffset = endOffset - startMark.length; |
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.
You are using endOffset
in two different 'meanings'* here , which is a little bit confusing.
*
offset from beginning of the text, and offset from the beginning of the mark
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.
Could be more clear with:
const endOffset = marked.indexOf( endMark ) - startMark.length;
Or:
endOffset = endOffset - startMark.length; | |
const matchedEndMark = marked.indexOf( endMark ); | |
const endOffset = matchedEndMark - startMark.length; |
js/src/decorator/gutenberg.js
Outdated
} | ||
|
||
/** | ||
* Calculates an annotation if the given mark is applicable tot he content of a block. |
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.
typo: to the
* So we try to find a mark index based on the mark content with all tags stripped. | ||
*/ | ||
if ( foundIndex === -1 ) { | ||
original = mark.getOriginal().replace( /(<([^>]+)>)/ig, "" ); |
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.
What's the difference between stripping all tags using this, and using stripHTMLTags
like above? Please comment.
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.
stripHTMLTags
in YoastSEO.js replaces HTML tags with one space, but we want to do another try where we replace HTML tags without replacing them with one space.
|
||
const offsets = getOffsets( mark ); | ||
|
||
const startOffset = foundIndex + offsets.startOffset; |
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.
Why do you need to add an offset to the foundIndex? Please add inline comment.
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.
The offsets.startOffset
and offsets.endOffset
are offsets of the <yoastmark>
relative to the start of the Mark
object. The foundIndex
is the index form the start of the RichText
until the matched Mark
, so to calculate the offset from the RichText
to the <yoastmark>
we need to add those two indexes/offsets.
Edit: This can probably be refactored to be more readable.
js/src/decorator/gutenberg.js
Outdated
const startOffset = foundIndex + offsets.startOffset; | ||
let endOffset = foundIndex + offsets.endOffset; | ||
|
||
// If the marks are at the beginning and the end we can use the length |
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.
Please turn into multline comment
* | ||
* @param {Paper} paper The paper that the marks are calculated on. | ||
* @param {Mark[]} marks The marks to annotate in the text. | ||
* @returns {void} |
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.
Newline before returns
js/src/decorator/gutenberg.js
Outdated
* @returns {void} | ||
*/ | ||
export function applyAsAnnotations( paper, marks ) { | ||
// Do this always to allow people to select a different eye marker. |
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.
... while/when another eye marker is still active
js/src/decorator/gutenberg.js
Outdated
|
||
// For every block... | ||
const annotations = flatMap( blocks, ( ( block ) => { | ||
// We go through every annotate able attribute. |
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.
annotatable
js/src/decorator/gutenberg.js
Outdated
* @param {string} blockTypeName The name of the block type. | ||
* @returns {string[]} The attributes that we can annotate. | ||
*/ | ||
function getAnnotateAbleAttributes( blockTypeName ) { |
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.
Annotatable
*/ | ||
initializeAnnotations() { | ||
if ( isAnnotationAvailable() ) { | ||
this._store.dispatch( setMarkerStatus( "enabled" ) ); |
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.
Does this interfere with other places where we dis-/enable the markers? For example, when we detect a pagebuilder
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.
It shouldn't. We check if the state for annotations is available and If so we put our marks as annotations in the annotation state. This is the most direct feature checking that's possible.
Acceptance: General testing (4.9.8 with Gutenberg plugin):
5.0.0-beta 3 with Gutenberg plugin development version (that should have annotations).
No breaking issues. 👍 |
Not working on classic editor using Gutenberg Manager plugin. Ref: #10265 (comment) |
The above issue is part of the |
Summary
This PR can be summarized in the following changelog entry:
Relevant technical choices:
wp-annotations
handle so I added that as a dependency. To make sure our scripts still load in older versions of Gutenberg I added a no-op script in our WP dependency registration.annotation-text-[source]
class, so I've added aannotation-text-yoast
style to get our desired mark color.core/quote
,core/paragraph
,core/list
andcore/heading
.window.requestIdleCallback
, this is to prevent freezing the browser while we are adding annotations. This can mean that it takes a bit longer before all annotations are rendered. This is expected behavior. It should never take longer than 1 second per annotation.Mark
objects and calculating where the the offsets within the block are.richText
to convert the HTML to be able to purely match the text inside block attributes. This breaks down if there is HTML in our marks, so I strip the marks of HTML. This can be made more sophisticated, but in my testing this was not necessary.Test instructions
This PR can be tested by following these steps:
Gutenberg <4.2
Gutenberg >4.3
This is not yet released and master doesn't have the relevant branch yet until this PR is merged: WordPress/gutenberg#7718. So for now, you need to check out that Gutenberg branch to be able to test this.
It should look something like this (I have updated the colors to match the classic editor since then):
Quality assurance
Fixes #11444