chromium-tabs 0.1.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.
- package/LICENSE +31 -0
- package/README.md +164 -0
- package/dist/chunk-2DTGNBUT.js +1667 -0
- package/dist/chunk-2DTGNBUT.js.map +1 -0
- package/dist/core/index.cjs +1699 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +761 -0
- package/dist/core/index.d.ts +761 -0
- package/dist/core/index.js +19 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.cjs +2084 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +128 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.js +394 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +165 -0
- package/package.json +77 -0
|
@@ -0,0 +1,761 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of ui/base/models/list_selection_model.{h,cc}.
|
|
3
|
+
*
|
|
4
|
+
* Selection model represented as a list of indexes. In addition to the set of
|
|
5
|
+
* selected indices it maintains:
|
|
6
|
+
*
|
|
7
|
+
* - active: the index of the currently visible item, or null if nothing is
|
|
8
|
+
* selected.
|
|
9
|
+
* - anchor: the index of the last item the user clicked on. Extending the
|
|
10
|
+
* selection extends it from this index. Null if nothing is selected.
|
|
11
|
+
*
|
|
12
|
+
* Typically there is one selected item, in which case anchor and active are
|
|
13
|
+
* the same.
|
|
14
|
+
*/
|
|
15
|
+
declare class ListSelectionModel {
|
|
16
|
+
private selectedIndices_;
|
|
17
|
+
private active_;
|
|
18
|
+
private anchor_;
|
|
19
|
+
get anchor(): number | null;
|
|
20
|
+
setAnchor(anchor: number | null): void;
|
|
21
|
+
get active(): number | null;
|
|
22
|
+
setActive(active: number | null): void;
|
|
23
|
+
/** True if nothing is selected. */
|
|
24
|
+
get empty(): boolean;
|
|
25
|
+
get size(): number;
|
|
26
|
+
/** Selected indices in ascending order. */
|
|
27
|
+
selectedIndices(): number[];
|
|
28
|
+
/**
|
|
29
|
+
* Increments all indices >= index. Used when a new item is inserted.
|
|
30
|
+
* list_selection_model.cc:112
|
|
31
|
+
*/
|
|
32
|
+
incrementFrom(index: number): void;
|
|
33
|
+
/**
|
|
34
|
+
* Shifts all indices > index down by 1; index itself is removed from the
|
|
35
|
+
* selection. Used when an item is removed. list_selection_model.cc:122
|
|
36
|
+
*/
|
|
37
|
+
decrementFrom(index: number): void;
|
|
38
|
+
/** Sets the anchor, active and selection to index. */
|
|
39
|
+
setSelectedIndex(index: number | null): void;
|
|
40
|
+
isSelected(index: number): boolean;
|
|
41
|
+
/** Adds index to the selection without changing active or anchor. */
|
|
42
|
+
addIndexToSelection(index: number): void;
|
|
43
|
+
/** Adds [indexStart, indexEnd] inclusive without changing active or anchor. */
|
|
44
|
+
addIndexRangeToSelection(indexStart: number, indexEnd: number): void;
|
|
45
|
+
/** Removes index from the selection without changing active or anchor. */
|
|
46
|
+
removeIndexFromSelection(index: number): void;
|
|
47
|
+
/**
|
|
48
|
+
* Sets the selection to the range anchor..index. If there is no anchor,
|
|
49
|
+
* behaves like setSelectedIndex. list_selection_model.cc:171
|
|
50
|
+
*/
|
|
51
|
+
setSelectionFromAnchorTo(index: number): void;
|
|
52
|
+
/**
|
|
53
|
+
* Makes sure anchor..index are selected, adding to the existing selection.
|
|
54
|
+
* list_selection_model.cc:186
|
|
55
|
+
*/
|
|
56
|
+
addSelectionFromAnchorTo(index: number): void;
|
|
57
|
+
/**
|
|
58
|
+
* Invoked when `length` items move from oldIndex to newIndex. If moving to
|
|
59
|
+
* a greater index, newIndex is the index *after* removing the moved range.
|
|
60
|
+
* list_selection_model.cc:199
|
|
61
|
+
*/
|
|
62
|
+
move(oldIndex: number, newIndex: number, length: number): void;
|
|
63
|
+
/** Clears the selection, anchor and active. */
|
|
64
|
+
clear(): void;
|
|
65
|
+
clone(): ListSelectionModel;
|
|
66
|
+
equals(other: ListSelectionModel): boolean;
|
|
67
|
+
/** 'active=X anchor=X selection=X X X...' — matches the C++ ToString. */
|
|
68
|
+
toString(): string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Core types. Ported from chromium-reference/chrome/browser/ui/tabs/tab_enums.h
|
|
73
|
+
* and the supporting types in tab_strip_model.h.
|
|
74
|
+
*
|
|
75
|
+
* Chrome's tabs carry a WebContents. This library carries a generic `data: T`
|
|
76
|
+
* payload instead so it works for any application.
|
|
77
|
+
*/
|
|
78
|
+
/** Sentinel for "no tab" — mirrors TabStripModel::kNoTab. */
|
|
79
|
+
declare const NO_TAB = -1;
|
|
80
|
+
type TabId = string;
|
|
81
|
+
type TabGroupId = string;
|
|
82
|
+
/**
|
|
83
|
+
* How a tab is being opened. Trimmed from ui::PageTransition to the two
|
|
84
|
+
* qualities the TabStripModel actually branches on (tab_strip_model.cc:1731,
|
|
85
|
+
* 1786): link-like openings (inherit opener, insert adjacent) and typed/manual
|
|
86
|
+
* openings (append at end, transient opener at end-of-strip).
|
|
87
|
+
*/
|
|
88
|
+
type TabOpenCause = 'link' | 'typed' | 'other';
|
|
89
|
+
/** Bitmask flags used when adding tabs. Mirrors AddTabTypes (tab_enums.h:42). */
|
|
90
|
+
declare const AddTabFlags: {
|
|
91
|
+
readonly NONE: 0;
|
|
92
|
+
/** The tab should become the active tab. */
|
|
93
|
+
readonly ACTIVE: number;
|
|
94
|
+
/** The tab should be pinned. */
|
|
95
|
+
readonly PINNED: number;
|
|
96
|
+
/**
|
|
97
|
+
* Use the caller-supplied index rather than letting the model determine
|
|
98
|
+
* the position from the open cause and opener relationships.
|
|
99
|
+
*/
|
|
100
|
+
readonly FORCE_INDEX: number;
|
|
101
|
+
/** Set the new tab's opener to the currently active tab. */
|
|
102
|
+
readonly INHERIT_OPENER: number;
|
|
103
|
+
};
|
|
104
|
+
/** Bitmask flags used when closing tabs. Mirrors TabCloseTypes (tab_enums.h:26). */
|
|
105
|
+
declare const CloseTabFlags: {
|
|
106
|
+
readonly NONE: 0;
|
|
107
|
+
/** The close was triggered directly by a user gesture. */
|
|
108
|
+
readonly USER_GESTURE: number;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Visual data attached to a tab group. Mirrors tab_groups::TabGroupVisualData.
|
|
112
|
+
* Chrome cycles through 9 named colors; we keep the names so UIs can map them
|
|
113
|
+
* to whatever palette they like.
|
|
114
|
+
*/
|
|
115
|
+
type TabGroupColor = 'grey' | 'blue' | 'red' | 'yellow' | 'green' | 'pink' | 'purple' | 'cyan' | 'orange';
|
|
116
|
+
declare const TAB_GROUP_COLORS: readonly TabGroupColor[];
|
|
117
|
+
interface TabGroupVisualData {
|
|
118
|
+
title: string;
|
|
119
|
+
color: TabGroupColor;
|
|
120
|
+
isCollapsed: boolean;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A tab in the strip. Identity is the object (like Chrome's TabModel pointer);
|
|
124
|
+
* `id` exists for React keys and serialization.
|
|
125
|
+
*/
|
|
126
|
+
interface Tab<T = unknown> {
|
|
127
|
+
readonly id: TabId;
|
|
128
|
+
/** Application payload (your "WebContents"). */
|
|
129
|
+
data: T;
|
|
130
|
+
/** The tab that opened this tab, if tracked. Mirrors TabModel::opener(). */
|
|
131
|
+
opener: Tab<T> | null;
|
|
132
|
+
/**
|
|
133
|
+
* When true, the opener relationship is cleared the next time the active
|
|
134
|
+
* tab changes. Set for typed new-tabs at end of strip ("quick look-up"
|
|
135
|
+
* pattern, tab_strip_model.cc:1804-1810).
|
|
136
|
+
*/
|
|
137
|
+
resetOpenerOnActiveTabChange: boolean;
|
|
138
|
+
/** Pinned tabs are locked to the left side of the strip. */
|
|
139
|
+
pinned: boolean;
|
|
140
|
+
/** Group membership, if any. Pinned tabs are never grouped. */
|
|
141
|
+
group: TabGroupId | null;
|
|
142
|
+
/** Blocked by a modal — selectable but flagged. Mirrors TabModel::blocked. */
|
|
143
|
+
blocked: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* True when the tab's content has been dropped to save memory. The tab
|
|
146
|
+
* stays in the strip (title intact via `data`); content remounts fresh
|
|
147
|
+
* when the tab is next activated. Mirrors TabLifecycleUnit::is_discarded_
|
|
148
|
+
* (tab_lifecycle_unit.cc:312) and WebContents::WasDiscarded.
|
|
149
|
+
*/
|
|
150
|
+
discarded: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Wall-clock ms of the last time this tab stopped being active, or
|
|
153
|
+
* Infinity while it is active. Used for least-recently-used discard
|
|
154
|
+
* ordering. Mirrors last_focused_time_ (tab_lifecycle_unit.cc:142, which
|
|
155
|
+
* uses Time::Max() while focused).
|
|
156
|
+
*/
|
|
157
|
+
lastActiveAt: number;
|
|
158
|
+
/**
|
|
159
|
+
* Per-tab opt-out from automatic discarding. Mirrors
|
|
160
|
+
* TabLifecycleUnit::auto_discardable_ (the extensions setAutoDiscardable
|
|
161
|
+
* API surface).
|
|
162
|
+
*/
|
|
163
|
+
autoDiscardable: boolean;
|
|
164
|
+
}
|
|
165
|
+
interface TabGroup {
|
|
166
|
+
readonly id: TabGroupId;
|
|
167
|
+
visualData: TabGroupVisualData;
|
|
168
|
+
}
|
|
169
|
+
/** Options for TabStripModel.addTab / insertTabAt. */
|
|
170
|
+
interface AddTabOptions {
|
|
171
|
+
/** Target index. Omit (or pass NO_TAB) to let the model decide. */
|
|
172
|
+
index?: number;
|
|
173
|
+
/** What kind of action opened this tab. Default 'other'. */
|
|
174
|
+
cause?: TabOpenCause;
|
|
175
|
+
/** Bitmask of AddTabFlags. */
|
|
176
|
+
flags?: number;
|
|
177
|
+
/** Insert directly into an existing group. */
|
|
178
|
+
group?: TabGroupId;
|
|
179
|
+
/** Stable id; generated if omitted. */
|
|
180
|
+
id?: TabId;
|
|
181
|
+
}
|
|
182
|
+
/** Desired state of one tab, for TabStripModel.reconcile. */
|
|
183
|
+
interface ReconcileTab<T> {
|
|
184
|
+
id: TabId;
|
|
185
|
+
data: T;
|
|
186
|
+
/** Defaults to false. The list should be pinned-first-consistent. */
|
|
187
|
+
pinned?: boolean;
|
|
188
|
+
}
|
|
189
|
+
interface ReconcileOptions<T> {
|
|
190
|
+
/** Tab to end up active. Omit to leave activation to the model. */
|
|
191
|
+
activeId?: TabId | null;
|
|
192
|
+
/** Equality for data payloads; defaults to Object.is. */
|
|
193
|
+
dataEquals?: (a: T, b: T) => boolean;
|
|
194
|
+
}
|
|
195
|
+
interface TabStripModelOptions<T> {
|
|
196
|
+
/**
|
|
197
|
+
* Veto tab closes (Chrome: IsTabClosable / policy). Return false to keep
|
|
198
|
+
* the tab open; observers get a tabCloseCancelled event.
|
|
199
|
+
*/
|
|
200
|
+
canCloseTab?: (tab: Tab<T>) => boolean;
|
|
201
|
+
/** Disable the group feature entirely (Chrome: null TabGroupModelFactory). */
|
|
202
|
+
supportsGroups?: boolean;
|
|
203
|
+
/** Custom id generator for tabs and groups. */
|
|
204
|
+
generateId?: () => string;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Observer event types. Ported from
|
|
209
|
+
* chromium-reference/chrome/browser/ui/tabs/tab_strip_model_observer.h.
|
|
210
|
+
*
|
|
211
|
+
* Changes to (1) the selection model, (2) the active tab, and (3) the set of
|
|
212
|
+
* tabs are bundled into a single onTabStripModelChanged call because the
|
|
213
|
+
* first two consist of indices into the list determined by the third.
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
/** Mirrors TabStripModelChange::Type. */
|
|
217
|
+
type TabStripModelChange<T> = {
|
|
218
|
+
type: 'selectionOnly';
|
|
219
|
+
} | {
|
|
220
|
+
/**
|
|
221
|
+
* Tabs were inserted at the given indices (index is the position at the
|
|
222
|
+
* time of that insertion, see tab_strip_model_observer.h:88).
|
|
223
|
+
*/
|
|
224
|
+
type: 'inserted';
|
|
225
|
+
contents: Array<{
|
|
226
|
+
tab: Tab<T>;
|
|
227
|
+
index: number;
|
|
228
|
+
}>;
|
|
229
|
+
} | {
|
|
230
|
+
/**
|
|
231
|
+
* Tabs were removed; index is the position at the time of that removal
|
|
232
|
+
* (tab_strip_model_observer.h:123).
|
|
233
|
+
*/
|
|
234
|
+
type: 'removed';
|
|
235
|
+
contents: Array<{
|
|
236
|
+
tab: Tab<T>;
|
|
237
|
+
index: number;
|
|
238
|
+
}>;
|
|
239
|
+
} | {
|
|
240
|
+
type: 'moved';
|
|
241
|
+
tab: Tab<T>;
|
|
242
|
+
fromIndex: number;
|
|
243
|
+
toIndex: number;
|
|
244
|
+
} | {
|
|
245
|
+
type: 'replaced';
|
|
246
|
+
tab: Tab<T>;
|
|
247
|
+
oldData: T;
|
|
248
|
+
newData: T;
|
|
249
|
+
index: number;
|
|
250
|
+
};
|
|
251
|
+
/** Mirrors TabStripSelectionChange. */
|
|
252
|
+
interface TabStripSelectionChange<T> {
|
|
253
|
+
oldTab: Tab<T> | null;
|
|
254
|
+
newTab: Tab<T> | null;
|
|
255
|
+
oldModel: ListSelectionModel;
|
|
256
|
+
newModel: ListSelectionModel;
|
|
257
|
+
/** Mirrors TabStripModelObserver::CHANGE_REASON_USER_GESTURE. */
|
|
258
|
+
reason: 'none' | 'userGesture';
|
|
259
|
+
get activeTabChanged(): boolean;
|
|
260
|
+
get selectionChanged(): boolean;
|
|
261
|
+
}
|
|
262
|
+
/** Mirrors TabGroupChange::Type (minus editor-UI concerns). */
|
|
263
|
+
type TabGroupChange = {
|
|
264
|
+
type: 'created';
|
|
265
|
+
groupId: TabGroupId;
|
|
266
|
+
} | {
|
|
267
|
+
type: 'visualsChanged';
|
|
268
|
+
groupId: TabGroupId;
|
|
269
|
+
oldVisuals: TabGroupVisualData;
|
|
270
|
+
newVisuals: TabGroupVisualData;
|
|
271
|
+
} | {
|
|
272
|
+
type: 'moved';
|
|
273
|
+
groupId: TabGroupId;
|
|
274
|
+
} | {
|
|
275
|
+
type: 'closed';
|
|
276
|
+
groupId: TabGroupId;
|
|
277
|
+
};
|
|
278
|
+
type CloseAllStoppedReason = 'completed' | 'canceled';
|
|
279
|
+
/**
|
|
280
|
+
* Observer interface. All methods optional — implement what you need.
|
|
281
|
+
* Mirrors TabStripModelObserver.
|
|
282
|
+
*/
|
|
283
|
+
interface TabStripModelObserver<T> {
|
|
284
|
+
onTabStripModelChanged?(change: TabStripModelChange<T>, selection: TabStripSelectionChange<T>): void;
|
|
285
|
+
/** A tab's pinned state changed. Fired after any accompanying move. */
|
|
286
|
+
onTabPinnedStateChanged?(tab: Tab<T>, index: number): void;
|
|
287
|
+
/** A tab entered or left a group. */
|
|
288
|
+
onTabGroupedStateChanged?(oldGroup: TabGroupId | null, newGroup: TabGroupId | null, tab: Tab<T>, index: number): void;
|
|
289
|
+
/** Group lifecycle and visual changes. */
|
|
290
|
+
onTabGroupChanged?(change: TabGroupChange): void;
|
|
291
|
+
/** A tab's data payload or blocked state changed in place. */
|
|
292
|
+
onTabChanged?(tab: Tab<T>, index: number): void;
|
|
293
|
+
/**
|
|
294
|
+
* A tab was discarded (content dropped to save memory) or restored.
|
|
295
|
+
* Mirrors TabLifecycleObserver::OnDiscardedStateChange.
|
|
296
|
+
*/
|
|
297
|
+
onTabDiscardedStateChanged?(tab: Tab<T>, index: number, discarded: boolean): void;
|
|
298
|
+
/** A close was vetoed by canCloseTab. */
|
|
299
|
+
onTabCloseCancelled?(tab: Tab<T>): void;
|
|
300
|
+
/** CloseAllTabs is starting. */
|
|
301
|
+
willCloseAllTabs?(): void;
|
|
302
|
+
/** CloseAllTabs finished or was canceled by a veto. */
|
|
303
|
+
closeAllTabsStopped?(reason: CloseAllStoppedReason): void;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Port of chrome/browser/ui/tabs/tab_strip_model.{h,cc} (Chromium main
|
|
308
|
+
* @ 3dbd2135). Line references in comments point into chromium-reference/.
|
|
309
|
+
*
|
|
310
|
+
* Differences from Chrome are listed in PORTING_NOTES.md. The big ones:
|
|
311
|
+
* tabs carry generic `data: T` instead of WebContents, split tabs are not
|
|
312
|
+
* ported, and there is no async unload-handler dance — closes are
|
|
313
|
+
* synchronous, vetoable via `canCloseTab`.
|
|
314
|
+
*
|
|
315
|
+
* Like Chrome, the model maintains these invariants:
|
|
316
|
+
* - all pinned tabs occur before all non-pinned tabs
|
|
317
|
+
* - tabs of a group are contiguous, and never pinned
|
|
318
|
+
* - the active tab is always valid while the strip is non-empty
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
/** [start, end) index range, mirroring gfx::Range usage for group spans. */
|
|
322
|
+
interface IndexRange {
|
|
323
|
+
start: number;
|
|
324
|
+
end: number;
|
|
325
|
+
}
|
|
326
|
+
interface ActivateOptions {
|
|
327
|
+
/**
|
|
328
|
+
* Marks the activation as a direct user gesture. Mirrors
|
|
329
|
+
* TabStripUserGestureDetails; gates the opener-forgetting heuristic
|
|
330
|
+
* (tab_strip_model.cc:5301).
|
|
331
|
+
*/
|
|
332
|
+
userGesture?: boolean;
|
|
333
|
+
}
|
|
334
|
+
declare class TabStripModel<T = unknown> {
|
|
335
|
+
private tabs_;
|
|
336
|
+
private groups_;
|
|
337
|
+
private selectedTabs_;
|
|
338
|
+
private activeTab_;
|
|
339
|
+
private anchorTab_;
|
|
340
|
+
private observers_;
|
|
341
|
+
private closingAll_;
|
|
342
|
+
private reentrancyGuard_;
|
|
343
|
+
private readonly canCloseTab_;
|
|
344
|
+
private readonly supportsGroups_;
|
|
345
|
+
private readonly generateId_;
|
|
346
|
+
constructor(options?: TabStripModelOptions<T>);
|
|
347
|
+
get count(): number;
|
|
348
|
+
get empty(): boolean;
|
|
349
|
+
/** True while closeAllTabs is in progress. */
|
|
350
|
+
get closingAll(): boolean;
|
|
351
|
+
containsIndex(index: number): boolean;
|
|
352
|
+
getTabAt(index: number): Tab<T>;
|
|
353
|
+
indexOfTab(tab: Tab<T> | null): number;
|
|
354
|
+
getTabById(id: TabId): Tab<T> | null;
|
|
355
|
+
/** Snapshot of the tabs in strip order. */
|
|
356
|
+
getTabs(): ReadonlyArray<Tab<T>>;
|
|
357
|
+
get activeTab(): Tab<T> | null;
|
|
358
|
+
get activeIndex(): number;
|
|
359
|
+
/** Index of the first non-pinned tab; count if all pinned. (cc:1418 area) */
|
|
360
|
+
indexOfFirstNonPinnedTab(): number;
|
|
361
|
+
isTabPinned(index: number): boolean;
|
|
362
|
+
isTabBlocked(index: number): boolean;
|
|
363
|
+
isTabSelected(index: number): boolean;
|
|
364
|
+
/** Derived index-based view of the selection (Chrome: GetListSelectionModel). */
|
|
365
|
+
selectionModel(): ListSelectionModel;
|
|
366
|
+
get supportsTabGroups(): boolean;
|
|
367
|
+
getTabGroupForTab(index: number): TabGroupId | null;
|
|
368
|
+
getGroups(): TabGroup[];
|
|
369
|
+
getGroupVisualData(group: TabGroupId): TabGroupVisualData | null;
|
|
370
|
+
containsGroup(group: TabGroupId): boolean;
|
|
371
|
+
/** [start, end) range of the group's tabs. Mirrors TabGroup::ListTabs. */
|
|
372
|
+
listTabsInGroup(group: TabGroupId): IndexRange;
|
|
373
|
+
isGroupCollapsed(group: TabGroupId): boolean;
|
|
374
|
+
/** True if the tab is inside a collapsed group. (cc:1423) */
|
|
375
|
+
isTabCollapsed(index: number): boolean;
|
|
376
|
+
/**
|
|
377
|
+
* If a tab inserted at index would land inside a group, returns that group.
|
|
378
|
+
* Returns null at the first index of a group (a tab there sits between
|
|
379
|
+
* groups, not inside one). Mirrors GetSurroundingTabGroup.
|
|
380
|
+
*/
|
|
381
|
+
getSurroundingTabGroup(index: number): TabGroupId | null;
|
|
382
|
+
addObserver(observer: TabStripModelObserver<T>): () => void;
|
|
383
|
+
removeObserver(observer: TabStripModelObserver<T>): void;
|
|
384
|
+
/**
|
|
385
|
+
* Command-level add: picks the position from the open cause and opener
|
|
386
|
+
* relationships, then inserts. Port of AddTab (cc:1715-1828).
|
|
387
|
+
*/
|
|
388
|
+
addTab(data: T, options?: AddTabOptions): Tab<T>;
|
|
389
|
+
/** Adds a tab at the end of the strip. Port of AppendTab. */
|
|
390
|
+
appendTab(data: T, foreground?: boolean): Tab<T>;
|
|
391
|
+
/**
|
|
392
|
+
* Inserts at the given index, only adjusting it to keep pinned tabs at the
|
|
393
|
+
* front. Does NOT consult the order controller. Port of InsertWebContentsAt.
|
|
394
|
+
* Returns the index actually used.
|
|
395
|
+
*/
|
|
396
|
+
insertTabAt(index: number, data: T, options?: Omit<AddTabOptions, 'index' | 'cause'>): Tab<T>;
|
|
397
|
+
/** Makes the tab at index active. Port of ActivateTabAt (cc:1022). */
|
|
398
|
+
activateTabAt(index: number, options?: ActivateOptions): void;
|
|
399
|
+
/** Extends the selection from the anchor to index. Port of cc:1514. */
|
|
400
|
+
extendSelectionTo(index: number): void;
|
|
401
|
+
/** Adds the tab at index to the selection and makes it active+anchor. (cc:1545) */
|
|
402
|
+
selectTabAt(index: number): void;
|
|
403
|
+
/** Removes the tab at index from the selection. No-op if it's the last one. (cc:1570) */
|
|
404
|
+
deselectTabAt(index: number): void;
|
|
405
|
+
/** Selects anchor..index, adding to the current selection. (cc:1616) */
|
|
406
|
+
addSelectionFromAnchorTo(index: number): void;
|
|
407
|
+
/** Replaces the selection with the given index-based model. */
|
|
408
|
+
setSelectionFromModel(source: ListSelectionModel): void;
|
|
409
|
+
/**
|
|
410
|
+
* Activates the next/previous tab, wrapping around and skipping collapsed
|
|
411
|
+
* groups. Port of SelectRelativeTab (cc:3951).
|
|
412
|
+
*/
|
|
413
|
+
selectNextTab(options?: ActivateOptions): void;
|
|
414
|
+
selectPreviousTab(options?: ActivateOptions): void;
|
|
415
|
+
selectLastTab(options?: ActivateOptions): void;
|
|
416
|
+
private selectRelativeTab_;
|
|
417
|
+
/**
|
|
418
|
+
* Moves the tab at index to toPosition (clamped so pinned tabs stay
|
|
419
|
+
* together). Group membership adjusts to keep groups contiguous. Port of
|
|
420
|
+
* MoveWebContentsAt (cc:1053). Returns the final index.
|
|
421
|
+
*/
|
|
422
|
+
moveTabTo(index: number, toPosition: number, selectAfterMove?: boolean): number;
|
|
423
|
+
/**
|
|
424
|
+
* Moves the selected tabs to index, pinned tabs first as a chunk, then
|
|
425
|
+
* unpinned. `index` is interpreted as if the strip did not contain the
|
|
426
|
+
* selected tabs. Port of MoveSelectedTabsTo (cc:1089).
|
|
427
|
+
*/
|
|
428
|
+
moveSelectedTabsTo(index: number, group?: TabGroupId | null): void;
|
|
429
|
+
/** Moves all tabs of a group to toIndex. Port of MoveGroupTo (cc:1117). */
|
|
430
|
+
moveGroupTo(group: TabGroupId, toIndex: number): void;
|
|
431
|
+
/**
|
|
432
|
+
* Moves the active tab one slot right/left. At a group boundary the tab
|
|
433
|
+
* first changes group membership without moving; collapsed neighbor groups
|
|
434
|
+
* are hopped over entirely. Port of MoveTabRelative (cc:3976).
|
|
435
|
+
*/
|
|
436
|
+
moveTabNext(): void;
|
|
437
|
+
moveTabPrevious(): void;
|
|
438
|
+
private moveTabRelative_;
|
|
439
|
+
/**
|
|
440
|
+
* Pins or unpins the tab, moving it to the pinned/unpinned boundary.
|
|
441
|
+
* Pinning removes the tab from its group. Returns the final index.
|
|
442
|
+
* Port of SetTabPinned (cc:1407) + SetTabPinnedImpl (cc:5052).
|
|
443
|
+
*/
|
|
444
|
+
setTabPinned(index: number, pinned: boolean): number;
|
|
445
|
+
/** Closes the tab at index. Returns true if it closed (not vetoed). */
|
|
446
|
+
closeTabAt(index: number): boolean;
|
|
447
|
+
/** Closes the tabs at the given indices. */
|
|
448
|
+
closeTabsAt(indices: number[]): boolean;
|
|
449
|
+
/** Port of CloseSelectedTabs. */
|
|
450
|
+
closeSelectedTabs(): boolean;
|
|
451
|
+
/** Port of CloseAllTabs (cc:455). */
|
|
452
|
+
closeAllTabs(): boolean;
|
|
453
|
+
/** Context-menu style helper: close every tab except the one at index. */
|
|
454
|
+
closeOtherTabs(index: number): boolean;
|
|
455
|
+
/** Context-menu style helper: close unpinned tabs to the right of index. */
|
|
456
|
+
closeTabsToRight(index: number): boolean;
|
|
457
|
+
/** Closes all tabs in a group. Port of CloseAllTabsInGroup. */
|
|
458
|
+
closeAllTabsInGroup(group: TabGroupId): boolean;
|
|
459
|
+
private closeTabs_;
|
|
460
|
+
/**
|
|
461
|
+
* Removes the tab and fixes up the selection. Port of
|
|
462
|
+
* RemoveTabFromIndexImpl (cc:4551). Caller batches notifications.
|
|
463
|
+
*/
|
|
464
|
+
private removeTabFromIndexImpl_;
|
|
465
|
+
/**
|
|
466
|
+
* Converges the strip to an external source-of-truth list with minimal
|
|
467
|
+
* mutations (no remove-all/re-add), so an app whose canonical tab state
|
|
468
|
+
* lives elsewhere (a router, a store, another window) can mirror it into
|
|
469
|
+
* the model without losing tab identity, content state, or discard status.
|
|
470
|
+
*
|
|
471
|
+
* - tabs absent from `desired` are removed, bypassing `canCloseTab` (the
|
|
472
|
+
* external state has already decided)
|
|
473
|
+
* - missing tabs are inserted at their position under the given id
|
|
474
|
+
* - `data` is swapped via setTabData where `dataEquals` reports a change
|
|
475
|
+
* - pinned state and order converge to the desired list; pass a
|
|
476
|
+
* pinned-first-consistent list or Chrome's clamping rules win
|
|
477
|
+
* - `activeId`, when provided and present, is activated last
|
|
478
|
+
*
|
|
479
|
+
* Observers fire for each underlying mutation as usual; reconcile-driven
|
|
480
|
+
* activations carry reason 'none', so a consumer that also writes model
|
|
481
|
+
* changes back to the external store can tell them from user gestures.
|
|
482
|
+
* Groups are not reconciled. No Chrome equivalent: this is integration
|
|
483
|
+
* surface for embedding apps.
|
|
484
|
+
*/
|
|
485
|
+
reconcile(desired: ReadonlyArray<ReconcileTab<T>>, options?: ReconcileOptions<T>): void;
|
|
486
|
+
getOpenerOfTabAt(index: number): Tab<T> | null;
|
|
487
|
+
setOpenerOfTabAt(index: number, opener: Tab<T> | null): void;
|
|
488
|
+
/** Port of ForgetAllOpeners (cc:3376). */
|
|
489
|
+
forgetAllOpeners(): void;
|
|
490
|
+
forgetOpener(tab: Tab<T>): void;
|
|
491
|
+
/**
|
|
492
|
+
* Call when the user navigates a tab. Typed-style navigations reset all
|
|
493
|
+
* opener relationships (the user started a new task), except in a fresh
|
|
494
|
+
* end-of-strip tab. Port of TabNavigating (cc:1378).
|
|
495
|
+
*/
|
|
496
|
+
tabNavigating(tab: Tab<T>, cause: TabOpenCause): void;
|
|
497
|
+
/**
|
|
498
|
+
* Index of the last tab opened (transitively) by the tab at startIndex,
|
|
499
|
+
* scanning right, skipping pinned tabs, stopping at the first unrelated
|
|
500
|
+
* unpinned tab. Port of GetIndexOfLastWebContentsOpenedBy (cc:1351).
|
|
501
|
+
*/
|
|
502
|
+
getIndexOfLastTabOpenedBy(opener: Tab<T>, startIndex: number): number;
|
|
503
|
+
/**
|
|
504
|
+
* Creates a group containing the tabs at indices (ascending). Tabs are
|
|
505
|
+
* unpinned and made contiguous without splitting other groups. Returns the
|
|
506
|
+
* group id. Port of AddToNewGroup (cc:671) + AddToNewGroupImpl (cc:4344).
|
|
507
|
+
*/
|
|
508
|
+
addToNewGroup(indices: number[], visualData?: Partial<TabGroupVisualData>): TabGroupId;
|
|
509
|
+
/**
|
|
510
|
+
* Adds the tabs at indices (ascending) to an existing group. Tabs left of
|
|
511
|
+
* the group move to its start, tabs right of it to its end; addToEnd sends
|
|
512
|
+
* everything to the end. Port of AddToExistingGroup (cc:4415).
|
|
513
|
+
*/
|
|
514
|
+
addToExistingGroup(indices: number[], group: TabGroupId, addToEnd?: boolean): void;
|
|
515
|
+
/**
|
|
516
|
+
* Removes the tabs at indices (ascending) from their groups. Tabs in the
|
|
517
|
+
* first half of a group exit left of it, the rest exit right. Port of
|
|
518
|
+
* RemoveFromGroup (cc:4253 area) + SeparateTabsByVisualPosition.
|
|
519
|
+
*/
|
|
520
|
+
removeFromGroup(indices: number[]): void;
|
|
521
|
+
/** Updates a group's title/color/collapsed state. Port of ChangeTabGroupVisuals. */
|
|
522
|
+
updateGroupVisuals(group: TabGroupId, visuals: Partial<TabGroupVisualData>): void;
|
|
523
|
+
setGroupCollapsed(group: TabGroupId, collapsed: boolean): void;
|
|
524
|
+
/** Chrome's TabGroupModel::GetNextColor: least-used color, in palette order. */
|
|
525
|
+
private nextGroupColor_;
|
|
526
|
+
/** Swaps the tab's data payload. Emits a 'replaced' change (Chrome: Replace). */
|
|
527
|
+
setTabData(index: number, data: T): void;
|
|
528
|
+
/** Notify observers the tab changed in place (after mutating tab.data). */
|
|
529
|
+
notifyTabChanged(index: number): void;
|
|
530
|
+
/** Port of SetTabBlocked (cc:1397). */
|
|
531
|
+
setTabBlocked(index: number, blocked: boolean): void;
|
|
532
|
+
/**
|
|
533
|
+
* Drops the tab's content to save memory while keeping the tab in the
|
|
534
|
+
* strip. The active tab cannot be discarded (it's visible). Content
|
|
535
|
+
* remounts fresh on the next activation, like Chrome's reload-on-focus.
|
|
536
|
+
* Port of TabLifecycleUnit::Discard (tab_lifecycle_unit.cc:346) +
|
|
537
|
+
* TabStripModel::DiscardWebContentsAt semantics. Returns true on success.
|
|
538
|
+
*/
|
|
539
|
+
discardTabAt(index: number): boolean;
|
|
540
|
+
/**
|
|
541
|
+
* Restores a discarded tab without activating it (Chrome: reloading a
|
|
542
|
+
* background discarded tab, DidStartLoading path).
|
|
543
|
+
*/
|
|
544
|
+
restoreTabAt(index: number): boolean;
|
|
545
|
+
/** Per-tab opt-out from automatic discarding (extensions setAutoDiscardable). */
|
|
546
|
+
setTabAutoDiscardable(index: number, autoDiscardable: boolean): void;
|
|
547
|
+
isTabDiscarded(index: number): boolean;
|
|
548
|
+
/** Number of tabs whose content is currently live (not discarded). */
|
|
549
|
+
get loadedTabCount(): number;
|
|
550
|
+
private restoreTab_;
|
|
551
|
+
/**
|
|
552
|
+
* Where to place a newly opened tab. Port of DetermineInsertionIndex
|
|
553
|
+
* (cc:5329).
|
|
554
|
+
*/
|
|
555
|
+
determineInsertionIndex(cause: TabOpenCause, foreground: boolean): number;
|
|
556
|
+
/**
|
|
557
|
+
* Which tab should become active after the tab at `index` closes.
|
|
558
|
+
* Port of DetermineNewSelectedIndex (cc:5377), single-tab block, with the
|
|
559
|
+
* "parent collection" preference specialized to groups. Returns the index
|
|
560
|
+
* in post-close coordinates, or null if this is the last tab.
|
|
561
|
+
*/
|
|
562
|
+
private determineNewSelectedIndex_;
|
|
563
|
+
/** Port of GetIndexOfNextWebContentsOpenedBy (cc:3286). */
|
|
564
|
+
private getIndexOfNextTabOpenedBy_;
|
|
565
|
+
/** Port of GetIndexOfNextWebContentsOpenedByOpenerOf (cc:3312). */
|
|
566
|
+
private getIndexOfNextTabOpenedByOpenerOf_;
|
|
567
|
+
/** Port of GetNextExpandedActiveTab (cc:3346): right of block, then left. */
|
|
568
|
+
private getNextExpandedActiveTab_;
|
|
569
|
+
private createTab_;
|
|
570
|
+
/** Port of ConstrainInsertionIndex (cc:3408). */
|
|
571
|
+
private constrainInsertionIndex_;
|
|
572
|
+
/** Port of ConstrainMoveIndex (cc:3413). */
|
|
573
|
+
private constrainMoveIndex_;
|
|
574
|
+
/** Port of InsertTabAtImpl (cc:3575). Returns the index actually used. */
|
|
575
|
+
private insertTabAtImpl_;
|
|
576
|
+
/**
|
|
577
|
+
* Single-tab move with explicit final group/pin state. Port of
|
|
578
|
+
* MoveTabToIndexImpl (cc:4617).
|
|
579
|
+
*/
|
|
580
|
+
private moveTabToIndexImpl_;
|
|
581
|
+
/**
|
|
582
|
+
* Block move: removes the tabs at `indices`, reinserts them contiguously at
|
|
583
|
+
* `destination` (post-removal coordinates), assigning the given group and
|
|
584
|
+
* the pinned state of the first moving tab. Port of MoveTabsToIndexImpl
|
|
585
|
+
* (cc:4698) + MoveTabsWithNotifications (cc:5081).
|
|
586
|
+
*/
|
|
587
|
+
private moveTabsToIndexImpl_;
|
|
588
|
+
/**
|
|
589
|
+
* Port of MoveTabsAndSetPropertiesImpl (cc:4469): destination is given in
|
|
590
|
+
* pre-removal coordinates and adjusted here.
|
|
591
|
+
*/
|
|
592
|
+
private moveTabsAndSetProperties_;
|
|
593
|
+
/**
|
|
594
|
+
* Group to assign when a tab moves from index to toPosition so groups stay
|
|
595
|
+
* contiguous. Port of GetGroupToAssign (cc:5195).
|
|
596
|
+
*/
|
|
597
|
+
private getGroupToAssign_;
|
|
598
|
+
/**
|
|
599
|
+
* Re-points the openers of any tab that referenced the tab at index at that
|
|
600
|
+
* tab's own opener. Port of FixOpeners (cc:5171).
|
|
601
|
+
*/
|
|
602
|
+
private fixOpeners_;
|
|
603
|
+
/** Selection helpers (Chrome: TabStripModelSelectionState). */
|
|
604
|
+
private setSelectedTab_;
|
|
605
|
+
private firstSelectedTab_;
|
|
606
|
+
private selectedIndices_;
|
|
607
|
+
/**
|
|
608
|
+
* Wraps a selection mutation in change tracking + notification. Mirrors
|
|
609
|
+
* SetSelection (cc:1178).
|
|
610
|
+
*/
|
|
611
|
+
private setSelection_;
|
|
612
|
+
private buildSelectionChange_;
|
|
613
|
+
/**
|
|
614
|
+
* Opener and lifecycle bookkeeping when the active tab changes. Port of
|
|
615
|
+
* OnActiveTabChanged (cc:5255) plus TabLifecycleUnit::SetFocused
|
|
616
|
+
* (tab_lifecycle_unit.cc:135).
|
|
617
|
+
*/
|
|
618
|
+
private handleActiveTabChanged_;
|
|
619
|
+
private emitGroupStateChange_;
|
|
620
|
+
private notifyAll_;
|
|
621
|
+
private requireGroups_;
|
|
622
|
+
private checkReentrancy_;
|
|
623
|
+
/**
|
|
624
|
+
* Invariant validation. Port of CompleteModelUpdateTransaction; Chrome
|
|
625
|
+
* CHECKs, we throw.
|
|
626
|
+
*/
|
|
627
|
+
private validate_;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Automatic tab discarding. Port of Chrome's tab lifecycle stack:
|
|
632
|
+
*
|
|
633
|
+
* - chrome/browser/resource_coordinator/tab_manager.cc (orchestration)
|
|
634
|
+
* - chrome/browser/performance_manager/policies/discard_eligibility_policy.h
|
|
635
|
+
* (CanDiscardResult tri-state, CannotDiscardReason, the importance sort in
|
|
636
|
+
* PageNodeSortProxy::operator<, kNonVisiblePagesUrgentProtectionTime)
|
|
637
|
+
* - chrome/browser/resource_coordinator/tab_lifecycle_unit.cc (discard
|
|
638
|
+
* mechanics live on the model as discardTabAt/restore-on-focus)
|
|
639
|
+
*
|
|
640
|
+
* Chrome triggers discards on OS memory pressure, which the web platform
|
|
641
|
+
* does not expose reliably. The deterministic equivalent is a budget on the
|
|
642
|
+
* number of loaded (mounted) tabs: when `maxLoadedTabs` is exceeded, the
|
|
643
|
+
* least important tabs are discarded, in exactly Chrome's importance order.
|
|
644
|
+
*/
|
|
645
|
+
|
|
646
|
+
/** Mirrors LifecycleUnitDiscardReason (minus Chrome-internal variants). */
|
|
647
|
+
type DiscardReason = 'proactive' | 'urgent' | 'external';
|
|
648
|
+
/** Trimmed CannotDiscardReason (cannot_discard_reason.h). */
|
|
649
|
+
type CannotDiscardReason = 'activeTab' | 'alreadyDiscarded' | 'optedOut' | 'appVeto' | 'pinnedTab' | 'recentlyActive';
|
|
650
|
+
/** Mirrors CanDiscardResult (discard_eligibility_policy.h:56). */
|
|
651
|
+
type CanDiscardResult = 'eligible' | 'protected' | 'disallowed';
|
|
652
|
+
interface CanDiscardDecision {
|
|
653
|
+
result: CanDiscardResult;
|
|
654
|
+
reasons: CannotDiscardReason[];
|
|
655
|
+
}
|
|
656
|
+
interface TabLifecycleOptions<T> {
|
|
657
|
+
/**
|
|
658
|
+
* Maximum number of tabs whose content stays loaded at once. Exceeding it
|
|
659
|
+
* triggers automatic discarding of the least important tabs. Pass null to
|
|
660
|
+
* disable automatic discarding (manual discardLeastImportant still works).
|
|
661
|
+
* Chrome's equivalent trigger is OS memory pressure.
|
|
662
|
+
*/
|
|
663
|
+
maxLoadedTabs?: number | null;
|
|
664
|
+
/**
|
|
665
|
+
* Tabs active within this window are protected (not disallowed) from
|
|
666
|
+
* discarding. Mirrors kNonVisiblePagesUrgentProtectionTime, 10 minutes on
|
|
667
|
+
* desktop (discard_eligibility_policy.h:38).
|
|
668
|
+
*/
|
|
669
|
+
recentlyActiveProtectionMs?: number;
|
|
670
|
+
/**
|
|
671
|
+
* Protect pinned tabs (CannotDiscardReason::kPinnedTab). Protected tabs
|
|
672
|
+
* are only discarded when eligible tabs alone can't satisfy the budget.
|
|
673
|
+
*/
|
|
674
|
+
protectPinnedTabs?: boolean;
|
|
675
|
+
/**
|
|
676
|
+
* App-level veto, the equivalent of the protections Chrome detects in the
|
|
677
|
+
* renderer (playing audio, form input, user edits, capturing, PiP...).
|
|
678
|
+
* Return false to disallow discarding a tab.
|
|
679
|
+
*/
|
|
680
|
+
canDiscardTab?: (tab: Tab<T>) => boolean;
|
|
681
|
+
/**
|
|
682
|
+
* Called just before a tab's content is dropped, the equivalent of
|
|
683
|
+
* WebContents::AboutToBeDiscarded. Last chance to snapshot restorable
|
|
684
|
+
* state (scroll position, draft text) into tab.data.
|
|
685
|
+
*/
|
|
686
|
+
onBeforeDiscard?: (tab: Tab<T>) => void;
|
|
687
|
+
/**
|
|
688
|
+
* Apps whose tab content shares global state per content type (a
|
|
689
|
+
* singleton store per route/scene) can return a key here: at most one
|
|
690
|
+
* non-discarded tab per distinct key stays loaded. Whenever two loaded
|
|
691
|
+
* tabs share a key, every one except the active (else the most recently
|
|
692
|
+
* active) is discarded immediately, and reload-on-focus re-derives each
|
|
693
|
+
* tab's state from its own `data` when it is next activated — shared
|
|
694
|
+
* state can then never bleed between two visible-at-once duplicates.
|
|
695
|
+
* Return null to exempt a tab (e.g. content that isolates correctly).
|
|
696
|
+
*
|
|
697
|
+
* This is a correctness policy, not a memory policy: it overrides the
|
|
698
|
+
* pinned/recently-active protections and the `canDiscardTab` veto (the
|
|
699
|
+
* active tab still always keeps its content). No Chrome equivalent —
|
|
700
|
+
* Chrome tabs never share renderer state.
|
|
701
|
+
*/
|
|
702
|
+
exclusiveContentKey?: (tab: Tab<T>) => string | null;
|
|
703
|
+
}
|
|
704
|
+
declare class TabLifecycleManager<T = unknown> {
|
|
705
|
+
private readonly model_;
|
|
706
|
+
private readonly maxLoadedTabs_;
|
|
707
|
+
private readonly recentlyActiveProtectionMs_;
|
|
708
|
+
private readonly protectPinnedTabs_;
|
|
709
|
+
private readonly canDiscardTab_;
|
|
710
|
+
private readonly onBeforeDiscard_;
|
|
711
|
+
private readonly exclusiveContentKey_;
|
|
712
|
+
private detach_;
|
|
713
|
+
private enforcePending_;
|
|
714
|
+
constructor(model: TabStripModel<T>, options?: TabLifecycleOptions<T>);
|
|
715
|
+
/**
|
|
716
|
+
* Starts observing the model and enforcing the loaded-tab budget. Returns
|
|
717
|
+
* a stop function. Discards run on a microtask after model changes, never
|
|
718
|
+
* re-entrantly (Chrome posts discard tasks for the same reason).
|
|
719
|
+
*/
|
|
720
|
+
start(): () => void;
|
|
721
|
+
stop(): void;
|
|
722
|
+
/**
|
|
723
|
+
* Tri-state discard eligibility for one tab. Port of
|
|
724
|
+
* DiscardEligibilityPolicy::CanDiscard.
|
|
725
|
+
*/
|
|
726
|
+
canDiscard(tab: Tab<T>): CanDiscardDecision;
|
|
727
|
+
/**
|
|
728
|
+
* Discard candidates in Chrome's importance order, least important first:
|
|
729
|
+
* eligible before protected, each group least-recently-active first,
|
|
730
|
+
* disallowed never. Port of PageNodeSortProxy::operator<
|
|
731
|
+
* (discard_eligibility_policy.h:95) with focused/visible folded into
|
|
732
|
+
* 'activeTab' (a single-window strip has one visible tab).
|
|
733
|
+
*/
|
|
734
|
+
getDiscardCandidates(includeProtected: boolean): Array<Tab<T>>;
|
|
735
|
+
/**
|
|
736
|
+
* Discards the least important discardable tab. 'urgent' may take
|
|
737
|
+
* protected tabs (Chrome: urgent discarding under memory pressure);
|
|
738
|
+
* 'proactive' and 'external' only take eligible ones. Port of
|
|
739
|
+
* PageDiscardingHelper::DiscardAPage. Returns the discarded tab or null.
|
|
740
|
+
*/
|
|
741
|
+
discardLeastImportant(reason?: DiscardReason): Tab<T> | null;
|
|
742
|
+
/**
|
|
743
|
+
* Discards tabs until the loaded count fits the budget. Eligible tabs go
|
|
744
|
+
* first; protected tabs are taken only if the budget still isn't met
|
|
745
|
+
* (matching the sort order Chrome walks when reclaiming memory).
|
|
746
|
+
* Disallowed tabs are never discarded, so the budget can be exceeded when
|
|
747
|
+
* everything left is active/opted-out/vetoed.
|
|
748
|
+
*/
|
|
749
|
+
enforceBudget(): number;
|
|
750
|
+
/**
|
|
751
|
+
* Enforces `exclusiveContentKey`: for every key shared by more than one
|
|
752
|
+
* loaded tab, keep the active tab (else the most recently active) and
|
|
753
|
+
* discard the rest. Returns the number of tabs discarded. Runs before the
|
|
754
|
+
* budget pass, so duplicates count toward freed budget first.
|
|
755
|
+
*/
|
|
756
|
+
enforceExclusiveContent(): number;
|
|
757
|
+
private discardTab_;
|
|
758
|
+
private scheduleEnforce_;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
export { AddTabFlags, type AddTabOptions, type CanDiscardDecision, type CanDiscardResult, type CannotDiscardReason, type CloseAllStoppedReason, CloseTabFlags, type DiscardReason, type IndexRange, ListSelectionModel, NO_TAB, type ReconcileOptions, type ReconcileTab, TAB_GROUP_COLORS, type Tab, type TabGroup, type TabGroupChange, type TabGroupColor, type TabGroupId, type TabGroupVisualData, type TabId, TabLifecycleManager, type TabLifecycleOptions, type TabOpenCause, TabStripModel, type TabStripModelChange, type TabStripModelObserver, type TabStripModelOptions, type TabStripSelectionChange };
|