Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@grammarly/editor-sdk

Package Overview
Dependencies
Maintainers
7
Versions
120
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@grammarly/editor-sdk - npm Package Compare versions

Comparing version 1.3.3 to 1.3.4

1081

lib/index.d.ts

@@ -20,3 +20,295 @@ /**

import { CAPIConnection } from '@grammarly/core-clients/esm/capi';
import { Delta } from '@grammarly/core-clients/esm/ot';
import { RawAlert, AbsRawTransform, CAPI } from '@grammarly/core-clients';
import { Emotion } from '@grammarly/core-clients/esm/capi/emotions';
/**
*
* @packageDocumentation
* @license
* (c) Copyright 2021 Grammarly, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Type of alert used to decide color in UI (eg underlines)
*/
declare const enum AlertDisplayType {
critical = "critical",
advanced = "advanced",
clarity = "clarity",
engagement = "engagement",
tone = "tone",
originality = "originality",
vox = "vox"
}
declare type Alert = RawAlert.WithPosition & {
displayType: AlertDisplayType;
sortOrder: number;
priority: number;
transformJson?: AbsRawTransform;
};
/**
* @internal
*/
interface Disposable {
/**
* @internal
*/
dispose: () => void | Promise<void>;
}
/**
* Interface for event listeners registered in {@link EventEmitter}
*
* @public
*/
declare type EventListener<T> = (event: Event<T>) => void | Promise<void>;
/**
* Interface for events dispatched by {@link EventEmitter}
*
* @public
*/
declare class Event<T> {
/**
* Event name
*
* @public
*/
readonly type: string;
/**
* Event payload
*
* @public
*/
readonly detail: T;
constructor(name: string, detail: T);
}
/**
* Emits events much like Node's {@link https://nodejs.org/docs/latest/api/events.html#events_class_eventemitter | EventEmitter}.
*
* @remarks
* ```ts
* editor.addEventListener("openOAuthUrl", event => {
* const url = event.detail
* // ...
* })
* ```
* The variable `editor` is an instance of Editor which implements {@link EventEmitter} interface.
*
* @public
*/
declare class EventEmitter<T> implements Disposable {
private _listeners;
/**
* This property is used for type inference.
*
* @internal
* @deprecated - This is a type only property. It does not exist.
*/
__type_helper_: T;
/**
* Register a function to be called whenever a specified event is emitted.
*
* @public
*/
addEventListener<E extends string & keyof T>(event: E, listener: EventListener<T[E]>): void;
/**
* Remove a previously added listener function.
*
* @public
*/
removeEventListener<E extends string & keyof T>(event: E, listener: EventListener<T[E]>): void;
/**
* Trigger listeners for an event.
*
* @internal
*/
dispatchEvent<E extends string & keyof T>(event: E, detail: T[E]): void;
/**
* @internal
* @deprecated - Use {@link EventEmitter#dispatchEvent}
*/
protected emit<E extends string & keyof T>(event: E, detail: T[E]): void;
/**
* Clear all event listeners.
*
* @internal
*/
dispose(): void;
}
declare type KeyOf<T> = T extends object ? string & keyof T : never;
declare type ModelEvents<T extends object> = {
[K in KeyOf<T> | "@updated"]: K extends "@updated" ? Array<KeyOf<T>> : K extends KeyOf<T> ? {
value: T[K];
previousValue: T[K];
} : never;
};
interface Readable<T extends object> {
get: <K extends KeyOf<T>>(key: K) => T[K];
}
declare type Immutable<T> = T extends Array<infer I> ? ReadonlyArray<Immutable<I>> : T extends Set<infer I> ? ReadonlySet<Immutable<I>> : T extends Map<infer K, infer V> ? ReadonlyMap<K, Immutable<V>> : T extends Date | Function | RegExp ? T : T extends object ? {
readonly [K in keyof T]: Immutable<T[K]>;
} : T;
declare type ReadonlyModel<T extends object> = Immutable<T> & Readable<T> & EventEmitter<ModelEvents<T>>;
interface Manager<T extends object> {
readonly state: ReadonlyModel<T>;
}
declare type TextEncoderEvents = {
change: {
changes: Delta;
previous: {
delta: Delta;
textLength: number;
};
next: {
delta: Delta;
textLength: number;
};
};
};
interface TextState {
transformedPlainText: string | null;
originalText: Delta;
transformedText: Delta;
length: number;
}
interface CursorInfo {
oldRange: {
index: number;
/** Selection length */
length: number;
};
newRange: {
index: number;
length: number;
};
}
/**
* @experimental
*/
interface TextTransformer {
encode: (text: Delta) => Delta;
decode: (text: Delta) => Delta;
getOriginalPosition: (position: number) => number;
getTransformedPosition: (position: number) => number;
}
declare class TextManager extends EventEmitter<TextEncoderEvents> {
protected readonly transformer: TextTransformer;
protected readonly state: TextState;
constructor(transformer?: TextTransformer);
/**
* Processed text for CAPI
*/
get delta(): Delta;
/**
* Length of processed text
*/
get textLength(): number;
/**
* Update text using transformer.
*
* @param originalText Text as viewed by user.
*/
setText(originalText: Delta | string, cursor?: number | CursorInfo): void;
/**
* Update text using transformer.
*
* @param changes text changes from previous state
*/
applyEdits(changes: Delta): void;
toText(): string;
getOriginalText(changesInTransformedText: Delta): Delta;
reset(): void;
}
declare type Suggestion = Alert;
declare type SuggestionId = Suggestion["id"];
declare type SuggestionProviderEvents = {
suggestionAdded: Suggestion[];
suggestionRemoved: Suggestion[];
};
declare const enum DismissReason {
UNKNOWN = 0,
INCORRECT = 1,
OFFENSIVE = 2
}
interface SuggestionProvider extends EventEmitter<SuggestionProviderEvents> {
accept: (id: SuggestionId, index?: number) => Promise<void>;
dismiss: (id: SuggestionId, reason?: DismissReason) => Promise<void>;
}
declare type AlertActivationSource = "hover" | "keyboard" | "manual";
declare type Events$1 = {
/** @deprecated Use `state.active` */
active: {
alert: Alert | undefined;
source: AlertActivationSource;
};
/** @deprecated Use `"suggestionAdded"` */
added: Alert;
/** @deprecated Use `"suggestionRemoved"` */
removed: Alert;
/** @deprecated Use `state.suggestions` */
change: Alert[];
};
/** @deprecated Use `SuggestionManager` */
declare class AlertManager extends EventEmitter<Events$1> {
private readonly _compat;
private readonly _suggestions;
constructor(source: TextManager, providers?: SuggestionProvider[]);
private _createFakeSuggestionProvider;
/**
* @deprecated Use `clear()`
*/
reset(): void;
/**
* @deprecated Use `setActiveSuggestion()`
*/
setActiveAlert(id: RawAlert.Id | undefined, source: AlertActivationSource): void;
/**
* @deprecated Use `getSuggestion()`
*/
getAlert(id: Alert["id"]): Alert | null;
/**
* @deprecated Use `SuggestionProvider`
*/
addRawAlert(rawAlert: RawAlert): void;
/**
* @deprecated Use `SuggestionProvider`
*/
addAlert(alert: Alert): void;
/**
* @deprecated Use `SuggestionProvider`
*/
removeAlert(id: Alert["id"]): void;
/**
* @deprecated Use `SuggestionManager.state.suggestions`
*/
getAllAlerts(): Alert[];
}
/**
* Categories of suggestions that can be muted.

@@ -105,3 +397,3 @@ *

*
* @defaultValue true
* @defaultValue false
*/

@@ -170,2 +462,3 @@ PassiveVoice?: boolean;

}
declare type MutedCategory = keyof SuggestionCategories;

@@ -245,2 +538,15 @@ /**

/**
* Configuration for connected accounts
*
* @public
*/
interface OAuthConfig {
/**
* URI to redirect to after successful account connection.
*
* @public
*/
redirectUri: string;
}
/**
* Configuration to customize the Grammarly integration.

@@ -270,2 +576,6 @@ *

/**
* Configuration for connected accounts.
*/
oauth?: OAuthConfig;
/**
* Callback to receive stats about the user-entered text and Grammarly session.

@@ -348,4 +658,8 @@ */

*/
declare type Dialect = "american" | "british" | "canadian" | "australian" | "auto-text" | "auto-browser"
/** @deprecated - Use "auto-browser" instead */
declare type Dialect = "american" | "british" | "canadian" | "australian"
/** @since 1.3.0 */
| "auto-text"
/** @since 1.3.0 */
| "auto-browser"
/** @deprecated since 1.3.0 - Use "auto-browser" instead */
| "auto";

@@ -362,3 +676,726 @@ /**

interface AppClientInfo {
/** @deprecated Use clientId (appId can be resolved from it) */
appId: string;
clientId: string;
oauthEnabled: boolean;
type?: "Web" | "Desktop";
}
declare type ConnectedAccountStatus = "connected" | "disconnected" | "failed";
interface OAuthCallbackResponse {
code: string;
codeVerifier: string;
}
interface OAuthRequest {
origin: string;
authorizeUrl: string;
codeVerifier: string;
}
declare type OAuthAuthorizationMode = "web_message" | "redirect";
interface OAuthRequestInit {
mode: OAuthAuthorizationMode;
redirectUri: string;
scopes: Array<"grammarly.capi.all">;
state?: string;
}
declare type User$1 = {
id: string;
isAnonymous: boolean;
};
declare type State = {
clientInfo: AppClientInfo | null;
user: User$1 | null;
connectedAccountStatus: ConnectedAccountStatus | null;
activeRequest: OAuthRequest | null;
};
declare class AuthManager implements Manager<State> {
private readonly _storage;
private readonly _state;
private readonly _oauth;
private readonly _anonymous;
private readonly _session;
private readonly _logger;
private readonly _clientId;
/**
* Resolves when AppInfo is available.
*/
private readonly _isReady;
constructor(clientId: string, storage: Storage);
get state(): ReadonlyModel<State>;
/**
* @deprecated Use `createAccessToken()`
*/
getAccessToken(): Promise<string>;
createAccessToken(): Promise<string>;
/**
* Clear connected account status.
*/
setAccountStatus(status: null): Promise<void>;
createOAuthRequest(options: OAuthRequestInit): Promise<OAuthRequest | null>;
handleOAuthCallback({ code, codeVerifier }: OAuthCallbackResponse): Promise<void>;
logout(): Promise<void>;
/**
* @deprecated Use `state.connectedAccountStatus`
*/
getAccountStatus(): ConnectedAccountStatus | null;
/**
* @deprecated Use `createOAuthRequest()`
*/
getAuthorizeUrl(params: OAuthRequestInit): Promise<OAuthRequest | null>;
/**
* @deprecated Use `handleOAuthCallback()`
*/
exchangeAuthorizationCode(code: string, codeVerifier: string): Promise<void>;
getClientId(): string;
/**
* @deprecated Use `state.user`
*/
getUser(): User$1 | null;
/**
* @deprecated Use clientId instead
*/
getAppId(): string | null;
/**
* Set active request,
* which will be unset when {@link AuthManager.handleOAuthCallback} is called
* with corresponding {@link OAuthRequest.codeVerifier}.
*/
setActiveOAuthRequest(request: State["activeRequest"]): void;
private _handleConnectedAccountStatusChange;
private _onLoginSuccess;
private _saveRefreshToken;
private _authenticate;
}
declare type Events = {
userAccountStatusChange: null;
userTokenChange: null;
reconnect: null;
};
/**
* @deprecated Use `AuthManager`
*/
declare class AuthService extends AuthManager {
private readonly events;
constructor({ clientId }: {
clientId: string;
});
addEventListener<E extends string & keyof Events>(event: E, listener: EventListener<Events[E]>): void;
removeEventListener<E extends string & keyof Events>(event: E, listener: EventListener<Events[E]>): void;
}
declare type CAPIConnectionManagerEvents = {
error: Error;
suggestionAdded: CAPI.AlertReceived;
suggestionRemoved: CAPI.AlertRemoved;
emotions: CAPI.EmotionsReceived;
textInfo: CAPI.TextInfoReceived;
idle: null;
status: "checking" | "idle";
};
declare enum RejectReason {
UNKNOWN = 0,
INCORRECT = 1,
OFFENSIVE = 2
}
declare class CAPIConnectionManager extends EventEmitter<CAPIConnectionManagerEvents> {
private readonly authService;
private options;
private readonly _logger;
private lastSyncedAt;
private isSyncing;
private isPaused;
constructor(authService: AuthService, options?: Pick<EditorConfig, "suggestions" | "document" | "onTextStats">);
setConfig(options: Pick<EditorConfig, "suggestions" | "document" | "onTextStats">): void;
/**
* CAPI text checking status.
*/
get checkingStatus(): CAPI.CheckingState | undefined;
/**
* Instance of CAPIConnection, available when connected.
*/
get socket(): CAPIConnection | undefined;
/**
* Update editor text state.
*
* If needed, it also starts CAPI connection.
*
* @param text Current text in the editor
*/
setText(text: string | Delta): void;
/**
* Stop sending messages to CAPI
*/
pause(): void;
/**
* If paused, restart sending messages to CAPI
*/
resume(): void;
disconnect(): Promise<void>;
/**
* Accept a suggestion.
*
* @param id Suggestion id.
* @param index Index of the replacement the user selected
*/
acceptSuggestion(id: RawAlert.Id, index: number): Promise<void>;
muteCategories(categories: MutedCategory[]): Promise<void>;
unmuteCategories(categories: MutedCategory[]): Promise<void>;
/**
* Reject a suggestion.
*
* @param id Suggestion id.
*/
rejectSuggestion(id: RawAlert.Id, reason: RejectReason): Promise<void>;
/**
* Feedback on detected tone.
*/
provideToneFeedback(emotionName: string, type: CAPI.EmotionFeedbackType): Promise<void>;
setPlagiarism(isEnabled: boolean): Promise<void>;
private readonly text;
private connection?;
private connectionPromise?;
private getConnection;
private withConnection;
private getCapiConnectionOptions;
private connectionRetries;
private connect;
/**
* Synchronize local text state with CAPI, if needed.
*/
private sync;
private publishState;
private sendFeedback;
private onFatalError;
}
interface FeedbackPayload {
rating: number;
comment: string;
url: string;
containerId: string;
documentId?: string;
}
declare class FeedbackService {
private readonly authService;
constructor(authService: AuthService);
submitFeedback(payload: FeedbackPayload): Promise<void>;
}
declare const enum GrammarlyStatus {
pending = "pending",
loading = "loading",
error = "error",
disabledByUser = "disabledByUser",
disabledByExtension = "disabledByExtension",
ok = "ok"
}
interface EncodedText {
delta: Delta;
offsets: Array<[number, Text]>;
inverseOffsets: Map<Text, number>;
}
/**
*
* @packageDocumentation
* @license
* (c) Copyright 2021 Grammarly, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare type EditorElement = HTMLInputElement | HTMLTextAreaElement | HTMLElement;
declare class EditorTextManager extends TextManager {
private _editor?;
private offsets;
private cleanup;
private readonly _logger;
get editor(): EditorElement;
connect(editor: EditorElement): void;
disconnect(): void;
setText(originalText: Delta | string, cursor?: number | CursorInfo): void;
/**
* Get DOM Range with transformed position.
*
* @param start start position in transformed text.
* @param end end position in transformed text.
*/
getRange(start: number, end: number): Range;
getPosition(start: number): Range;
private getTextMapping;
}
interface Highlight {
alert: Alert;
element: HTMLDivElement;
}
declare class HighlightContainer {
static create(): HighlightContainer;
/**
* A root container for highlights.
*
* This is a statically positioned block element.
* The static position and block display, place it at the bottom of the editor
* viewport, which enables us to compute the relative offset of highlights
* from the top-left corner of the editor viewport.
*/
readonly element: HTMLDivElement;
/**
* A wrapper element for scrolling highlights as a group.
*
* `transform: translate()` is synced with scroll position of the editor to scroll
* highlights in the viewport.
*/
readonly scroller: HTMLDivElement;
/**
* A wrapper element to clip overflowing highlights to match the editor viewport.
*/
readonly viewport: HTMLDivElement;
/**
* Set viewport height
*/
setHeight(height: number): void;
/**
* Set viewport width
*/
setWidth(width: number): void;
/**
* Move vieport such that it's on top the editor
*/
setOffset(x: number, y: number): void;
constructor();
}
interface Position {
x: number;
y: number;
}
declare type HighlightDisplayMode =
/** Show all alerts. */
"all"
/** Show critical alerts. */
| "corrective"
/** Show no alerts */
| "none";
declare type HighlightManagerEvents = {
mouseenter: {
highlight: Highlight;
event?: MouseEvent;
};
mouseleave: {
highlight: Highlight;
event?: MouseEvent;
};
viewport: {
size: {
width: number;
height: number;
};
offset: Position;
};
};
interface DOMRectLike {
x: number;
y: number;
width: number;
height: number;
}
declare type EditorKind = "plain" | "rich";
declare class HighlightManager extends EventEmitter<HighlightManagerEvents> {
protected readonly textManager: EditorTextManager;
private _kind;
private readonly _logger;
get kind(): EditorKind;
private readonly resizeObserver;
private readonly hasViewportWidthChanged;
private readonly hasEditorWidthChanged;
private readonly highlights;
private prevAlerts;
private readonly renderWorker;
private _target?;
private _editor?;
private _viewport?;
protected readonly container: HighlightContainer;
protected activeHighlightId?: Alert["id"];
/** Offset position in text, after which highlights needs rendering. */
protected dirtyAfterIndex: number;
protected lastScrollState: {
top: number;
left: number;
};
get editor(): EditorElement;
get viewport(): HTMLElement;
private originalSpellCheck;
get text(): EncodedText;
private _displayMode;
get displayMode(): HighlightDisplayMode;
/**
* Triggers a full rerender when mode changes.
*/
set displayMode(mode: HighlightDisplayMode);
constructor(textManager: EditorTextManager);
private _isConnected;
get isConnected(): boolean;
connect(target?: HTMLElement | null): void;
disconnect(): void;
setViewport(viewport: HTMLElement): void;
clearViewport(): void;
setEditor(editor: EditorElement): void;
clearEditor(): void;
render(alerts?: Alert[]): void;
getHighlight(alertId: Alert["id"]): Highlight | undefined;
getHighlightRect(alertId: Alert["id"]): DOMRectLike | null;
setHoverState(alertId: Alert["id"], isHovered: boolean): void;
/**
* BoundingClientRect of the highlights wrapper element
* before highlights should be updated. This can be used
* to compute relative position of the highlights for non-mirrored
* elements.
*/
protected currentReferenceClientRect: DOMRect;
private updateAll;
private readonly renderCandidates;
private readonly dom;
private setAlerts;
private createRenderTask;
private shouldDisplayAlert;
private isRendering;
/**
* Lazily render out-of-viewport highlights.
*/
private scheduleDelayedRender;
private updateHighlight;
private getHighlightClass;
private createHighlightElement;
private createUnderlineElements;
/**
* Update visible highlight as per editor scroll state.
*/
private readonly scrollWorker;
private readonly onScrollEvent;
private readonly onKeyboardScroll;
/**
* Compute custom hover event for highlights.
*/
private readonly onMouseEvent;
private readonly onMouseLeaveEvent;
private _viewportOffset;
get viewportOffset(): Readonly<Position>;
private prevViewportRect?;
/**
* Callback to handle change in viewport size.
*/
private readonly synchronizeViewport;
/**
* Set currently visible highlight.
*/
setActiveHighlight(highlightId?: RawAlert.Id): void;
/**
* Fire fake/custom mouse enter/leave event for highlight.
*
* @param highlight activated highlight.
* @param event active highlight change is triggered by the event.
*/
private setActiveHighlightWithMouse;
private getMousePosition;
private getPlainTextMousePosition;
private getRichTextMousePosition;
private getHighlightPosition;
}
interface EditorManagerLike extends EventEmitter<EditorManagerEvents> {
instanceId: number;
authService: AuthService;
editor: HTMLElement;
pluginElement: HTMLElement;
alerts: AlertManager;
highlights: HighlightManager;
status: GrammarlyStatus;
connection: CAPIConnectionManager;
disablePlugin: (reason: PluginDisableReason) => void;
showUnderlines: () => void;
hideUnderlines: () => void;
}
declare type EditorManagerEvents = {
connected: null;
disconnected: null;
status: GrammarlyStatus;
};
declare type GButtonManagerEvents = {
alertCount: number;
status: GrammarlyStatus;
};
declare class GButtonManager extends EventEmitter<GButtonManagerEvents> {
private readonly managerState;
private _lastLoggedGButtonShowEvent;
private _status;
private readonly _logger;
private static primaryManager;
private static instance?;
static underlinesVisible: boolean;
static getInstance(): GButtonManager;
private constructor();
get status(): GrammarlyStatus;
hasVisibleAlerts(): boolean;
hasPrimary(): boolean;
isPrimary(manager: EditorManagerLike): boolean;
setPrimary(manager: EditorManagerLike): void;
register(manager: EditorManagerLike): void;
deregister(manager: EditorManagerLike): void;
private syncManagers;
private handleStatusChange;
private publishAlertChanges;
disablePlugin(reason: PluginDisableReason): void;
updateShowUnderlines(visible: boolean): void;
private getPageOrderAlerts;
private scrollToHighlight;
showFirstHighlight(): void;
}
declare type ToneManagerEvents = {
change: {
emotions: Emotion[];
};
};
interface ToneManagerState {
emotions: Emotion[];
cleanup: () => void;
}
declare class ToneManager extends EventEmitter<ToneManagerEvents> {
private readonly managerState;
private currentState;
private static primaryManager;
private static instance?;
static getInstance(): ToneManager;
private constructor();
private readonly _logger;
get emotions(): ToneManagerState["emotions"];
hasPrimary(): boolean;
isPrimary(manager: EditorManagerLike): boolean;
setPrimary(manager: EditorManagerLike): void;
private emotionsChanged;
register(manager: EditorManagerLike): void;
private handleFocus;
private isInsidePlugin;
handleBlur(event: FocusEvent): void;
private reset;
private publishCurrent;
deregister(manager: EditorManagerLike): void;
}
declare type ExtensionEvents = {
status: {
detected: boolean;
};
};
declare class ExtensionManager extends EventEmitter<ExtensionEvents> {
private readonly extensionLoadedWorker;
private readonly attrObserver;
private readonly elementObserver;
private readonly integrationElementObserver;
private static instance?;
static getInstance(): ExtensionManager;
private constructor();
private readonly _logger;
connect(): void;
disconnect(): void;
private readonly references;
private isActive;
register(reference: any): void;
deregister(reference: any): void;
private checkForEnabledGrammarlyExtension;
private checkIntegrationElementMutations;
private checkElementMutations;
private checkAttributeMutations;
private readonly publishStatus;
}
/**
* Coordination with Llama aka Grammarly Desktop
*
* @remarks
* Llama is restricted to only reading ids and CSS classes, so we use CSS classes.
* We currently never get any state _from_ Llama because it cannot modify the page.
*/
declare class LlamaManager {
/** Element modified with flag that Llama can read. */
private element;
private readonly cleanups;
private readonly _logger;
connect(manager: EditorManagerLike): void;
private setClassFlag;
private onStatusChange;
disconnect(): void;
}
/**
* @private
*
* Unified controller for Grammarly enhanced editors.
*/
declare class EditorManager extends EventEmitter<EditorManagerEvents> implements EditorManagerLike {
readonly clientId: string;
readonly pluginElement: HTMLElement;
readonly authService: AuthService;
readonly connection: CAPIConnectionManager;
readonly feedback: FeedbackService;
private readonly _logger;
constructor(clientId: string, pluginElement: HTMLElement);
readonly instanceId: number;
readonly textManager: EditorTextManager;
readonly extensionManager: ExtensionManager;
readonly llamaManager: LlamaManager;
readonly gbuttonManager: GButtonManager;
readonly toneManager: ToneManager;
readonly alerts: AlertManager;
readonly highlights: HighlightManager;
private _status;
private _config;
private _isConnected;
get isConnected(): boolean;
private _cleanups;
private _rootStyles;
private _zIndex;
/**
* Should copy styles from viewport to wrapper web component?
*
* `"auto"` is used for [data-grammarly] and `withElement()`.
* `"none"` set `rootStyles` is always `null`, used in declarative web-component/react/vue APIs.
*
* @internal
*/
styleMode: "auto" | "none";
/**
* Styles inherited from viewport.
*/
get rootStyles(): CSSStyleDeclaration | null;
/**
* z-index for rendering UI above editor
*/
get zIndex(): number | null;
get editor(): EditorElement;
get viewport(): HTMLElement;
get status(): GrammarlyStatus;
get user(): User$1 | null;
get text(): Delta;
get config(): Readonly<EditorConfig>;
connect(editor: EditorElement, viewport?: HTMLElement): void;
disconnect(): void;
private readonly refreshConnection;
/**
* The plugin begins in "pending" state until user activates eg by focus.
* Exception: when the plugin is triggered using imperative API.
*/
activate(): void;
/**
* User has chosen to disable the plugin.
*/
disablePlugin(reason: PluginDisableReason): void;
/**
* User has chosen to visually hide underlines.
*/
hideUnderlines(): void;
/**
* User has chosen to undo hiding underlines.
*/
showUnderlines(): void;
/**
* Applies replacement to the editor and dispatches input events
* as defined in https://w3c.github.io/input-events/
*
* @returns true if alert replacement is applied, false otherwise
*/
applyAlertReplacement(alert: Alert, options: {
index?: number;
}): Promise<boolean>;
setConfig(config: Partial<EditorConfig>): void;
private updateStatus;
private setStatus;
/**
* Turns off the plugin. Status error can not be recovered from.
*/
handleFatalError(error: Error): void;
private handleExtensionStatus;
private setupManagers;
private readonly onTextStats;
private syncEditorWithCAPI;
}
/**
* @public
*
* A web component to encapsulate DOM elements rendered
* for displaying highlights and suggestion cards.
*/
declare class GrammarlyEditorPluginElement extends HTMLElement {
static observedAttributes: never[];
private readonly editor?;
private readonly viewport?;
constructor();
private isUsingManualConnect;
private readonly editorDetector;
set clientId(value: string);
get clientId(): string;
private _config?;
get config(): Partial<EditorConfig>;
set config(config: Partial<EditorConfig>);
connect(editor: EditorElement, viewport?: HTMLElement): void;
connectedCallback(): void;
disconnectedCallback(): void;
adoptedCallback(): void;
attributeChangedCallback(): void;
/**
* Delete a set property before the web component definition has been loaded so that the setters can be called.
* @see https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
*/
private upgradeProperty;
private updateStyle;
private render;
private readonly _tryAutoConnect;
private _startWatchingSubTree;
private _startWatchingEditor;
/**
* @returns true when new editor is connected.
*/
private _connect;
/**
* Create editor manager if client ID is available.
*/
private createManager;
private shouldAutoDetectEditor;
}
/**
* @internal
*/
interface EditorInitOptions {
manager: EditorManager;
plugin: GrammarlyEditorPluginElement;
editor: HTMLElement;
viewport?: HTMLElement;
}
/**
* An instance of Editor represents an HTML editor from your app enhanced with Grammarly.

@@ -374,5 +1411,31 @@ *

*/
interface Editor {
/** Close Grammarly connection and clean up any state. */
disconnect: () => void;
declare class Editor {
private readonly _scope;
private _plugin;
/**
* Is connected to textarea/input element?
*
* @internal
*/
get isConnected(): boolean;
/**
* @internal
*/
static create(options: EditorInitOptions): Editor;
/**
* @internal
*/
private constructor();
/**
* Close Grammarly connection and clean up any state.
* @public
*/
disconnect(): void;
/**
* Process OAuth callback and complete account connection.
*
* @public
* @since 1.3.4
*/
handleOAuthCallback(url: string): Promise<void>;
}

@@ -399,7 +1462,7 @@

*
* @param element - Element to be enhanced
* @param editor - Element to be enhanced
* @param config - Optional {@link EditorConfig}
* @returns An {@link Editor}
*/
withElement(element: HTMLElement, config?: Partial<EditorConfig>): Editor;
withElement(editor: HTMLElement, config?: Partial<EditorConfig>): Editor;
/**

@@ -437,2 +1500,2 @@ * Enhance all elements that match provided selectors with Grammarly.

export { ClientId, Dialect, DocumentConfig, Domain, Editor, EditorConfig, EditorFactory, PluginDisableReason, SessionStats, SessionSuggestionBreakdown, SuggestionCategories, TextStats, Time, UIConfig, init };
export { ClientId, Dialect, DocumentConfig, Domain, Editor, EditorConfig, EditorFactory, Event, EventEmitter, EventListener, PluginDisableReason, SessionStats, SessionSuggestionBreakdown, SuggestionCategories, TextStats, Time, UIConfig, init };

2

lib/index.esm.js

@@ -17,2 +17,2 @@ /**

*/
var ExceptionCodes={};ExceptionCodes[ExceptionCodes["UNKNOWN"]=1e3]="UNKNOWN";ExceptionCodes[ExceptionCodes["ENVIRONMENT_UNSUPPORTED"]=3001]="ENVIRONMENT_UNSUPPORTED";const messages={[ExceptionCodes.UNKNOWN]:"Unknown error",[ExceptionCodes.ENVIRONMENT_UNSUPPORTED]:"The environment is not supported"};class GrammarlyException extends Error{constructor(code=ExceptionCodes.UNKNOWN,message=messages[code]){super(message);this.code=code}}GrammarlyException.codes=ExceptionCodes;function findScript(url){const scripts=document.querySelectorAll(`script[src^="${url}"]`);return scripts[0]}function injectScript(url){const script=document.createElement("script");script.src=url;document.head.appendChild(script);return script}const promises=new Map;function initGrammarlyGlobalAPI(){if(typeof window==="undefined"){return}if(window.Grammarly!=null)return;window.Grammarly={}}async function loadScript(url,clientId){if(typeof window==="undefined"){return await Promise.reject(new GrammarlyException(GrammarlyException.codes.ENVIRONMENT_UNSUPPORTED,"Cannot load script in non-browser environment"))}initGrammarlyGlobalAPI();if(promises.has(url)){return await promises.get(url)}else{const grammarlyPromise=new Promise(((resolve,reject)=>{try{let script=findScript(url);if(script!=null){resolve(window.Grammarly)}else{script=injectScript(clientId!=null?`${url}?clientId=${clientId}`:url);script.addEventListener("load",(()=>{if(window.Grammarly!=null){resolve(window.Grammarly)}else{reject(new Error("Grammarly not available"))}}));script.addEventListener("error",(function(){reject(new Error(`Failed to load ${url}`))}))}}catch(error){return reject(error)}})).finally((()=>{promises.delete(url)}));promises.set(url,grammarlyPromise);return grammarlyPromise}}const[versionMajor,versionMinor]="1.3.3".split(".");const resolvedVersion=`${versionMajor}.${versionMinor}`;async function init(clientId){var _a,_b;const Grammarly=await loadScript((_a=undefined)!==null&&_a!==void 0?_a:`https://js.${(_b="grammarly.com")!==null&&_b!==void 0?_b:"grammarly.com"}/grammarly-editor-sdk@${resolvedVersion}`,clientId);if(clientId!=null){return new Grammarly.EditorFactory(clientId)}}export{init};
var ExceptionCodes={};ExceptionCodes[ExceptionCodes["UNKNOWN"]=1e3]="UNKNOWN";ExceptionCodes[ExceptionCodes["ENVIRONMENT_UNSUPPORTED"]=3001]="ENVIRONMENT_UNSUPPORTED";const messages={[ExceptionCodes.UNKNOWN]:"Unknown error",[ExceptionCodes.ENVIRONMENT_UNSUPPORTED]:"The environment is not supported"};class GrammarlyException extends Error{constructor(code=ExceptionCodes.UNKNOWN,message=messages[code]){super(message);this.code=code}}GrammarlyException.codes=ExceptionCodes;function findScript(url){const scripts=document.querySelectorAll(`script[src^="${url}"]`);return scripts[0]}function injectScript(url){const script=document.createElement("script");script.src=url;document.head.appendChild(script);return script}const promises=new Map;function initGrammarlyGlobalAPI(){if(typeof window==="undefined"){return}if(window.Grammarly!=null)return;window.Grammarly={}}async function loadScript(url,clientId){if(typeof window==="undefined"){return await Promise.reject(new GrammarlyException(GrammarlyException.codes.ENVIRONMENT_UNSUPPORTED,"Cannot load script in non-browser environment"))}initGrammarlyGlobalAPI();if(promises.has(url)){return await promises.get(url)}else{const grammarlyPromise=new Promise(((resolve,reject)=>{try{let script=findScript(url);if(script!=null){resolve(window.Grammarly)}else{script=injectScript(clientId!=null?`${url}?clientId=${clientId}`:url);script.addEventListener("load",(()=>{if(window.Grammarly!=null){resolve(window.Grammarly)}else{reject(new Error("Grammarly not available"))}}));script.addEventListener("error",(function(){reject(new Error(`Failed to load ${url}`))}))}}catch(error){return reject(error)}})).finally((()=>{promises.delete(url)}));promises.set(url,grammarlyPromise);return grammarlyPromise}}const[versionMajor,versionMinor]="1.3.4".split(".");const resolvedVersion=`${versionMajor}.${versionMinor}`;async function init(clientId){var _a,_b;const Grammarly=await loadScript((_a=undefined)!==null&&_a!==void 0?_a:`https://js.${(_b="grammarly.com")!==null&&_b!==void 0?_b:"grammarly.com"}/grammarly-editor-sdk@${resolvedVersion}`,clientId);if(clientId!=null){return new Grammarly.EditorFactory(clientId)}}export{init};

@@ -17,2 +17,2 @@ /**

*/
!function(){"use strict";var n={};n[n.UNKNOWN=1e3]="UNKNOWN",n[n.ENVIRONMENT_UNSUPPORTED=3001]="ENVIRONMENT_UNSUPPORTED";const r={[n.UNKNOWN]:"Unknown error",[n.ENVIRONMENT_UNSUPPORTED]:"The environment is not supported"};class t extends Error{constructor(t=n.UNKNOWN,e=r[t]){super(e),this.code=t}}t.codes=n;const e=new Map;async function o(n,r){if("undefined"==typeof window)return await Promise.reject(new t(t.codes.ENVIRONMENT_UNSUPPORTED,"Cannot load script in non-browser environment"));if("undefined"!=typeof window&&null==window.Grammarly&&(window.Grammarly={}),e.has(n))return await e.get(n);{const t=new Promise(((t,e)=>{try{let o=function(n){return document.querySelectorAll(`script[src^="${n}"]`)[0]}(n);null!=o?t(window.Grammarly):(o=function(n){const r=document.createElement("script");return r.src=n,document.head.appendChild(r),r}(null!=r?`${n}?clientId=${r}`:n),o.addEventListener("load",(()=>{null!=window.Grammarly?t(window.Grammarly):e(new Error("Grammarly not available"))})),o.addEventListener("error",(function(){e(new Error(`Failed to load ${n}`))})))}catch(n){return e(n)}})).finally((()=>{e.delete(n)}));return e.set(n,t),t}}const[i,a]="1.3.3".split("."),c=`${i}.${a}`;async function l(n){var r;const t=await o((void 0,`https://js.${null!==(r="grammarly.com")?r:"grammarly.com"}/grammarly-editor-sdk@${c}`),n);if(null!=n)return new t.EditorFactory(n)}const s=function(){const n=function(){if(document.currentScript instanceof HTMLScriptElement)return document.currentScript}();if(n){const r=n.src;if(r){const n=new URL(r).searchParams.get("clientId");if(null!=n)return n}const t=n.getAttribute("clientId");if(null!=t)return t}}(),u=null!=s?l(s):void 0;window.Grammarly.init=async(n=s)=>{const r=s===n?await u:null!=n?await l(n):void 0;if(null==r)throw new Error('A "clientId" is required to init Grammarly SDK.');return r}}();
!function(){"use strict";var n={};n[n.UNKNOWN=1e3]="UNKNOWN",n[n.ENVIRONMENT_UNSUPPORTED=3001]="ENVIRONMENT_UNSUPPORTED";const r={[n.UNKNOWN]:"Unknown error",[n.ENVIRONMENT_UNSUPPORTED]:"The environment is not supported"};class t extends Error{constructor(t=n.UNKNOWN,e=r[t]){super(e),this.code=t}}t.codes=n;const e=new Map;async function o(n,r){if("undefined"==typeof window)return await Promise.reject(new t(t.codes.ENVIRONMENT_UNSUPPORTED,"Cannot load script in non-browser environment"));if("undefined"!=typeof window&&null==window.Grammarly&&(window.Grammarly={}),e.has(n))return await e.get(n);{const t=new Promise(((t,e)=>{try{let o=function(n){return document.querySelectorAll(`script[src^="${n}"]`)[0]}(n);null!=o?t(window.Grammarly):(o=function(n){const r=document.createElement("script");return r.src=n,document.head.appendChild(r),r}(null!=r?`${n}?clientId=${r}`:n),o.addEventListener("load",(()=>{null!=window.Grammarly?t(window.Grammarly):e(new Error("Grammarly not available"))})),o.addEventListener("error",(function(){e(new Error(`Failed to load ${n}`))})))}catch(n){return e(n)}})).finally((()=>{e.delete(n)}));return e.set(n,t),t}}const[i,a]="1.3.4".split("."),c=`${i}.${a}`;async function l(n){var r;const t=await o((void 0,`https://js.${null!==(r="grammarly.com")?r:"grammarly.com"}/grammarly-editor-sdk@${c}`),n);if(null!=n)return new t.EditorFactory(n)}const s=function(){const n=function(){if(document.currentScript instanceof HTMLScriptElement)return document.currentScript}();if(n){const r=n.src;if(r){const n=new URL(r).searchParams.get("clientId");if(null!=n)return n}const t=n.getAttribute("clientId");if(null!=t)return t}}(),u=null!=s?l(s):void 0;window.Grammarly.init=async(n=s)=>{const r=s===n?await u:null!=n?await l(n):void 0;if(null==r)throw new Error('A "clientId" is required to init Grammarly SDK.');return r}}();

@@ -17,2 +17,2 @@ /**

*/
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var ExceptionCodes={};ExceptionCodes[ExceptionCodes["UNKNOWN"]=1e3]="UNKNOWN";ExceptionCodes[ExceptionCodes["ENVIRONMENT_UNSUPPORTED"]=3001]="ENVIRONMENT_UNSUPPORTED";const messages={[ExceptionCodes.UNKNOWN]:"Unknown error",[ExceptionCodes.ENVIRONMENT_UNSUPPORTED]:"The environment is not supported"};class GrammarlyException extends Error{constructor(code=ExceptionCodes.UNKNOWN,message=messages[code]){super(message);this.code=code}}GrammarlyException.codes=ExceptionCodes;function findScript(url){const scripts=document.querySelectorAll(`script[src^="${url}"]`);return scripts[0]}function injectScript(url){const script=document.createElement("script");script.src=url;document.head.appendChild(script);return script}const promises=new Map;function initGrammarlyGlobalAPI(){if(typeof window==="undefined"){return}if(window.Grammarly!=null)return;window.Grammarly={}}async function loadScript(url,clientId){if(typeof window==="undefined"){return await Promise.reject(new GrammarlyException(GrammarlyException.codes.ENVIRONMENT_UNSUPPORTED,"Cannot load script in non-browser environment"))}initGrammarlyGlobalAPI();if(promises.has(url)){return await promises.get(url)}else{const grammarlyPromise=new Promise(((resolve,reject)=>{try{let script=findScript(url);if(script!=null){resolve(window.Grammarly)}else{script=injectScript(clientId!=null?`${url}?clientId=${clientId}`:url);script.addEventListener("load",(()=>{if(window.Grammarly!=null){resolve(window.Grammarly)}else{reject(new Error("Grammarly not available"))}}));script.addEventListener("error",(function(){reject(new Error(`Failed to load ${url}`))}))}}catch(error){return reject(error)}})).finally((()=>{promises.delete(url)}));promises.set(url,grammarlyPromise);return grammarlyPromise}}const[versionMajor,versionMinor]="1.3.3".split(".");const resolvedVersion=`${versionMajor}.${versionMinor}`;async function init(clientId){var _a,_b;const Grammarly=await loadScript((_a=undefined)!==null&&_a!==void 0?_a:`https://js.${(_b="grammarly.com")!==null&&_b!==void 0?_b:"grammarly.com"}/grammarly-editor-sdk@${resolvedVersion}`,clientId);if(clientId!=null){return new Grammarly.EditorFactory(clientId)}}exports.init=init;
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var ExceptionCodes={};ExceptionCodes[ExceptionCodes["UNKNOWN"]=1e3]="UNKNOWN";ExceptionCodes[ExceptionCodes["ENVIRONMENT_UNSUPPORTED"]=3001]="ENVIRONMENT_UNSUPPORTED";const messages={[ExceptionCodes.UNKNOWN]:"Unknown error",[ExceptionCodes.ENVIRONMENT_UNSUPPORTED]:"The environment is not supported"};class GrammarlyException extends Error{constructor(code=ExceptionCodes.UNKNOWN,message=messages[code]){super(message);this.code=code}}GrammarlyException.codes=ExceptionCodes;function findScript(url){const scripts=document.querySelectorAll(`script[src^="${url}"]`);return scripts[0]}function injectScript(url){const script=document.createElement("script");script.src=url;document.head.appendChild(script);return script}const promises=new Map;function initGrammarlyGlobalAPI(){if(typeof window==="undefined"){return}if(window.Grammarly!=null)return;window.Grammarly={}}async function loadScript(url,clientId){if(typeof window==="undefined"){return await Promise.reject(new GrammarlyException(GrammarlyException.codes.ENVIRONMENT_UNSUPPORTED,"Cannot load script in non-browser environment"))}initGrammarlyGlobalAPI();if(promises.has(url)){return await promises.get(url)}else{const grammarlyPromise=new Promise(((resolve,reject)=>{try{let script=findScript(url);if(script!=null){resolve(window.Grammarly)}else{script=injectScript(clientId!=null?`${url}?clientId=${clientId}`:url);script.addEventListener("load",(()=>{if(window.Grammarly!=null){resolve(window.Grammarly)}else{reject(new Error("Grammarly not available"))}}));script.addEventListener("error",(function(){reject(new Error(`Failed to load ${url}`))}))}}catch(error){return reject(error)}})).finally((()=>{promises.delete(url)}));promises.set(url,grammarlyPromise);return grammarlyPromise}}const[versionMajor,versionMinor]="1.3.4".split(".");const resolvedVersion=`${versionMajor}.${versionMinor}`;async function init(clientId){var _a,_b;const Grammarly=await loadScript((_a=undefined)!==null&&_a!==void 0?_a:`https://js.${(_b="grammarly.com")!==null&&_b!==void 0?_b:"grammarly.com"}/grammarly-editor-sdk@${resolvedVersion}`,clientId);if(clientId!=null){return new Grammarly.EditorFactory(clientId)}}exports.init=init;

@@ -5,3 +5,3 @@ {

"description": "Grammarly writing SDK for web editors",
"version": "1.3.3",
"version": "1.3.4",
"main": "lib/index.js",

@@ -27,4 +27,4 @@ "module": "lib/index.esm.js",

"devDependencies": {
"@grammarly/plugin-core": "1.3.3",
"@grammarly/plugin-editor": "1.3.3",
"@grammarly/plugin-core": "1.3.4",
"@grammarly/plugin-editor": "1.3.4",
"@microsoft/api-extractor": "^7.15.1",

@@ -31,0 +31,0 @@ "@testing-library/jest-dom": "^5.11.10",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc