@grammarly/editor-sdk
Advanced tools
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 }; |
@@ -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", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
62536
1513
1