From a4b9d2d91a2be841320030d93afde46ae723c8c3 Mon Sep 17 00:00:00 2001 From: Azat Alimov <32402726+mkslanc@users.noreply.github.com> Date: Tue, 28 Jan 2025 15:29:31 +0400 Subject: [PATCH] Fix: wrong type of paste event and missing types for themelist extension (#5725) * fix: wrong type of paste event * Apply suggestions from code review * generate with typescript 5.7.3 * fix: small bug in `moveToMouse`; types * add types for themelist --- ace-internal.d.ts | 4 +++- ace.d.ts | 6 +++++- demo/test_package/index.ts | 12 +++++++++++- src/editor.js | 4 ++-- src/ext/themelist.js | 13 ++++++++++++- src/keyboard/textinput.js | 8 ++++---- types/ace-ext.d.ts | 21 ++++++++++++++++++--- 7 files changed, 55 insertions(+), 13 deletions(-) diff --git a/ace-internal.d.ts b/ace-internal.d.ts index 26a2fd927f1..ee570f6b78d 100644 --- a/ace-internal.d.ts +++ b/ace-internal.d.ts @@ -511,7 +511,7 @@ export namespace Ace { /** * Emitted when text is pasted. **/ - "paste": (text: string, event: any) => void; + "paste": (e: { text: string, event?: ClipboardEvent }) => void; /** * Emitted when the selection style changes, via [[Editor.setSelectionStyle]]. * @param data Contains one property, `data`, which indicates the new selection style @@ -530,6 +530,7 @@ export namespace Ace { "gutterclick": (e: MouseEvent) => void; "showGutterTooltip": (e: GutterTooltip) => void; "hideGutterTooltip": (e: GutterTooltip) => void; + "compositionStart": () => void; } interface AcePopupEvents { @@ -1334,6 +1335,7 @@ declare module "./src/editor" { showSettingsMenu?: () => void, searchBox?: Ace.SearchBox, _eventRegistry?: any, + $textInputAriaLabel?: string } } diff --git a/ace.d.ts b/ace.d.ts index dda1c7ecff3..8e70a970f3d 100644 --- a/ace.d.ts +++ b/ace.d.ts @@ -422,7 +422,10 @@ declare module "ace-code" { /** * Emitted when text is pasted. **/ - "paste": (text: string, event: any) => void; + "paste": (e: { + text: string; + event?: ClipboardEvent; + }) => void; /** * Emitted when the selection style changes, via [[Editor.setSelectionStyle]]. * @param data Contains one property, `data`, which indicates the new selection style @@ -443,6 +446,7 @@ declare module "ace-code" { "gutterclick": (e: MouseEvent) => void; "showGutterTooltip": (e: GutterTooltip) => void; "hideGutterTooltip": (e: GutterTooltip) => void; + "compositionStart": () => void; } interface AcePopupEvents { "click": (e: MouseEvent) => void; diff --git a/demo/test_package/index.ts b/demo/test_package/index.ts index 3e0b12f7593..9da639d55cc 100644 --- a/demo/test_package/index.ts +++ b/demo/test_package/index.ts @@ -9,6 +9,7 @@ import {MarkerGroup, MarkerGroupItem} from "ace-code/src/marker_group"; import {HoverTooltip} from "ace-code/src/tooltip"; import {hardWrap} from "ace-code/src/ext/hardwrap"; import {SearchBox} from "ace-code/src/ext/searchbox"; +import {themesByName} from 'ace-code/src/ext/themelist'; import("ace-code/src/ext/language_tools"); import "../../src/test/mockdom.js"; @@ -134,4 +135,13 @@ const filter = new FilteredList([]); filter.setFilter("test"); editor.session.startOperation(); -editor.session.endOperation(); \ No newline at end of file +editor.session.endOperation(); + +editor.on("paste", (e) => { + var htmlString = e.event?.clipboardData?.getData("text/html") + if (htmlString) { + e.text = htmlString + } +}) + +themesByName.textmate?.theme; \ No newline at end of file diff --git a/src/editor.js b/src/editor.js index b89a8115b09..eb73bedc401 100644 --- a/src/editor.js +++ b/src/editor.js @@ -853,7 +853,7 @@ class Editor { /** * Called whenever a text "paste" happens. * @param {String} text The pasted text - * @param {any} event + * @param {ClipboardEvent} [event] * @internal **/ onPaste(text, event) { @@ -863,7 +863,7 @@ class Editor { /** * - * @param e + * @param {string | {text: string, event?: ClipboardEvent}} e * @returns {boolean} */ $handlePaste(e) { diff --git a/src/ext/themelist.js b/src/ext/themelist.js index c677f865e10..7c81f89dba8 100644 --- a/src/ext/themelist.js +++ b/src/ext/themelist.js @@ -8,6 +8,14 @@ "use strict"; +/** + * @typedef {Object} Theme + * @property {string} caption - The display caption of the theme. + * @property {string} theme - The path or identifier for the ACE theme. + * @property {boolean} isDark - Indicates whether the theme is dark or light. + * @property {string} name - The normalized name used as the key. + */ + var themeData = [ ["Chrome" ], ["Clouds" ], @@ -54,11 +62,14 @@ var themeData = [ ["CloudEditor Dark" ,"cloud_editor_dark" , "dark"] ]; - +/** + * @type {Object} + */ exports.themesByName = {}; /** * An array containing information about available themes. + * @type {Theme[]} */ exports.themes = themeData.map(function(data) { var name = data[1] || data[0].replace(/ /g, "_").toLowerCase(); diff --git a/src/keyboard/textinput.js b/src/keyboard/textinput.js index fb657872b75..89f06a50c45 100644 --- a/src/keyboard/textinput.js +++ b/src/keyboard/textinput.js @@ -22,7 +22,7 @@ var valueResetRegex = isIOS ? /\s/ : /\n/; var isMobile = useragent.isMobile; var TextInput; -TextInput= function(parentNode, host) { +TextInput= function(/**@type{HTMLTextAreaElement} */parentNode, /**@type{import("../editor").Editor} */host) { /**@type {HTMLTextAreaElement & {msGetInputContext?: () => {compositionStartOffset: number}, getInputContext?: () => {compositionStartOffset: number}}}*/ var text = dom.createElement("textarea"); text.className = "ace_text-input"; @@ -35,7 +35,7 @@ TextInput= function(parentNode, host) { text.style.opacity = "0"; parentNode.insertBefore(text, parentNode.firstChild); - var copied = false; + /**@type{boolean|string}*/var copied = false; var pasted = false; /**@type {(boolean|Object) & {context?: any, useTextareaForIME?: boolean, selectionStart?: number, markerRange?: any}}} */ var inComposition = false; @@ -62,7 +62,7 @@ TextInput= function(parentNode, host) { // Set number of extra lines in textarea, some screenreaders // perform better with extra lines above and below in the textarea. - this.setNumberOfExtraLines = function(number) { + this.setNumberOfExtraLines = function(/**@type{number}*/number) { rowStart = Number.MAX_SAFE_INTEGER; rowEnd = Number.MIN_SAFE_INTEGER; @@ -695,7 +695,7 @@ TextInput= function(parentNode, host) { var rect = host.container.getBoundingClientRect(); var style = dom.computedStyle(host.container); var top = rect.top + (parseInt(style.borderTopWidth) || 0); - var left = rect.left + (parseInt(rect.borderLeftWidth) || 0); + var left = rect.left + (parseInt(style.borderLeftWidth) || 0); var maxTop = rect.bottom - top - text.clientHeight -2; var move = function(e) { dom.translate(text, e.clientX - left - 2, Math.min(e.clientY - top - 2, maxTop)); diff --git a/types/ace-ext.d.ts b/types/ace-ext.d.ts index afabd9debfb..eadf79ad064 100644 --- a/types/ace-ext.d.ts +++ b/types/ace-ext.d.ts @@ -404,13 +404,28 @@ declare module "ace-code/src/ext/modelist" { } } declare module "ace-code/src/ext/themelist" { - export const themesByName: {}; - export const themes: { + export const themesByName: { + [x: string]: Theme; + }; + export const themes: Theme[]; + export type Theme = { + /** + * - The display caption of the theme. + */ caption: string; + /** + * - The path or identifier for the ACE theme. + */ theme: string; + /** + * - Indicates whether the theme is dark or light. + */ isDark: boolean; + /** + * - The normalized name used as the key. + */ name: string; - }[]; + }; } declare module "ace-code/src/ext/options" { export class OptionPanel {