Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions content-intelligence/dist/plugin.system.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { IAIRTEInstance } from "../../../content-intelligence/types";
declare global {
interface Window {
postRobot: any;
rte: IAIRTEInstance;
}
}
export declare const getAPISuggestion: (text: any) => Promise<any>;
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
declare const CI_Features: {
name: string;
isEnabled: boolean;
}[];
import { ICIFeatures } from "./types";
declare const CI_Features: ICIFeatures;
export declare const CIFeatureName: {
autoSuggestion: string;
spellCorrection: string;
};
export default CI_Features;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import { IAIRTEInstance } from '../types';
export declare const CIIcon: React.FC<{
rte: IAIRTEInstance;
}>;
export declare const CIComponent: (props: any) => JSX.Element;
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import './style.css';
export declare const contentIntelligenceIcon: (RTE: any) => any;
import { IRTEPluginInitializer } from '@contentstack/app-sdk/dist/src/RTE/types';
export declare const contentIntelligenceIcon: (RTE: IRTEPluginInitializer) => import("@contentstack/app-sdk/dist/src/RTE").RTEPlugin;
26 changes: 26 additions & 0 deletions content-intelligence/dist/types/content-intelligence/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { IRteParam } from "@contentstack/app-sdk/dist/src/RTE/types";
import { Node, NodeEntry } from "slate/dist/interfaces/node";
import { BaseRange } from "slate/dist/interfaces/range";
import { Text, TextInterface } from "slate/dist/interfaces/text";
import { EditorInterface } from "slate/dist/interfaces/editor";
interface IAdvRte {
Text: TextInterface;
Editor: EditorInterface;
addToDecorate: Function;
}
export interface ICIFeatures {
"autoSuggestion": boolean;
"spellCorrection": boolean;
}
interface extendedRTEParams {
CIFeatures: ICIFeatures;
CIAppResponse: {
spellResponse: {
incorrectWithSuggestedResponseMap: Map<string, Set<string>>;
};
};
_adv: IRteParam['_adv'] & IAdvRte;
}
export declare type IAIRTEInstance = IRteParam & extendedRTEParams;
export declare type IRTEDecorate = (entry: NodeEntry<Node | Text>) => Array<BaseRange>;
export {};
4 changes: 2 additions & 2 deletions content-intelligence/dist/types/plugin.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
declare const _default: Promise<{
ContentIntelligence: any;
ContentIntelligence: import("@contentstack/app-sdk/dist/src/RTE").RTEPlugin;
GrammarCheck: any;
SpellCheck: any;
SpellCheck: import("@contentstack/app-sdk/dist/src/RTE").RTEPlugin;
AutoSuggestion: any;
} | undefined>;
export default _default;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import "./style.css";
declare const SpellCheckTooltip: (props: any, handleClick: any) => JSX.Element;
declare const SpellCheckTooltip: (props: any) => JSX.Element;
export default SpellCheckTooltip;
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
declare const SpellComponent: (props: any, handleClick: any) => JSX.Element;
declare const SpellComponent: (props: any) => JSX.Element;
export default SpellComponent;
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,14 @@ declare global {
postRobot: any;
}
}
export declare const getSpellSuggestion: (text: any) => Promise<any>;
interface ISpellCorrectionDTO {
"incorrect_input": string;
"corrected_input": Array<string>;
"start_offset": number;
"end_offset": number;
}
interface ISpellCheckResponse {
contentToReplace: Array<ISpellCorrectionDTO>;
}
export declare const getSpellSuggestion: (body: string) => Promise<ISpellCheckResponse>;
export {};
3 changes: 2 additions & 1 deletion content-intelligence/dist/types/spell-check/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import "./style.css";
export declare const createSpellCheck: (RTE: any) => any;
import { IRTEPluginInitializer } from "@contentstack/app-sdk/dist/src/RTE/types";
export declare const createSpellCheck: (RTE: IRTEPluginInitializer) => import("@contentstack/app-sdk/dist/src/RTE").RTEPlugin;
16 changes: 16 additions & 0 deletions content-intelligence/dist/types/spell-check/utils/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { IAIRTEInstance, IRTEDecorate } from '../../content-intelligence/types';
export declare const reRenderElement: (rte: IAIRTEInstance) => void;
export declare const triggerSpellCheck: (rte: IAIRTEInstance, text: string) => Promise<never[] | undefined>;
export declare const debouncedTriggerSpellCheck: ((updatedRTE: IAIRTEInstance) => Promise<void>) & {
clear(): void;
} & {
flush(): void;
};
export declare const spellCheckDecorate: (rte: IAIRTEInstance) => IRTEDecorate;
export declare const getEntriesStringForRTE: (rte: IAIRTEInstance) => string;
export declare const triggerSpellCheckForCompleteRTE: (rte: IAIRTEInstance) => void;
export declare const debouncedTriggerSpellCheckForCompleteRTE: ((rte: IAIRTEInstance) => void) & {
clear(): void;
} & {
flush(): void;
};
16 changes: 12 additions & 4 deletions content-intelligence/src/content-intelligence/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react';
import isHotkey from 'is-hotkey'
import CI_Features from './ciFeatures';

import './style.css'
import { IRTEPluginInitializer } from '@contentstack/app-sdk/dist/src/RTE/types';
import { IAIRTEInstance } from './types';
import { debouncedTriggerSpellCheck, getEntriesStringForRTE, spellCheckDecorate, triggerSpellCheck } from '../spell-check/utils';
import { debouncedTriggerSpellCheck, debouncedTriggerSpellCheckForCompleteRTE, getEntriesStringForRTE, spellCheckDecorate, triggerSpellCheck, triggerSpellCheckForCompleteRTE } from '../spell-check/utils';
import { CIComponent, CIIcon } from './components';

export const contentIntelligenceIcon = (RTE: IRTEPluginInitializer) => {
Expand All @@ -20,8 +21,7 @@ export const contentIntelligenceIcon = (RTE: IRTEPluginInitializer) => {
rte._adv.addToDecorate(handleDecorate);

// To execute the spell check for first time.
const initialRTEStringContent = getEntriesStringForRTE(rte)
triggerSpellCheck(rte, initialRTEStringContent)
triggerSpellCheckForCompleteRTE(rte)

return ({
title: 'Content Intelligence',
Expand All @@ -43,8 +43,16 @@ export const contentIntelligenceIcon = (RTE: IRTEPluginInitializer) => {
})

ContentIntelligence.on('keydown', async (props) => {
const { rte } = props
const { rte, event } = props
const updatedRTE: IAIRTEInstance = rte as any
if(isHotkey('mod',event)){
// Early return if ctrl
return
}
if(isHotkey('mod+v',event) || isHotkey('mod+x',event)){
debouncedTriggerSpellCheckForCompleteRTE(updatedRTE)
return
}
debouncedTriggerSpellCheck(updatedRTE)
})
return ContentIntelligence
Expand Down
8 changes: 4 additions & 4 deletions content-intelligence/src/spell-check/SpellCheckTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
//@ts-ignore
import "./style.css";

const SpellCheckTooltip = (props: any, handleClick: any) => {
const SpellCheckTooltip = (props: any) => {
const correctOptionsSet: Set<string> = props?.leaf?.['spell-check'] || new Set()
const correctOptionsArray = Array.from(correctOptionsSet)
return (
Expand All @@ -15,13 +15,13 @@ const SpellCheckTooltip = (props: any, handleClick: any) => {
</div>
<div style={{display: "flex"}}>
{
correctOptionsArray.map((spelling: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined) => {
correctOptionsArray.map((spelling) => {
return(
<div className="spell-suggestions-wrapper">
<div className="spell-suggestions-wrapper" key={spelling}>
<span className="spell-suggestions"
onClick={() => {
props.setVisible(false)
props.handleClick(spelling)
props.handleClick(props.leaf.text, spelling)
}}
>
{spelling}
Expand Down
3 changes: 1 addition & 2 deletions content-intelligence/src/spell-check/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import React from "react";
import { getSpellSuggestion } from "./getSpellSuggestion";
import "./style.css";
import SpellComponent from "./SpellComponent";
import isHotkey from 'is-hotkey'
import { IRTEPluginInitializer } from "@contentstack/app-sdk/dist/src/RTE/types";
import { IAIRTEInstance } from "../content-intelligence/types";

export const createSpellCheck = (RTE: IRTEPluginInitializer) => {
//@ts-ignore
const SpellCheckPlugin = RTE("spell-check", (rte: IAIRTEInstance) => {
const handleClick = (spelling:string) => {
const handleClick = (incorrectSpell:string,spelling:string) => {
rte._adv.Transforms.move(rte._adv.editor,{unit:"word"})
rte._adv.editor.deleteBackward("word")
rte._adv.Editor.insertText(rte._adv.editor, spelling);
Expand Down
24 changes: 17 additions & 7 deletions content-intelligence/src/spell-check/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,18 @@ export const spellCheckDecorate = (rte: IAIRTEInstance) => {
return ranges;
}

const wordsInText = node.text.split(" ")
wordsInText.reduce((actualIndex, word, indexOfWordInArray) => {
if (spellResponse.incorrectWithSuggestedResponseMap.has(word)) {
const wordsInText = node.text.split(/[ ,]/)
const _totalLength = wordsInText.reduce((actualIndex, word, _indexOfWordInArray) => {
const lowerCaseWord = word.toLowerCase()
if (spellResponse.incorrectWithSuggestedResponseMap.has(lowerCaseWord)) {
ranges.push({
//@ts-ignore
"spell-check": spellResponse.incorrectWithSuggestedResponseMap.get(word),
"spell-check": spellResponse.incorrectWithSuggestedResponseMap.get(lowerCaseWord),
anchor: { path, offset: actualIndex },
focus: { path, offset: actualIndex + word.length },
focus: { path, offset: actualIndex + lowerCaseWord.length },
});
}
return actualIndex + word.length + 1
return actualIndex + lowerCaseWord.length + 1
}, 0)
return ranges;
};
Expand All @@ -74,4 +75,13 @@ export const spellCheckDecorate = (rte: IAIRTEInstance) => {

export const getEntriesStringForRTE = (rte: IAIRTEInstance) => {
return rte._adv.Editor.string(rte._adv.editor, [0], { voids: true })
}
}

export const triggerSpellCheckForCompleteRTE = (rte: IAIRTEInstance) => {
const initialRTEStringContent = getEntriesStringForRTE(rte)
triggerSpellCheck(rte, initialRTEStringContent)
.finally(() => {
reRenderElement(rte)
})
}
export const debouncedTriggerSpellCheckForCompleteRTE = debounce(triggerSpellCheckForCompleteRTE, 500)
Loading