UI.js 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use strict';
  2. const UIValue = Symbol('Displayed value in UI');
  3. const UISelection = Symbol('Displayed selection in UI');
  4. const InitialValue = Symbol('Initial value to compare on blur');
  5. function isUIValue(value) {
  6. return typeof value === 'object' && UIValue in value;
  7. }
  8. function isUISelectionStart(start) {
  9. return !!start && typeof start === 'object' && UISelection in start;
  10. }
  11. function setUIValue(element, value) {
  12. if (element[InitialValue] === undefined) {
  13. element[InitialValue] = element.value;
  14. }
  15. element[UIValue] = value;
  16. // eslint-disable-next-line no-new-wrappers
  17. element.value = Object.assign(new String(value), {
  18. [UIValue]: true
  19. });
  20. }
  21. function getUIValue(element) {
  22. return element[UIValue] === undefined ? element.value : String(element[UIValue]);
  23. }
  24. /** Flag the IDL value as clean. This does not change the value.*/ function setUIValueClean(element) {
  25. element[UIValue] = undefined;
  26. }
  27. function clearInitialValue(element) {
  28. element[InitialValue] = undefined;
  29. }
  30. function getInitialValue(element) {
  31. return element[InitialValue];
  32. }
  33. function setUISelectionRaw(element, selection) {
  34. element[UISelection] = selection;
  35. }
  36. function setUISelection(element, { focusOffset: focusOffsetParam, anchorOffset: anchorOffsetParam = focusOffsetParam }, mode = 'replace') {
  37. const valueLength = getUIValue(element).length;
  38. const sanitizeOffset = (o)=>Math.max(0, Math.min(valueLength, o));
  39. const anchorOffset = mode === 'replace' || element[UISelection] === undefined ? sanitizeOffset(anchorOffsetParam) : element[UISelection].anchorOffset;
  40. const focusOffset = sanitizeOffset(focusOffsetParam);
  41. const startOffset = Math.min(anchorOffset, focusOffset);
  42. const endOffset = Math.max(anchorOffset, focusOffset);
  43. element[UISelection] = {
  44. anchorOffset,
  45. focusOffset
  46. };
  47. if (element.selectionStart === startOffset && element.selectionEnd === endOffset) {
  48. return;
  49. }
  50. // eslint-disable-next-line no-new-wrappers
  51. const startObj = Object.assign(new Number(startOffset), {
  52. [UISelection]: true
  53. });
  54. try {
  55. element.setSelectionRange(startObj, endOffset);
  56. } catch {
  57. // DOMException for invalid state is expected when calling this
  58. // on an element without support for setSelectionRange
  59. }
  60. }
  61. function getUISelection(element) {
  62. var _element_selectionStart, _element_selectionEnd, _element_UISelection;
  63. const sel = (_element_UISelection = element[UISelection]) !== null && _element_UISelection !== undefined ? _element_UISelection : {
  64. anchorOffset: (_element_selectionStart = element.selectionStart) !== null && _element_selectionStart !== undefined ? _element_selectionStart : 0,
  65. focusOffset: (_element_selectionEnd = element.selectionEnd) !== null && _element_selectionEnd !== undefined ? _element_selectionEnd : 0
  66. };
  67. return {
  68. ...sel,
  69. startOffset: Math.min(sel.anchorOffset, sel.focusOffset),
  70. endOffset: Math.max(sel.anchorOffset, sel.focusOffset)
  71. };
  72. }
  73. function hasUISelection(element) {
  74. return !!element[UISelection];
  75. }
  76. /** Flag the IDL selection as clean. This does not change the selection. */ function setUISelectionClean(element) {
  77. element[UISelection] = undefined;
  78. }
  79. exports.clearInitialValue = clearInitialValue;
  80. exports.getInitialValue = getInitialValue;
  81. exports.getUISelection = getUISelection;
  82. exports.getUIValue = getUIValue;
  83. exports.hasUISelection = hasUISelection;
  84. exports.isUISelectionStart = isUISelectionStart;
  85. exports.isUIValue = isUIValue;
  86. exports.setUISelection = setUISelection;
  87. exports.setUISelectionClean = setUISelectionClean;
  88. exports.setUISelectionRaw = setUISelectionRaw;
  89. exports.setUIValue = setUIValue;
  90. exports.setUIValueClean = setUIValueClean;