UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

173 lines (134 loc) 5.65 kB
/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ /** @class Siesta.Test.TextSelection This is a mixin providing text selection functionality. */ Role('Siesta.Test.TextSelection', { methods : { /** * Utility method which returns the selected text in the passed element or in the document * @param {Siesta.Test.ActionTarget} el The element * @return {String} The selected text */ getSelectedText : function (el) { el = this.normalizeElement(el); if ('selectionStart' in el) { try { return el.value.substring(el.selectionStart, el.selectionEnd); } catch (e) { // the "email" and "number" input fields (possibly some other too) does not allow to access // the "selectionStart/End" properties and throws exceptions } } var win = this.global, doc = win.document; if (win.getSelection) { return win.getSelection().toString(); } else if (doc.getSelection) { return doc.getSelection(); } else if (doc.selection) { return doc.selection.createRange().text; } }, /** * Utility method which selects text in the passed element (should be an <input> element). * @param {Siesta.Test.ActionTarget} el The element * @param {Int} start (optional) The selection start index * @param {Int} end (optional) The selection end index */ selectText : function (el, start, end, callback) { el = this.normalizeElement(el, true); if (el && this.elementSupportsSelection(el)) { var v = el.value || el.innerHTML, doFocus = true; if (v.length > 0) { start = start === undefined ? 0 : start; end = end === undefined ? v.length : end; if (el.setSelectionRange) { try { // can throw exception in IE9 (if element is not visible) el.setSelectionRange(start, end); } catch (e) { } } else if (el.createTextRange) { var R = el.createTextRange(); R.moveStart('character', start); R.moveEnd('character', end - v.length); R.select(); } doFocus = bowser.gecko || bowser.opera; } if (doFocus) { this.focus(el); } } callback && callback.call(this); }, // Returns undefined if caret pos cannot be determined (older IEs with contentEditable) getCaretPosition : function (el) { var pos; var win = this.global; var document = win.document; if ('selectionStart' in el) { try { // the exception can be thrown in case of manipulating with input#type=email fields // and possibly some other input types pos = el.selectionStart; } catch (e) { pos = null } } else if (win.getSelection && this.isEditableNode(el)){ var sel = win.getSelection(); if (sel.rangeCount) { var range = sel.getRangeAt(0); if (range.commonAncestorContainer.parentNode == el) { pos = range.endOffset; } } } else if (document.selection) { // Legacy IE this.focus(el) var oSel = document.selection.createRange(); oSel.moveStart('character', -el.value.length); pos = oSel.text.length; } return pos; }, setCaretPosition : function (el, caretPos) { if (el.createTextRange) { // seems range methods throws sometimes in IE try { var range = el.createTextRange(); range.move('character', caretPos); range.select(); } catch (e) { } } else { if (el.setSelectionRange) { this.focus(el) try { // the exception can be thrown in case of manipulating with input#type=email fields // and possibly some other input types el.setSelectionRange(caretPos, caretPos); } catch (e) { } } else { this.focus(el) } } }, moveCaretPosition : function (el, distance) { var pos = Math.min(Math.max(0, this.getCaretPosition(el) + distance), el.value.length); this.setCaretPosition(el, pos); }, elementSupportsSelection : function (el) { var tagName = el.tagName.toLowerCase(); var inputTypes = /^text|password|tel|url|search$/i; return tagName === 'textarea' || tagName === 'input' && inputTypes.test(el.getAttribute('type')); } } })