history.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { ArrayNavigator } from './navigator.js';
  6. export class HistoryNavigator {
  7. constructor(history = [], limit = 10) {
  8. this._initialize(history);
  9. this._limit = limit;
  10. this._onChange();
  11. }
  12. getHistory() {
  13. return this._elements;
  14. }
  15. add(t) {
  16. this._history.delete(t);
  17. this._history.add(t);
  18. this._onChange();
  19. }
  20. next() {
  21. // This will navigate past the end of the last element, and in that case the input should be cleared
  22. return this._navigator.next();
  23. }
  24. previous() {
  25. if (this._currentPosition() !== 0) {
  26. return this._navigator.previous();
  27. }
  28. return null;
  29. }
  30. current() {
  31. return this._navigator.current();
  32. }
  33. first() {
  34. return this._navigator.first();
  35. }
  36. last() {
  37. return this._navigator.last();
  38. }
  39. isLast() {
  40. return this._currentPosition() >= this._elements.length - 1;
  41. }
  42. isNowhere() {
  43. return this._navigator.current() === null;
  44. }
  45. has(t) {
  46. return this._history.has(t);
  47. }
  48. _onChange() {
  49. this._reduceToLimit();
  50. const elements = this._elements;
  51. this._navigator = new ArrayNavigator(elements, 0, elements.length, elements.length);
  52. }
  53. _reduceToLimit() {
  54. const data = this._elements;
  55. if (data.length > this._limit) {
  56. this._initialize(data.slice(data.length - this._limit));
  57. }
  58. }
  59. _currentPosition() {
  60. const currentElement = this._navigator.current();
  61. if (!currentElement) {
  62. return -1;
  63. }
  64. return this._elements.indexOf(currentElement);
  65. }
  66. _initialize(history) {
  67. this._history = new Set();
  68. for (const entry of history) {
  69. this._history.add(entry);
  70. }
  71. }
  72. get _elements() {
  73. const elements = [];
  74. this._history.forEach(e => elements.push(e));
  75. return elements;
  76. }
  77. }