@lvce-editor/completion-worker 1.11.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1145,7 +1145,7 @@ const isEqual$2 = (oldState, newState) => {
1145
1145
  };
1146
1146
 
1147
1147
  const isEqual$1 = (oldState, newState) => {
1148
- return oldState.items === newState.items && oldState.focusedIndex === newState.focusedIndex;
1148
+ return oldState.items === newState.items && oldState.focusedIndex === newState.focusedIndex && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY;
1149
1149
  };
1150
1150
 
1151
1151
  const isEqual = (oldState, newState) => {
@@ -1761,6 +1761,28 @@ const getNumberOfVisibleItems = (listHeight, itemHeight) => {
1761
1761
  return Math.ceil(listHeight / itemHeight) + 1;
1762
1762
  };
1763
1763
 
1764
+ const getNewOffsets = (itemHeight, finalDeltaY, deltaY, height, headerHeight, value, itemCount) => {
1765
+ const listHeight = height - headerHeight;
1766
+ const newDeltaY = clamp(value, 0, finalDeltaY);
1767
+ if (deltaY === newDeltaY) {
1768
+ return {
1769
+ modified: false,
1770
+ newDeltaY: 0,
1771
+ newMinLineY: 0,
1772
+ newMaxLineY: 0
1773
+ };
1774
+ }
1775
+ // TODO when it only moves by one px, items don't need to be rerendered, only negative margin
1776
+ const minLineY = Math.floor(newDeltaY / itemHeight);
1777
+ const maxLineY = Math.min(minLineY + getNumberOfVisibleItems(listHeight, itemHeight), itemCount - 1);
1778
+ return {
1779
+ newDeltaY: newDeltaY,
1780
+ newMinLineY: minLineY,
1781
+ newMaxLineY: maxLineY,
1782
+ modified: true
1783
+ };
1784
+ };
1785
+
1764
1786
  const setDeltaY = (state, value) => {
1765
1787
  object(state);
1766
1788
  number(value);
@@ -1769,21 +1791,23 @@ const setDeltaY = (state, value) => {
1769
1791
  finalDeltaY,
1770
1792
  deltaY,
1771
1793
  height,
1772
- headerHeight
1794
+ headerHeight,
1795
+ items
1773
1796
  } = state;
1774
- const listHeight = height - headerHeight;
1775
- const newDeltaY = clamp(value, 0, finalDeltaY);
1776
- if (deltaY === newDeltaY) {
1797
+ const {
1798
+ newDeltaY,
1799
+ newMaxLineY,
1800
+ newMinLineY,
1801
+ modified
1802
+ } = getNewOffsets(itemHeight, finalDeltaY, deltaY, height, headerHeight, value, items.length);
1803
+ if (!modified) {
1777
1804
  return state;
1778
1805
  }
1779
- // TODO when it only moves by one px, extensions don't need to be rerendered, only negative margin
1780
- const minLineY = Math.floor(newDeltaY / itemHeight);
1781
- const maxLineY = minLineY + getNumberOfVisibleItems(listHeight, itemHeight);
1782
1806
  return {
1783
1807
  ...state,
1784
1808
  deltaY: newDeltaY,
1785
- minLineY,
1786
- maxLineY
1809
+ minLineY: newMinLineY,
1810
+ maxLineY: newMaxLineY
1787
1811
  };
1788
1812
  };
1789
1813
 
@@ -1906,8 +1930,13 @@ const renderContent = (oldState, newState) => {
1906
1930
  return [SetDom2, uid, dom];
1907
1931
  };
1908
1932
 
1909
- const getEventListeners = uid => {
1910
- return [];
1933
+ const HandleWheel = 'handleWheel';
1934
+
1935
+ const getEventListeners = () => {
1936
+ return [{
1937
+ name: HandleWheel,
1938
+ params: ['EditorCompletion.handleWheel', 'event.deltaMode', 'event.deltaY']
1939
+ }];
1911
1940
  };
1912
1941
 
1913
1942
  const renderEventListeners = state => {
@@ -1922,6 +1951,10 @@ const renderFocusContext = (oldState, newState) => {
1922
1951
  return [/* method */'Viewlet.setFocusContext', FocusEditorRename];
1923
1952
  };
1924
1953
 
1954
+ const None = 'none';
1955
+ const Option = 'option';
1956
+ const ListBox = 'listbox';
1957
+
1925
1958
  const ColoredMaskIcon = 'ColoredMaskIcon';
1926
1959
  const EditorCompletion = 'EditorCompletion';
1927
1960
  const EditorCompletionItem = 'EditorCompletionItem';
@@ -1930,10 +1963,33 @@ const EditorCompletionItemFocused = 'EditorCompletionItemFocused';
1930
1963
  const EditorCompletionItemHighlight = 'EditorCompletionItemHighlight';
1931
1964
  const FileIcon = 'FileIcon';
1932
1965
  const Label = 'Label';
1966
+ const ListItems = 'ListItems';
1967
+ const ScrollBar = 'ScrollBar';
1968
+ const ScrollBarSmall = 'ScrollBarSmall';
1969
+ const ScrollBarThumb = 'ScrollBarThumb';
1933
1970
  const Viewlet = 'Viewlet';
1934
1971
 
1935
- const None = 'none';
1936
- const Option = 'option';
1972
+ const emptyObject = {};
1973
+ const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1974
+ const i18nString = (key, placeholders = emptyObject) => {
1975
+ if (placeholders === emptyObject) {
1976
+ return key;
1977
+ }
1978
+ const replacer = (match, rest) => {
1979
+ return placeholders[rest];
1980
+ };
1981
+ return key.replaceAll(RE_PLACEHOLDER, replacer);
1982
+ };
1983
+
1984
+ const NoSuggestions = 'No Suggestions';
1985
+ const Suggest = 'Suggest';
1986
+
1987
+ const noSuggestions = () => {
1988
+ return i18nString(NoSuggestions);
1989
+ };
1990
+ const suggest = () => {
1991
+ return i18nString(Suggest);
1992
+ };
1937
1993
 
1938
1994
  const Div = 4;
1939
1995
  const Span = 8;
@@ -1971,6 +2027,12 @@ const text = data => {
1971
2027
  childCount: 0
1972
2028
  };
1973
2029
  };
2030
+ const px = value => {
2031
+ return `${value}px`;
2032
+ };
2033
+ const position = (x, y) => {
2034
+ return `${x}px ${y}px`;
2035
+ };
1974
2036
 
1975
2037
  const label1 = {
1976
2038
  type: Div,
@@ -2041,24 +2103,6 @@ const getCompletionItemVirtualDom = visibleItem => {
2041
2103
  }, getIconDom(fileIcon, symbolName), ...getHighlightedLabelDom(label, highlights)];
2042
2104
  };
2043
2105
 
2044
- const emptyObject = {};
2045
- const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
2046
- const i18nString = (key, placeholders = emptyObject) => {
2047
- if (placeholders === emptyObject) {
2048
- return key;
2049
- }
2050
- const replacer = (match, rest) => {
2051
- return placeholders[rest];
2052
- };
2053
- return key.replaceAll(RE_PLACEHOLDER, replacer);
2054
- };
2055
-
2056
- const NoSuggestions = 'No Suggestions';
2057
-
2058
- const noSuggestions = () => {
2059
- return i18nString(NoSuggestions);
2060
- };
2061
-
2062
2106
  const parentNode = {
2063
2107
  type: Div,
2064
2108
  childCount: 1
@@ -2079,24 +2123,60 @@ const getCompletionItemsVirtualDom = visibleItems => {
2079
2123
  return dom;
2080
2124
  };
2081
2125
 
2082
- const getCompletionVirtualDom = visibleItems => {
2126
+ const getScrollBarVirtualDom = (scrollBarHeight, scrollBarTop) => {
2127
+ const shouldShowScrollbar = scrollBarHeight > 0;
2128
+ if (!shouldShowScrollbar) {
2129
+ return [];
2130
+ }
2131
+ const heightString = px(scrollBarHeight);
2132
+ const translateString = position(0, scrollBarTop);
2083
2133
  return [{
2084
2134
  type: Div,
2085
- className: mergeClassNames(Viewlet, EditorCompletion),
2086
- id: 'Completions',
2135
+ className: mergeClassNames(ScrollBar, ScrollBarSmall),
2087
2136
  childCount: 1
2088
2137
  }, {
2089
2138
  type: Div,
2090
- className: 'ListItems',
2091
- role: 'listbox',
2092
- ariaLabel: 'Suggest',
2093
- childCount: 1
2094
- }, ...getCompletionItemsVirtualDom(visibleItems)
2139
+ className: ScrollBarThumb,
2140
+ childCount: 0,
2141
+ height: heightString,
2142
+ translate: translateString
2143
+ }];
2144
+ };
2145
+
2146
+ const Completions = 'Completions';
2095
2147
 
2148
+ const getCompletionVirtualDom = (visibleItems, scrollBarHeight, scrollBarTop) => {
2149
+ const scrollBarDom = getScrollBarVirtualDom(scrollBarHeight, scrollBarTop);
2150
+ const childCount = scrollBarDom.length === 0 ? 1 : 2;
2151
+ return [{
2152
+ type: Div,
2153
+ className: mergeClassNames(Viewlet, EditorCompletion),
2154
+ id: Completions,
2155
+ childCount: childCount
2156
+ }, {
2157
+ type: Div,
2158
+ className: ListItems,
2159
+ role: ListBox,
2160
+ ariaLabel: suggest(),
2161
+ childCount: 1,
2162
+ onWheel: HandleWheel
2163
+ }, ...getCompletionItemsVirtualDom(visibleItems), ...scrollBarDom
2096
2164
  // TODO render scrollbar
2097
2165
  ];
2098
2166
  };
2099
2167
 
2168
+ const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
2169
+ if (size >= contentSize) {
2170
+ return 0;
2171
+ }
2172
+ return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
2173
+ };
2174
+
2175
+ const getScrollBarTop = (height, contentHeight, scrollTop) => {
2176
+ const scrollBarTop = Math.round(scrollTop / contentHeight * height);
2177
+ return scrollBarTop;
2178
+ };
2179
+
2100
2180
  const Property = 1;
2101
2181
  const Value = 2;
2102
2182
  const Function = 3;
@@ -2158,11 +2238,16 @@ const getHighlights = item => {
2158
2238
  const getLabel = item => {
2159
2239
  return item.label;
2160
2240
  };
2161
- const getVisibleIem = (item, itemHeight, leadingWord, i, focusedIndex) => {
2241
+
2242
+ const getTop = (i, minLineY, itemHeight, relative) => {
2243
+ return (i - minLineY) * itemHeight - relative;
2244
+ };
2245
+
2246
+ const getVisibleIem = (item, itemHeight, leadingWord, i, minLineY, focusedIndex, relative) => {
2162
2247
  return {
2163
2248
  label: getLabel(item),
2164
2249
  symbolName: getSymbolName(item.kind),
2165
- top: i * itemHeight,
2250
+ top: getTop(i, minLineY, itemHeight, relative),
2166
2251
  highlights: getHighlights(item),
2167
2252
  focused: i === focusedIndex,
2168
2253
  deprecated: item.flags & Deprecated,
@@ -2170,21 +2255,27 @@ const getVisibleIem = (item, itemHeight, leadingWord, i, focusedIndex) => {
2170
2255
  };
2171
2256
  };
2172
2257
 
2173
- const getVisibleItems = (filteredItems, itemHeight, leadingWord, minLineY, maxLineY, focusedIndex) => {
2258
+ const getVisibleItems = (filteredItems, itemHeight, leadingWord, minLineY, maxLineY, focusedIndex, deltaY) => {
2174
2259
  const visibleItems = [];
2260
+ const relative = deltaY % itemHeight;
2175
2261
  for (let i = minLineY; i < maxLineY; i++) {
2176
2262
  const filteredItem = filteredItems[i];
2177
- visibleItems.push(getVisibleIem(filteredItem, itemHeight, leadingWord, i, focusedIndex));
2263
+ visibleItems.push(getVisibleIem(filteredItem, itemHeight, leadingWord, i, minLineY, focusedIndex, relative));
2178
2264
  }
2179
2265
  return visibleItems;
2180
2266
  };
2181
2267
 
2182
2268
  const renderItems = (oldState, newState) => {
2183
2269
  const {
2184
- uid
2270
+ uid,
2271
+ height,
2272
+ deltaY
2185
2273
  } = newState;
2186
- const visibleItems = getVisibleItems(newState.items, newState.itemHeight, newState.leadingWord, newState.minLineY, newState.maxLineY, newState.focusedIndex);
2187
- const dom = getCompletionVirtualDom(visibleItems);
2274
+ const visibleItems = getVisibleItems(newState.items, newState.itemHeight, newState.leadingWord, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.deltaY);
2275
+ const contentHeight = newState.items.length * newState.itemHeight;
2276
+ const scrollBarHeight = getScrollBarSize(height, contentHeight, 20);
2277
+ const scrollBarTop = getScrollBarTop(height, contentHeight, deltaY);
2278
+ const dom = getCompletionVirtualDom(visibleItems, scrollBarHeight, scrollBarTop);
2188
2279
  return [SetDom2, uid, dom];
2189
2280
  };
2190
2281
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/completion-worker",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "description": "Web Worker for the find widget in Lvce Editor",
5
5
  "repository": {
6
6
  "type": "git",