From 5aca165a4fa430d9956ff7906be004841eef7a9e Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Tue, 11 Mar 2025 18:40:07 +0300 Subject: [PATCH 01/11] Convert to string if number bigger than max safe int --- src/js/util.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index 429393a91..15f94c95d 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -118,7 +118,10 @@ export function getType (object) { return 'undefined' } if ((object instanceof Number) || (typeof object === 'number')) { - return 'number' + if (object <= Number.MAX_SAFE_INTEGER) { + return 'number' + } + return 'string' } if ((object instanceof String) || (typeof object === 'string')) { return 'string' @@ -1144,7 +1147,7 @@ export function parseString (str) { const num = Number(str) // will nicely fail with '123ab' const numFloat = parseFloat(str) // will nicely fail with ' ' - if (!isNaN(num) && !isNaN(numFloat)) { + if (!isNaN(num) && !isNaN(numFloat) && num <= Number.MAX_SAFE_INTEGER && numFloat <= Number.MAX_SAFE_INTEGER) { return num } From a639d83851285629e3af9d199951bd5359f99c6f Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Tue, 11 Mar 2025 18:40:58 +0300 Subject: [PATCH 02/11] Changed contenteditable to plaintext-only to escape html paste --- examples/css/darktheme.css | 4 ++++ src/js/Node.js | 4 ++-- src/js/treemode.js | 2 +- src/scss/jsoneditor/_editor.scss | 4 ++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/css/darktheme.css b/examples/css/darktheme.css index 3c1c88191..a402ab267 100644 --- a/examples/css/darktheme.css +++ b/examples/css/darktheme.css @@ -25,9 +25,13 @@ tr.jsoneditor-selected { } div.jsoneditor-field[contenteditable=true]:focus, +div.jsoneditor-field[contenteditable=plaintext-only]:focus, div.jsoneditor-field[contenteditable=true]:hover, +div.jsoneditor-field[contenteditable=plaintext-only]:hover, div.jsoneditor-value[contenteditable=true]:focus, +div.jsoneditor-value[contenteditable=plaintext-only]:focus, div.jsoneditor-value[contenteditable=true]:hover, +div.jsoneditor-value[contenteditable=plaintext-only]:hover, div.jsoneditor-field.jsoneditor-highlight, div.jsoneditor-value.jsoneditor-highlight { background-color: #808080; diff --git a/src/js/Node.js b/src/js/Node.js index 5c83478b3..0020fc764 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -2235,7 +2235,7 @@ export class Node { if (domField) { if (this.fieldEditable) { // parent is an object - domField.contentEditable = this.editable.field + domField.contentEditable = this.editable.field ? 'plaintext-only' : false domField.spellcheck = false domField.className = 'jsoneditor-field' } else { @@ -2428,7 +2428,7 @@ export class Node { } else { // create an editable or read-only div domValue = document.createElement('div') - domValue.contentEditable = this.editable.value + domValue.contentEditable = this.editable.value ? 'plaintext-only' : false domValue.spellcheck = false domValue.innerHTML = this._escapeHTML(this.value) } diff --git a/src/js/treemode.js b/src/js/treemode.js index 19ef86ab5..3da5d8f38 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -360,7 +360,7 @@ treemode.getName = function () { * - to the first button in the top menu */ treemode.focus = function () { - let input = this.scrollableContent.querySelector('[contenteditable=true]') + let input = this.scrollableContent.querySelector('[contenteditable=true]') || this.scrollableContent.querySelector('[contenteditable=plaintext-only]') if (input) { input.focus() } else if (this.node.dom.expand) { diff --git a/src/scss/jsoneditor/_editor.scss b/src/scss/jsoneditor/_editor.scss index 996cc17fa..b43b79458 100644 --- a/src/scss/jsoneditor/_editor.scss +++ b/src/scss/jsoneditor/_editor.scss @@ -293,9 +293,13 @@ a.jsoneditor-value.jsoneditor-url:focus { color: variables.$jse-number; } div.jsoneditor-field[contenteditable="true"]:focus, +div.jsoneditor-field[contenteditable="plaintext-only"]:focus, div.jsoneditor-field[contenteditable="true"]:hover, +div.jsoneditor-field[contenteditable="plaintext-only"]:hover, div.jsoneditor-value[contenteditable="true"]:focus, +div.jsoneditor-value[contenteditable="plaintext-only"]:focus, div.jsoneditor-value[contenteditable="true"]:hover, +div.jsoneditor-value[contenteditable="plaintext-only"]:hover, div.jsoneditor-field.jsoneditor-highlight, div.jsoneditor-value.jsoneditor-highlight { background-color: variables.$jse-busy; From ef76e1f189047472ccf61f07c6af2858b8652a7d Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Thu, 13 Mar 2025 16:31:49 +0300 Subject: [PATCH 03/11] Revert "Changed contenteditable to plaintext-only to escape html paste" This reverts commit a639d83851285629e3af9d199951bd5359f99c6f. --- examples/css/darktheme.css | 4 ---- src/js/Node.js | 4 ++-- src/js/treemode.js | 2 +- src/scss/jsoneditor/_editor.scss | 4 ---- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/examples/css/darktheme.css b/examples/css/darktheme.css index a402ab267..3c1c88191 100644 --- a/examples/css/darktheme.css +++ b/examples/css/darktheme.css @@ -25,13 +25,9 @@ tr.jsoneditor-selected { } div.jsoneditor-field[contenteditable=true]:focus, -div.jsoneditor-field[contenteditable=plaintext-only]:focus, div.jsoneditor-field[contenteditable=true]:hover, -div.jsoneditor-field[contenteditable=plaintext-only]:hover, div.jsoneditor-value[contenteditable=true]:focus, -div.jsoneditor-value[contenteditable=plaintext-only]:focus, div.jsoneditor-value[contenteditable=true]:hover, -div.jsoneditor-value[contenteditable=plaintext-only]:hover, div.jsoneditor-field.jsoneditor-highlight, div.jsoneditor-value.jsoneditor-highlight { background-color: #808080; diff --git a/src/js/Node.js b/src/js/Node.js index 0020fc764..5c83478b3 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -2235,7 +2235,7 @@ export class Node { if (domField) { if (this.fieldEditable) { // parent is an object - domField.contentEditable = this.editable.field ? 'plaintext-only' : false + domField.contentEditable = this.editable.field domField.spellcheck = false domField.className = 'jsoneditor-field' } else { @@ -2428,7 +2428,7 @@ export class Node { } else { // create an editable or read-only div domValue = document.createElement('div') - domValue.contentEditable = this.editable.value ? 'plaintext-only' : false + domValue.contentEditable = this.editable.value domValue.spellcheck = false domValue.innerHTML = this._escapeHTML(this.value) } diff --git a/src/js/treemode.js b/src/js/treemode.js index 3da5d8f38..19ef86ab5 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -360,7 +360,7 @@ treemode.getName = function () { * - to the first button in the top menu */ treemode.focus = function () { - let input = this.scrollableContent.querySelector('[contenteditable=true]') || this.scrollableContent.querySelector('[contenteditable=plaintext-only]') + let input = this.scrollableContent.querySelector('[contenteditable=true]') if (input) { input.focus() } else if (this.node.dom.expand) { diff --git a/src/scss/jsoneditor/_editor.scss b/src/scss/jsoneditor/_editor.scss index b43b79458..996cc17fa 100644 --- a/src/scss/jsoneditor/_editor.scss +++ b/src/scss/jsoneditor/_editor.scss @@ -293,13 +293,9 @@ a.jsoneditor-value.jsoneditor-url:focus { color: variables.$jse-number; } div.jsoneditor-field[contenteditable="true"]:focus, -div.jsoneditor-field[contenteditable="plaintext-only"]:focus, div.jsoneditor-field[contenteditable="true"]:hover, -div.jsoneditor-field[contenteditable="plaintext-only"]:hover, div.jsoneditor-value[contenteditable="true"]:focus, -div.jsoneditor-value[contenteditable="plaintext-only"]:focus, div.jsoneditor-value[contenteditable="true"]:hover, -div.jsoneditor-value[contenteditable="plaintext-only"]:hover, div.jsoneditor-field.jsoneditor-highlight, div.jsoneditor-value.jsoneditor-highlight { background-color: variables.$jse-busy; From a2bf78edf82294b74e8cc9e77b0d8a401da8c031 Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Thu, 13 Mar 2025 21:35:50 +0300 Subject: [PATCH 04/11] add check for negative safe integer & unit tests --- src/js/util.js | 20 ++++++++--- test/util.test.js | 84 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 72 insertions(+), 32 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index 15f94c95d..5429bef82 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -118,10 +118,7 @@ export function getType (object) { return 'undefined' } if ((object instanceof Number) || (typeof object === 'number')) { - if (object <= Number.MAX_SAFE_INTEGER) { - return 'number' - } - return 'string' + return 'number' } if ((object instanceof String) || (typeof object === 'string')) { return 'string' @@ -1147,13 +1144,26 @@ export function parseString (str) { const num = Number(str) // will nicely fail with '123ab' const numFloat = parseFloat(str) // will nicely fail with ' ' - if (!isNaN(num) && !isNaN(numFloat) && num <= Number.MAX_SAFE_INTEGER && numFloat <= Number.MAX_SAFE_INTEGER) { + if (isSafeNumber(num) && isSafeNumber(numFloat)) { return num } return str } +/** + * Check values is between max and min safe integer numbers + * + * @param {*} num + * @returns {boolean} + */ +export const isSafeNumber = (num) => { + const isNumber = typeof num === 'number' && !isNaN(num) + const isSafe = num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER + + return isNumber && isSafe +} + /** * Test whether some field contains a timestamp in milliseconds after the year 2000. * @param {string} field diff --git a/test/util.test.js b/test/util.test.js index 7b0cdc994..4565f523a 100644 --- a/test/util.test.js +++ b/test/util.test.js @@ -7,6 +7,7 @@ import { getChildPaths, getIndexForPosition, isObject, + isSafeNumber, isTimestamp, isValidationErrorChanged, limitCharacters, @@ -305,33 +306,39 @@ describe('util', () => { }) }) - it('should parse a string', () => { - assert.strictEqual(parseString('foo'), 'foo') - assert.strictEqual(parseString('234foo'), '234foo') - assert.strictEqual(parseString(' 234'), 234) - assert.strictEqual(parseString('234 '), 234) - assert.strictEqual(parseString('2.3'), 2.3) - assert.strictEqual(parseString('null'), null) - assert.strictEqual(parseString('true'), true) - assert.strictEqual(parseString('false'), false) - assert.strictEqual(parseString('+1'), 1) - assert.strictEqual(parseString('01'), '01') - assert.strictEqual(parseString('001'), '001') - assert.strictEqual(parseString('0.3'), 0.3) - assert.strictEqual(parseString('0e3'), 0) - assert.strictEqual(parseString(' '), ' ') - assert.strictEqual(parseString(''), '') - assert.strictEqual(parseString('"foo"'), '"foo"') - assert.strictEqual(parseString('"2"'), '"2"') - assert.strictEqual(parseString('\'foo\''), '\'foo\'') - assert.strictEqual(parseString('0x1A'), '0x1A') - assert.strictEqual(parseString('0x1F'), '0x1F') - assert.strictEqual(parseString('0x1a'), '0x1a') - assert.strictEqual(parseString('0b1101'), '0b1101') - assert.strictEqual(parseString('0o3700'), '0o3700') - assert.strictEqual(parseString('0X1a'), '0X1a') - assert.strictEqual(parseString('0B1101'), '0B1101') - assert.strictEqual(parseString('0O3700'), '0O3700') + describe('parseString', () => { + it('should parse a string', () => { + assert.strictEqual(parseString('foo'), 'foo') + assert.strictEqual(parseString('234foo'), '234foo') + assert.strictEqual(parseString(' 234'), 234) + assert.strictEqual(parseString('234 '), 234) + assert.strictEqual(parseString('2.3'), 2.3) + assert.strictEqual(parseString('null'), null) + assert.strictEqual(parseString('true'), true) + assert.strictEqual(parseString('false'), false) + assert.strictEqual(parseString('+1'), 1) + assert.strictEqual(parseString('01'), '01') + assert.strictEqual(parseString('001'), '001') + assert.strictEqual(parseString('0.3'), 0.3) + assert.strictEqual(parseString('0e3'), 0) + assert.strictEqual(parseString(' '), ' ') + assert.strictEqual(parseString(''), '') + assert.strictEqual(parseString('"foo"'), '"foo"') + assert.strictEqual(parseString('"2"'), '"2"') + assert.strictEqual(parseString('\'foo\''), '\'foo\'') + assert.strictEqual(parseString('0x1A'), '0x1A') + assert.strictEqual(parseString('0x1F'), '0x1F') + assert.strictEqual(parseString('0x1a'), '0x1a') + assert.strictEqual(parseString('0b1101'), '0b1101') + assert.strictEqual(parseString('0o3700'), '0o3700') + assert.strictEqual(parseString('0X1a'), '0X1a') + assert.strictEqual(parseString('0B1101'), '0B1101') + assert.strictEqual(parseString('0O3700'), '0O3700') + assert.strictEqual(parseString('7405242042266046865'), '7405242042266046865') + assert.strictEqual(parseString('9007199254740991'), 9007199254740991) + assert.strictEqual(parseString('9007199254740991'), 9007199254740991) + assert.strictEqual(parseString('-9007199254740991'), -9007199254740991) + }) }) it('should find a unique name', () => { @@ -427,5 +434,28 @@ describe('util', () => { }) }) + describe('isSafeNumber', () => { + it('should return true if number is safe', () => { + assert.strictEqual(isSafeNumber(0), true) + assert.strictEqual(isSafeNumber(123), true) + assert.strictEqual(isSafeNumber(-123), true) + assert.strictEqual(isSafeNumber(123.123), true) + assert.strictEqual(isSafeNumber(9007199254740991), true) + assert.strictEqual(isSafeNumber(-9007199254740991), true) + }) + + it('should return false if number isn`t safe', () => { + assert.strictEqual(isSafeNumber(''), false) + assert.strictEqual(isSafeNumber(true), false) + assert.strictEqual(isSafeNumber({}), false) + assert.strictEqual(isSafeNumber([]), false) + assert.strictEqual(isSafeNumber(NaN), false) + assert.strictEqual(isSafeNumber(Infinity), false) + assert.strictEqual(isSafeNumber(new Date()), false) + assert.strictEqual(isSafeNumber(9007199254740992), false) + assert.strictEqual(isSafeNumber(-9007199254740992), false) + }) + }) + // TODO: thoroughly test all util methods }) From 74188e840e2b5eb540b63b9e6c18cd85ebb31811 Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Thu, 13 Mar 2025 21:43:18 +0300 Subject: [PATCH 05/11] add one more parseString unit test check --- test/util.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/util.test.js b/test/util.test.js index 4565f523a..80719a18d 100644 --- a/test/util.test.js +++ b/test/util.test.js @@ -338,6 +338,7 @@ describe('util', () => { assert.strictEqual(parseString('9007199254740991'), 9007199254740991) assert.strictEqual(parseString('9007199254740991'), 9007199254740991) assert.strictEqual(parseString('-9007199254740991'), -9007199254740991) + assert.strictEqual(parseString('1e25'), '1e25') }) }) From b4497fdfe53fbfb4deed0b79aea29ff5a8bed7fe Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Thu, 13 Mar 2025 22:07:54 +0300 Subject: [PATCH 06/11] handling exponential numbers --- src/js/util.js | 41 +++++++++++++++++------------------------ test/util.test.js | 28 +++------------------------- 2 files changed, 20 insertions(+), 49 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index 5429bef82..161e18169 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -145,7 +145,7 @@ const isUrlRegex = /^https?:\/\/\S+$/ export function isUrl (text) { return (typeof text === 'string' || text instanceof String) && - isUrlRegex.test(text) + isUrlRegex.test(text) } /** @@ -338,7 +338,7 @@ export function getSelectionOffset () { const range = getSelection() if (range && 'startOffset' in range && 'endOffset' in range && - range.startContainer && (range.startContainer === range.endContainer)) { + range.startContainer && (range.startContainer === range.endContainer)) { return { startOffset: range.startOffset, endOffset: range.endOffset, @@ -713,8 +713,8 @@ export function isPromise (object) { */ export function isValidValidationError (validationError) { return typeof validationError === 'object' && - Array.isArray(validationError.path) && - typeof validationError.message === 'string' + Array.isArray(validationError.path) && + typeof validationError.message === 'string' } /** @@ -726,9 +726,9 @@ export function isValidValidationError (validationError) { export function insideRect (parent, child, margin) { const _margin = margin !== undefined ? margin : 0 return child.left - _margin >= parent.left && - child.right + _margin <= parent.right && - child.top - _margin >= parent.top && - child.bottom + _margin <= parent.bottom + child.right + _margin <= parent.right && + child.top - _margin >= parent.top && + child.bottom + _margin <= parent.bottom } /** @@ -775,12 +775,12 @@ export function textDiff (oldText, newText) { let newEnd = newText.length while (newText.charAt(start) === oldText.charAt(start) && - start < len) { + start < len) { start++ } while (newText.charAt(newEnd - 1) === oldText.charAt(oldEnd - 1) && - newEnd > start && oldEnd > 0) { + newEnd > start && oldEnd > 0) { newEnd-- oldEnd-- } @@ -1144,26 +1144,19 @@ export function parseString (str) { const num = Number(str) // will nicely fail with '123ab' const numFloat = parseFloat(str) // will nicely fail with ' ' - if (isSafeNumber(num) && isSafeNumber(numFloat)) { - return num + if (!isNaN(num) && !isNaN(numFloat)) { + if ((num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER) && isFinite(num)) { + return num + } + const isExponentialNumber = /^[+-]?\d+(\.\d+)?[eE][+-]?\d+$/ + if (isExponentialNumber.test(str) && isFinite(num)) { + return num + } } return str } -/** - * Check values is between max and min safe integer numbers - * - * @param {*} num - * @returns {boolean} - */ -export const isSafeNumber = (num) => { - const isNumber = typeof num === 'number' && !isNaN(num) - const isSafe = num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER - - return isNumber && isSafe -} - /** * Test whether some field contains a timestamp in milliseconds after the year 2000. * @param {string} field diff --git a/test/util.test.js b/test/util.test.js index 80719a18d..88d8ee297 100644 --- a/test/util.test.js +++ b/test/util.test.js @@ -7,7 +7,6 @@ import { getChildPaths, getIndexForPosition, isObject, - isSafeNumber, isTimestamp, isValidationErrorChanged, limitCharacters, @@ -338,7 +337,9 @@ describe('util', () => { assert.strictEqual(parseString('9007199254740991'), 9007199254740991) assert.strictEqual(parseString('9007199254740991'), 9007199254740991) assert.strictEqual(parseString('-9007199254740991'), -9007199254740991) - assert.strictEqual(parseString('1e25'), '1e25') + assert.strictEqual(parseString('1e25'), 1e25) + assert.strictEqual(parseString('1e308'), 1e308) + assert.strictEqual(parseString('1e309'), '1e309') }) }) @@ -435,28 +436,5 @@ describe('util', () => { }) }) - describe('isSafeNumber', () => { - it('should return true if number is safe', () => { - assert.strictEqual(isSafeNumber(0), true) - assert.strictEqual(isSafeNumber(123), true) - assert.strictEqual(isSafeNumber(-123), true) - assert.strictEqual(isSafeNumber(123.123), true) - assert.strictEqual(isSafeNumber(9007199254740991), true) - assert.strictEqual(isSafeNumber(-9007199254740991), true) - }) - - it('should return false if number isn`t safe', () => { - assert.strictEqual(isSafeNumber(''), false) - assert.strictEqual(isSafeNumber(true), false) - assert.strictEqual(isSafeNumber({}), false) - assert.strictEqual(isSafeNumber([]), false) - assert.strictEqual(isSafeNumber(NaN), false) - assert.strictEqual(isSafeNumber(Infinity), false) - assert.strictEqual(isSafeNumber(new Date()), false) - assert.strictEqual(isSafeNumber(9007199254740992), false) - assert.strictEqual(isSafeNumber(-9007199254740992), false) - }) - }) - // TODO: thoroughly test all util methods }) From cdd26b64d6f26b657f93f2879da5075804475200 Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Thu, 13 Mar 2025 22:19:05 +0300 Subject: [PATCH 07/11] fix format --- src/js/util.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index 161e18169..1a6a3ce57 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -145,7 +145,7 @@ const isUrlRegex = /^https?:\/\/\S+$/ export function isUrl (text) { return (typeof text === 'string' || text instanceof String) && - isUrlRegex.test(text) + isUrlRegex.test(text) } /** @@ -338,7 +338,7 @@ export function getSelectionOffset () { const range = getSelection() if (range && 'startOffset' in range && 'endOffset' in range && - range.startContainer && (range.startContainer === range.endContainer)) { + range.startContainer && (range.startContainer === range.endContainer)) { return { startOffset: range.startOffset, endOffset: range.endOffset, @@ -713,8 +713,8 @@ export function isPromise (object) { */ export function isValidValidationError (validationError) { return typeof validationError === 'object' && - Array.isArray(validationError.path) && - typeof validationError.message === 'string' + Array.isArray(validationError.path) && + typeof validationError.message === 'string' } /** @@ -726,9 +726,9 @@ export function isValidValidationError (validationError) { export function insideRect (parent, child, margin) { const _margin = margin !== undefined ? margin : 0 return child.left - _margin >= parent.left && - child.right + _margin <= parent.right && - child.top - _margin >= parent.top && - child.bottom + _margin <= parent.bottom + child.right + _margin <= parent.right && + child.top - _margin >= parent.top && + child.bottom + _margin <= parent.bottom } /** @@ -775,12 +775,12 @@ export function textDiff (oldText, newText) { let newEnd = newText.length while (newText.charAt(start) === oldText.charAt(start) && - start < len) { + start < len) { start++ } while (newText.charAt(newEnd - 1) === oldText.charAt(oldEnd - 1) && - newEnd > start && oldEnd > 0) { + newEnd > start && oldEnd > 0) { newEnd-- oldEnd-- } From 15dbeee2ed4450462dd43df4e34371ab0885108e Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Fri, 21 Mar 2025 23:09:18 +0300 Subject: [PATCH 08/11] improve logic --- src/js/util.js | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index 1a6a3ce57..e037e9384 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -145,7 +145,7 @@ const isUrlRegex = /^https?:\/\/\S+$/ export function isUrl (text) { return (typeof text === 'string' || text instanceof String) && - isUrlRegex.test(text) + isUrlRegex.test(text) } /** @@ -338,7 +338,7 @@ export function getSelectionOffset () { const range = getSelection() if (range && 'startOffset' in range && 'endOffset' in range && - range.startContainer && (range.startContainer === range.endContainer)) { + range.startContainer && (range.startContainer === range.endContainer)) { return { startOffset: range.startOffset, endOffset: range.endOffset, @@ -713,8 +713,8 @@ export function isPromise (object) { */ export function isValidValidationError (validationError) { return typeof validationError === 'object' && - Array.isArray(validationError.path) && - typeof validationError.message === 'string' + Array.isArray(validationError.path) && + typeof validationError.message === 'string' } /** @@ -726,9 +726,9 @@ export function isValidValidationError (validationError) { export function insideRect (parent, child, margin) { const _margin = margin !== undefined ? margin : 0 return child.left - _margin >= parent.left && - child.right + _margin <= parent.right && - child.top - _margin >= parent.top && - child.bottom + _margin <= parent.bottom + child.right + _margin <= parent.right && + child.top - _margin >= parent.top && + child.bottom + _margin <= parent.bottom } /** @@ -775,12 +775,12 @@ export function textDiff (oldText, newText) { let newEnd = newText.length while (newText.charAt(start) === oldText.charAt(start) && - start < len) { + start < len) { start++ } while (newText.charAt(newEnd - 1) === oldText.charAt(oldEnd - 1) && - newEnd > start && oldEnd > 0) { + newEnd > start && oldEnd > 0) { newEnd-- oldEnd-- } @@ -1144,14 +1144,11 @@ export function parseString (str) { const num = Number(str) // will nicely fail with '123ab' const numFloat = parseFloat(str) // will nicely fail with ' ' - if (!isNaN(num) && !isNaN(numFloat)) { - if ((num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER) && isFinite(num)) { - return num - } - const isExponentialNumber = /^[+-]?\d+(\.\d+)?[eE][+-]?\d+$/ - if (isExponentialNumber.test(str) && isFinite(num)) { - return num - } + const isFiniteNumber = !isNaN(num) && !isNaN(numFloat) && isFinite(num) + const isInSafeRange = num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER + const hasSymbols = !/^\d+$/.test(str) // for 1e12, +1, 1.23 etc + if (isFiniteNumber && (isInSafeRange || hasSymbols)) { + return num } return str From ee5cdc7de3094c1e283b7cece7d1b309dd8f26f1 Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Fri, 21 Mar 2025 23:11:32 +0300 Subject: [PATCH 09/11] lint --- src/js/util.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index e037e9384..f0936de28 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -145,7 +145,7 @@ const isUrlRegex = /^https?:\/\/\S+$/ export function isUrl (text) { return (typeof text === 'string' || text instanceof String) && - isUrlRegex.test(text) + isUrlRegex.test(text) } /** @@ -338,7 +338,7 @@ export function getSelectionOffset () { const range = getSelection() if (range && 'startOffset' in range && 'endOffset' in range && - range.startContainer && (range.startContainer === range.endContainer)) { + range.startContainer && (range.startContainer === range.endContainer)) { return { startOffset: range.startOffset, endOffset: range.endOffset, @@ -713,8 +713,8 @@ export function isPromise (object) { */ export function isValidValidationError (validationError) { return typeof validationError === 'object' && - Array.isArray(validationError.path) && - typeof validationError.message === 'string' + Array.isArray(validationError.path) && + typeof validationError.message === 'string' } /** @@ -726,9 +726,9 @@ export function isValidValidationError (validationError) { export function insideRect (parent, child, margin) { const _margin = margin !== undefined ? margin : 0 return child.left - _margin >= parent.left && - child.right + _margin <= parent.right && - child.top - _margin >= parent.top && - child.bottom + _margin <= parent.bottom + child.right + _margin <= parent.right && + child.top - _margin >= parent.top && + child.bottom + _margin <= parent.bottom } /** @@ -775,12 +775,12 @@ export function textDiff (oldText, newText) { let newEnd = newText.length while (newText.charAt(start) === oldText.charAt(start) && - start < len) { + start < len) { start++ } while (newText.charAt(newEnd - 1) === oldText.charAt(oldEnd - 1) && - newEnd > start && oldEnd > 0) { + newEnd > start && oldEnd > 0) { newEnd-- oldEnd-- } From f3be85face3c2b9d0bb96519a12718d202326075 Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Wed, 26 Mar 2025 20:51:07 +0300 Subject: [PATCH 10/11] renamed hassymbols to isinteger --- src/js/util.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index f0936de28..903a11c45 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -1146,8 +1146,8 @@ export function parseString (str) { const numFloat = parseFloat(str) // will nicely fail with ' ' const isFiniteNumber = !isNaN(num) && !isNaN(numFloat) && isFinite(num) const isInSafeRange = num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER - const hasSymbols = !/^\d+$/.test(str) // for 1e12, +1, 1.23 etc - if (isFiniteNumber && (isInSafeRange || hasSymbols)) { + const isInteger = /^\d+$/.test(str) // for 1e12, +1, 1.23 etc + if (isFiniteNumber && (isInSafeRange || !isInteger)) { return num } From 37ca40a1ffe0eaf230dbf418cc873130e9b1c026 Mon Sep 17 00:00:00 2001 From: "paw.frolow" Date: Wed, 26 Mar 2025 21:04:13 +0300 Subject: [PATCH 11/11] removed isinteger comment --- src/js/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/util.js b/src/js/util.js index 903a11c45..9dd1dea28 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -1146,7 +1146,7 @@ export function parseString (str) { const numFloat = parseFloat(str) // will nicely fail with ' ' const isFiniteNumber = !isNaN(num) && !isNaN(numFloat) && isFinite(num) const isInSafeRange = num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER - const isInteger = /^\d+$/.test(str) // for 1e12, +1, 1.23 etc + const isInteger = /^\d+$/.test(str) if (isFiniteNumber && (isInSafeRange || !isInteger)) { return num }