* Handler for 'paste' event * * @param {Event|ClipboardEvent} e
(e)
| 7078 | * @param {Event|ClipboardEvent} e |
| 7079 | */ |
| 7080 | _onPaste(e) { |
| 7081 | //FIXME When pasting '000' on a thousand group selection, the whole selection gets deleted, and only one '0' is pasted (cf. issue #302) |
| 7082 | // The event is prevented by default, since otherwise the user would be able to paste invalid characters into the input |
| 7083 | e.preventDefault(); |
| 7084 | |
| 7085 | if (this.settings.readOnly || this.domElement.readOnly || this.domElement.disabled) { |
| 7086 | // Do not allow pasting in a readonly element (fix issue #505) |
| 7087 | return; |
| 7088 | } |
| 7089 | |
| 7090 | let rawPastedText; |
| 7091 | if (e.clipboardData && e.clipboardData.getData) { |
| 7092 | rawPastedText = e.clipboardData.getData('text/plain'); |
| 7093 | } else { |
| 7094 | AutoNumericHelper.throwError('Unable to retrieve the pasted value. Please use a modern browser (i.e. Firefox or Chromium).'); |
| 7095 | } |
| 7096 | |
| 7097 | // Fix for firefox paste handling on `contenteditable` elements where `e.target` is the text node, not the element |
| 7098 | let eventTarget; |
| 7099 | if (!e.target.tagName) { |
| 7100 | eventTarget = e.explicitOriginalTarget; |
| 7101 | } else { |
| 7102 | eventTarget = e.target; |
| 7103 | } |
| 7104 | |
| 7105 | // 0. Special case if the user has selected all the input text before pasting |
| 7106 | const initialFormattedValue = AutoNumericHelper.getElementValue(eventTarget); |
| 7107 | const selectionStart = eventTarget.selectionStart || 0; |
| 7108 | const selectionEnd = eventTarget.selectionEnd || 0; |
| 7109 | const selectionSize = selectionEnd - selectionStart; |
| 7110 | |
| 7111 | if (selectionSize === initialFormattedValue.length) { // If all the element text is selected |
| 7112 | //TODO Refactor this with the tests below |
| 7113 | // Since the whole element content will be replaced, no need to complicate things and directly test for the validity of the pasted content, then set the `rawValue` and caret position (fix issue #482) |
| 7114 | // 1. Strip all thousand separators, brackets and currency sign, and convert the decimal character to a dot |
| 7115 | const untranslatedPastedText = this._preparePastedText(rawPastedText); |
| 7116 | let pastedRawValue = AutoNumericHelper.arabicToLatinNumbers(untranslatedPastedText, false, false, false); // Allow pasting arabic numbers |
| 7117 | |
| 7118 | // 2. Check that the paste is a valid number once it has been normalized to a raw value |
| 7119 | if (pastedRawValue === '.' || pastedRawValue === '' || (pastedRawValue !== '.' && !AutoNumericHelper.isNumber(pastedRawValue))) { |
| 7120 | this.formatted = true; // This prevents the `keyup` event on the `v` key during a paste to try to format an empty value. |
| 7121 | // If the user tries to paste a single decimal character (that has been translated to '.' already) or the empty value, ignore the paste |
| 7122 | if (this.settings.onInvalidPaste === AutoNumeric.options.onInvalidPaste.error) { |
| 7123 | AutoNumericHelper.throwError(`The pasted value '${rawPastedText}' is not a valid paste content.`); |
| 7124 | } |
| 7125 | |
| 7126 | return; |
| 7127 | } |
| 7128 | |
| 7129 | // 2a. Handle 'truncate' or 'replace' paste behavior - they work the same way here because the whole text in the input is selected and there are no digits to the right of the caret to be replaced |
| 7130 | if (this.settings.onInvalidPaste === AutoNumeric.options.onInvalidPaste.truncate || this.settings.onInvalidPaste === AutoNumeric.options.onInvalidPaste.replace) { |
| 7131 | const minParse = AutoNumericHelper.parseStr(this.settings.minimumValue); |
| 7132 | const maxParse = AutoNumericHelper.parseStr(this.settings.maximumValue); |
| 7133 | let lastGoodKnownResult = ''; // This is set as the default, in case we do not add even one number |
| 7134 | let pastedTextIndex = 0; |
| 7135 | while (pastedTextIndex < pastedRawValue.length) { |
| 7136 | // Modify the result with another pasted character |
| 7137 | const newCandidate = lastGoodKnownResult + pastedRawValue[pastedTextIndex]; |
no test coverage detected