Skip to content

Commit

Permalink
AI Proofread: Target specific term occurrence (#38397)
Browse files Browse the repository at this point in the history
* rename file

* add helper functions

* fix complex word entry

* add the occurrence to the request payload

* changelog
  • Loading branch information
dhasilva authored Jul 18, 2024
1 parent e040fc9 commit 1867c87
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: other

AI Proofread: Target specific term occurrence
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// All phrases need to be lowercase
const phrases = {
'a and/or b': 'a or b or both',
'able to': 'can',
Expand Down Expand Up @@ -239,7 +240,7 @@ const phrases = {
'under the provisions of': 'under',
'until such time as': 'until',
utilize: 'use',
URL: 'link',
url: 'link',
validate: 'confirm',
viable: 'workable',
vice: 'instead of',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import React from 'react';
import { AiSVG } from '../../ai-icon';
import features from '../features';
import registerEvents from '../features/events';
import { getNodeTextIndex } from '../utils/get-node-text-index';
import { getNonLinkAncestor } from '../utils/get-non-link-ancestor';
import { numberToOrdinal } from '../utils/number-to-ordinal';
import highlight from './highlight';
import './style.scss';
/**
Expand Down Expand Up @@ -102,14 +105,24 @@ export default function Highlight() {

const handleSuggestions = () => {
const target = ( anchor as HTMLElement )?.innerText;
const sentence = ( anchor as HTMLElement )?.parentElement?.innerText as string;
const parent = getNonLinkAncestor( anchor as HTMLElement );
const sentence = parent?.innerText as string;
// Get the index of the target in the parent
const startIndex = getNodeTextIndex( parent as HTMLElement, anchor as HTMLElement );
// Get the occurrences of the target in the sentence
const targetRegex = new RegExp( target, 'gi' );
const matches = Array.from( sentence.matchAll( targetRegex ) ).map( match => match.index );
// Get the right occurrence of the target in the sentence
const occurrence = Math.max( 1, matches.indexOf( startIndex ) + 1 );
const ordinalOccurence = numberToOrdinal( occurrence );

setSuggestions( {
id,
target,
feature,
sentence,
blockId,
occurrence: ordinalOccurence,
} );
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { askQuestionSync } from '@automattic/jetpack-ai-client';
import { select } from '@wordpress/data';
import { getRequestMessages } from '../utils/getRequestMessages';
import { getRequestMessages } from '../utils/get-request-messages';

// ACTIONS

Expand Down Expand Up @@ -54,12 +54,14 @@ export function setSuggestions( {
target,
sentence,
blockId,
occurrence,
}: {
id: string;
feature: string;
target: string;
sentence: string;
blockId: string;
occurrence: string;
} ) {
return ( { dispatch } ) => {
dispatch( {
Expand All @@ -76,6 +78,7 @@ export function setSuggestions( {
target,
sentence,
blockId,
occurrence,
} ),
{
feature: 'jetpack-ai-breve',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export type BreveDispatch = {
target: string;
sentence: string;
blockId: string;
occurrence: string;
} ) => void;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Get the starting text index of a node's content within its parent's text content.
* Used to determine the position of a highlight within a sentence.
*/
export const getNodeTextIndex = ( parent: HTMLElement, node: HTMLElement ) => {
const nodes = Array.from( parent.childNodes );
const nodePosition = nodes.indexOf( node );

const nodesBefore = nodes.slice( 0, nodePosition );
const container = document.createElement( 'div' );

nodesBefore.forEach( n => container.appendChild( n.cloneNode( true ) ) );

return container.innerText.length;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Helper function to get the first non-link ancestor of an element.
* Used to determine the sentence context for a given word inside a link.
*/
export const getNonLinkAncestor = ( element: HTMLElement ) => {
let parent: HTMLElement | null = element?.parentElement ?? null;

while ( parent && parent.tagName === 'A' ) {
parent = parent.parentElement;
}

return parent;
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const requestTypeMap = {
// adjective: 'breve-adjective',
};

export const getRequestMessages = ( { feature, target, sentence, blockId } ) => {
export const getRequestMessages = ( { feature, target, sentence, blockId, occurrence } ) => {
const block = select( 'core/block-editor' ).getBlock( blockId );
const html = getBlockContent( block );
const dictionary = features?.find?.( ftr => ftr.config.name === feature )?.dictionary || {};
Expand All @@ -30,6 +30,7 @@ export const getRequestMessages = ( { feature, target, sentence, blockId } ) =>
sentence,
html,
replacement,
occurrence,
},
},
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Converts a number to an ordinal string.
* Used to inform the AI model of the position of the right word in a sentence.
*/
export const numberToOrdinal = ( number: number ) => {
const suffix = [ 'th', 'st', 'nd', 'rd' ];
const lastTwoDigits = number % 100;

return (
number + ( suffix[ ( lastTwoDigits - 20 ) % 10 ] || suffix[ lastTwoDigits ] || suffix[ 0 ] )
);
};

0 comments on commit 1867c87

Please sign in to comment.