()
| 251 | * @returns {{from:number,to:number}|null} |
| 252 | */ |
| 253 | export function getColorRange() { |
| 254 | const { editor } = editorManager; |
| 255 | |
| 256 | try { |
| 257 | const sel = editor.state.selection.main; |
| 258 | const from = sel.from; |
| 259 | const to = sel.to; |
| 260 | |
| 261 | // If there is a selection, validate and return it |
| 262 | if (from !== to) { |
| 263 | const text = editor.state.doc.sliceString(from, to); |
| 264 | if (!isValidColor(text)) return null; |
| 265 | return { from, to }; |
| 266 | } |
| 267 | |
| 268 | // No selection: find color under cursor in the current line |
| 269 | const head = sel.head; |
| 270 | const line = editor.state.doc.lineAt(head); |
| 271 | const lineText = line.text; |
| 272 | const col = head - line.from; |
| 273 | |
| 274 | const regex = colorRegex.anyGlobal; |
| 275 | let match; |
| 276 | |
| 277 | while ((match = regex.exec(lineText))) { |
| 278 | const startCol = match.index + match[1].length; |
| 279 | const endCol = startCol + match[2].length; |
| 280 | |
| 281 | if (col >= startCol && col <= endCol) { |
| 282 | return { from: line.from + startCol, to: line.from + endCol }; |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | return null; |
| 287 | } catch { |
| 288 | return null; |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | export function isValidColor(value) { |
| 293 | return colorRegex.anyStrict.test(value); |
no test coverage detected