kireji 0.5.0 → 0.6.6

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.
Files changed (154) hide show
  1. package/package.json +1 -1
  2. package/src/app/kireji/attributes_.js +3 -0
  3. package/src/app/kireji/editor/part.json +13 -11
  4. package/src/app/kireji/editor/point.js +2 -1
  5. package/src/app/kireji/editor/sections/properties/part.html_.js +5 -5
  6. package/src/app/kireji/editor/sections/section/part.json +6 -4
  7. package/src/app/kireji/editor/sections/section/view-update.js +8 -0
  8. package/src/app/kireji/editor/sections/state-space/part.html_.js +4 -4
  9. package/src/app/kireji/editor/tab-group/build.js +2 -30
  10. package/src/app/kireji/editor/tab-group/listeners-attach.js +2 -1
  11. package/src/app/kireji/editor/tab-group/listeners-detach.js +2 -1
  12. package/src/app/kireji/editor/tab-group/part.css +1 -1
  13. package/src/app/kireji/editor/tab-group/part.json +26 -24
  14. package/src/app/kireji/editor/tab-group/routeID-distribute.js +1 -1
  15. package/src/app/kireji/editor/tab-group/routeID-get-permutation.js +1 -1
  16. package/src/app/kireji/editor/tab-group/type.d.ts +0 -9
  17. package/src/app/kireji/editor/tab-group/{view-add.js → view-hydrate.js} +5 -7
  18. package/src/app/kireji/editor/tab-group/view-update.js +115 -0
  19. package/src/app/kireji/sidebar/open/view-update.js +10 -0
  20. package/src/app/kireji/sidebar/part.json +3 -1
  21. package/src/app/kireji/sidebar/width/part.json +6 -4
  22. package/src/app/kireji/tool-bar/button/view-add.js +5 -7
  23. package/src/app/kireji/tool-bar/part.css +1 -1
  24. package/src/app/kireji/tool-bar/part.json +7 -5
  25. package/src/application-goto.js +1 -1
  26. package/src/build.js +102 -21
  27. package/src/images-inject.js +34 -0
  28. package/src/part.html_.js +39 -60
  29. package/src/part.json +21 -20
  30. package/src/parts/abstract/application/attributes_.js +3 -0
  31. package/src/parts/abstract/application/classes_.js +1 -0
  32. package/src/parts/abstract/application/type.d.ts +2 -2
  33. package/src/parts/abstract/body-mode/view-add.js +0 -1
  34. package/src/parts/abstract/boolean/part.json +5 -3
  35. package/src/parts/abstract/clip/build.js +0 -1
  36. package/src/parts/abstract/clip/loop.js +12 -0
  37. package/src/parts/abstract/clip/part.json +6 -4
  38. package/src/parts/abstract/clip/playback-stop.js +0 -5
  39. package/src/parts/abstract/error/part.json +13 -11
  40. package/src/parts/abstract/error/type.d.ts +1 -1
  41. package/src/parts/abstract/facet/part.json +10 -8
  42. package/src/parts/abstract/match/build.js +15 -13
  43. package/src/parts/abstract/match/equation.html_.js +1 -1
  44. package/src/parts/abstract/match/part.json +6 -4
  45. package/src/parts/abstract/match/routeID-collect.js +2 -11
  46. package/src/parts/abstract/mix/build.js +12 -10
  47. package/src/parts/abstract/mix/model_.js +1 -1
  48. package/src/parts/abstract/mix/part.json +6 -4
  49. package/src/parts/abstract/part/build.js +7 -1
  50. package/src/parts/abstract/part/constants.js +2 -5
  51. package/src/parts/abstract/part/manifest-resolve-owner-of.js +6 -0
  52. package/src/parts/abstract/part/manifest-resolve-part-from.js +10 -0
  53. package/src/parts/abstract/part/part.json +76 -68
  54. package/src/parts/abstract/part/routeID-set.js +20 -7
  55. package/src/parts/abstract/part/type.d.ts +44 -19
  56. package/src/parts/abstract/part/view-collect-update.js +13 -0
  57. package/src/parts/abstract/part/view-distribute-hydrate.js +10 -0
  58. package/src/parts/abstract/part/view-distribute-update.js +14 -0
  59. package/src/parts/abstract/part/view-update.js +0 -0
  60. package/src/parts/abstract/part-mask/part.json +3 -1
  61. package/src/parts/abstract/part-outliner/folders/view-update.js +18 -0
  62. package/src/parts/abstract/part-outliner/part.json +29 -27
  63. package/src/parts/abstract/part-outliner/point-toggle.js +0 -20
  64. package/src/parts/abstract/permutation/build.js +1 -30
  65. package/src/parts/abstract/permutation/part.json +45 -43
  66. package/src/parts/abstract/permutation/routeID-distribute.js +1 -4
  67. package/src/parts/abstract/permutation/routeID-get-permutation.js +1 -1
  68. package/src/parts/abstract/permutation/type.d.ts +0 -6
  69. package/src/parts/abstract/permutation/view-hydrate.js +3 -0
  70. package/src/parts/abstract/permutation/view-update.js +32 -0
  71. package/src/parts/abstract/scroller/build.js +4 -0
  72. package/src/parts/abstract/scroller/constants.js +0 -1
  73. package/src/parts/abstract/scroller/part.json +16 -14
  74. package/src/parts/abstract/scroller/view-add.js +1 -20
  75. package/src/parts/abstract/scroller/view-hydrate.js +19 -0
  76. package/src/parts/abstract/scroller/view-remove.js +4 -2
  77. package/src/parts/abstract/scroller/view-update.js +7 -0
  78. package/src/parts/core/address-bar/part.json +6 -4
  79. package/src/parts/core/client/async-install.js +53 -6
  80. package/src/parts/core/client/build.js +1 -15
  81. package/src/parts/core/client/description +1 -1
  82. package/src/parts/core/client/part.json +1 -4
  83. package/src/parts/core/hot-keys/combo_.js +7 -7
  84. package/src/parts/core/hot-keys/part.json +4 -2
  85. package/src/parts/core/pointer/constants.js +1 -0
  86. package/src/parts/core/pointer/handle.js +7 -1
  87. package/src/parts/core/pointer/part.json +5 -3
  88. package/src/parts/core/server/sync-install.js +4 -8
  89. package/src/parts/core/update/part.json +9 -7
  90. package/src/parts/core/worker/part.html_.js +1 -1
  91. package/src/parts/core/worker/part.json +6 -4
  92. package/src/parts/core/worker/sync-install.js +0 -1
  93. package/src/parts/desktop/attributes_.js +3 -1
  94. package/src/parts/desktop/color/part.json +19 -17
  95. package/src/parts/desktop/color/type.d.ts +3 -3
  96. package/src/parts/desktop/era/part.json +6 -4
  97. package/src/parts/desktop/era/type.d.ts +3 -3
  98. package/src/parts/desktop/era/vintage/static.css +25 -6
  99. package/src/parts/desktop/icons/part.json +6 -4
  100. package/src/parts/desktop/icons/view-update.js +13 -0
  101. package/src/parts/desktop/task-bar/menu/classes_.js +9 -0
  102. package/src/parts/desktop/task-bar/menu/clip/type.d.ts +1 -1
  103. package/src/parts/desktop/task-bar/menu/clip/view-update.js +1 -0
  104. package/src/parts/desktop/task-bar/menu/closed/view-add.js +1 -1
  105. package/src/parts/desktop/task-bar/menu/closed/view-remove.js +1 -1
  106. package/src/parts/desktop/task-bar/menu/introduce/view-add.js +1 -2
  107. package/src/parts/desktop/task-bar/menu/introduce/view-hydrate.js +1 -0
  108. package/src/parts/desktop/task-bar/menu/menu.html_.js +1 -1
  109. package/src/parts/desktop/task-bar/menu/opened/view-add.js +1 -4
  110. package/src/parts/desktop/task-bar/menu/opened/view-remove.js +1 -3
  111. package/src/parts/desktop/task-bar/menu/part.json +6 -4
  112. package/src/parts/desktop/task-bar/menu/type.d.ts +2 -0
  113. package/src/parts/desktop/task-bar/tray/item/part.json +6 -4
  114. package/src/parts/desktop/task-bar/view-hydrate.js +21 -0
  115. package/src/parts/desktop/windows/HTML-render-task.js +1 -1
  116. package/src/parts/desktop/windows/part.json +23 -21
  117. package/src/parts/desktop/windows/point.js +4 -3
  118. package/src/parts/desktop/windows/{view-add.js → view-hydrate.js} +1 -1
  119. package/src/route-set.js +5 -5
  120. package/src/type.d.ts +22 -24
  121. package/src/validate.js +0 -4
  122. package/src/view-hydrate.js +12 -0
  123. package/src/app/kireji/editor/sections/section/view-populate.js +0 -10
  124. package/src/app/kireji/editor/tab-group/view-populate.js +0 -116
  125. package/src/app/kireji/sidebar/open/view-populate.js +0 -12
  126. package/src/app/kireji/style_.js +0 -1
  127. package/src/early-get-images.js +0 -25
  128. package/src/parts/abstract/clip/view-add.js +0 -1
  129. package/src/parts/abstract/clip/view-populate.js +0 -20
  130. package/src/parts/abstract/part/view-collect-populate.js +0 -13
  131. package/src/parts/abstract/part/view-distribute-populate.js +0 -14
  132. package/src/parts/abstract/part-outliner/folders/view-populate.js +0 -20
  133. package/src/parts/abstract/permutation/view-add.js +0 -4
  134. package/src/parts/abstract/permutation/view-populate.js +0 -36
  135. package/src/parts/abstract/scroller/view-populate.js +0 -17
  136. package/src/parts/desktop/icons/view-populate.js +0 -15
  137. package/src/parts/desktop/task-bar/menu/clip/view-populate.js +0 -2
  138. package/src/parts/desktop/task-bar/menu/introduce/view-remove.js +0 -2
  139. package/src/parts/desktop/task-bar/view-add.js +0 -20
  140. package/src/parts/desktop/windows/view-populate.js +0 -1
  141. package/src/view-add.js +0 -22
  142. /package/src/app/kireji/sidebar/{view-add.js → view-hydrate.js} +0 -0
  143. /package/src/app/kireji/sidebar/width/{view-populate.js → view-update.js} +0 -0
  144. /package/src/parts/abstract/application/{view-add.js → view-hydrate.js} +0 -0
  145. /package/src/parts/abstract/part/{view-populate.js → view-hydrate.js} +0 -0
  146. /package/src/parts/desktop/color/{view-populate.js → view-update.js} +0 -0
  147. /package/src/parts/desktop/era/{view-populate.js → view-update.js} +0 -0
  148. /package/src/parts/desktop/task-bar/menu/closed/{attr-style → style} +0 -0
  149. /package/src/parts/desktop/task-bar/menu/introduce/{attr-style_.js → style_.js} +0 -0
  150. /package/src/parts/desktop/task-bar/menu/opened/{attr-style → style} +0 -0
  151. /package/src/parts/desktop/task-bar/menu/{view-add.js → view-hydrate.js} +0 -0
  152. /package/src/parts/desktop/task-bar/tray/clock/{view-add.js → view-hydrate.js} +0 -0
  153. /package/src/parts/desktop/task-bar/tray/item/{view-add.js → view-hydrate.js} +0 -0
  154. /package/src/{view-populate.js → view-update.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kireji",
3
- "version": "0.5.0",
3
+ "version": "0.6.6",
4
4
  "description": "A web framework for stateful, entropy-perfect, multi-origin web applications. Currently in alpha. Expect breaking changes for version 0. Use with caution!",
5
5
  "files": [
6
6
  "src/",
@@ -0,0 +1,3 @@
1
+ return [
2
+ `style="${sidebar.width.style}"`
3
+ ]
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "extends": "mix",
3
- "point": [
4
- "POINTER_EVENT",
5
- "TARGET_ELEMENT",
6
- "PART_INDEX",
7
- "FILE_INDEX",
8
- "TAB_PAYLOAD = 0n"
9
- ],
10
- "point-close": [
11
- "POINTER_EVENT",
12
- "TARGET_ELEMENT"
13
- ]
3
+ "methods": {
4
+ "point": [
5
+ "POINTER_EVENT",
6
+ "TARGET_ELEMENT",
7
+ "PART_INDEX",
8
+ "FILE_INDEX",
9
+ "TAB_PAYLOAD = 0n"
10
+ ],
11
+ "point-close": [
12
+ "POINTER_EVENT",
13
+ "TARGET_ELEMENT"
14
+ ]
15
+ }
14
16
  }
@@ -94,7 +94,7 @@ const pointerConfig = {
94
94
  return
95
95
  }
96
96
 
97
- if (tabGroup.previewTabIndex === null && BigInt(tabGroup.openTabs.length) === tabGroup.maxTabCount) {
97
+ if ((tabGroup.previewTabIndex === null || droppedOntoEditor) && BigInt(tabGroup.openTabs.length) === tabGroup.maxTabCount) {
98
98
  alert("You have too many tabs open!")
99
99
  return
100
100
  }
@@ -163,6 +163,7 @@ const pointerConfig = {
163
163
  tabGroup.recomputeRouteID(true)
164
164
  } else {
165
165
 
166
+ debug("B", tabGroup.previewTabIndex === null, BigInt(tabGroup.openTabs.length), tabGroup.maxTabCount)
166
167
  if (BigInt(tabGroup.openTabs.length) === tabGroup.maxTabCount) {
167
168
  alert("You have too many tabs open!")
168
169
  return
@@ -7,7 +7,7 @@ const
7
7
  const filename = isProperty ? subjectProperty.filename : data
8
8
  const modifiers = isProperty ? subjectProperty.modifiers : ""
9
9
  const niceName = isProperty ? subjectProperty.niceName : `"${filename}"`
10
- const args = isProperty ? subject.manifest[subjectProperty.id] ?? null : null
10
+ const args = isProperty ? subject.manifest.methods[subjectProperty.id] ?? null : null
11
11
  const isAlias = isProperty && subjectProperty.isAlias
12
12
  const isView = isProperty && subjectProperty.isView
13
13
  const isGenerated = isProperty && subjectProperty.isGenerated
@@ -67,10 +67,10 @@ const
67
67
  },
68
68
  recordHTML = [createRecordsHTML(activePart)]
69
69
 
70
- let prototype = activePart.prototype
71
- while (prototype !== Object.prototype) {
72
- recordHTML.push(createRecordsHTML(prototype))
73
- prototype = prototype.prototype
70
+ let recordsSubject = activePart.prototype
71
+ while (recordsSubject) {
72
+ recordHTML.push(createRecordsHTML(recordsSubject))
73
+ recordsSubject = recordsSubject.prototype
74
74
  }
75
75
 
76
76
  return recordHTML.join("")
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "abstract": true,
3
3
  "extends": "boolean",
4
- "point": [
5
- "POINTER_EVENT",
6
- "TARGET_ELEMENT"
7
- ]
4
+ "methods": {
5
+ "point": [
6
+ "POINTER_EVENT",
7
+ "TARGET_ELEMENT"
8
+ ]
9
+ }
8
10
  }
@@ -0,0 +1,8 @@
1
+ const detailsElement = Q(`#info-${part.key}`)
2
+
3
+ if (detailsElement) {
4
+ if (part.model)
5
+ detailsElement.setAttribute("open", "")
6
+ else
7
+ detailsElement.removeAttribute("open")
8
+ }
@@ -1,13 +1,13 @@
1
- const cardinality = activePart.cardinality
2
- const cardinalityAsString = instances.includes(activePart) ? cardinality.toLocaleString() : null
1
+ const activePartCardinality = activePart.cardinality
2
+ const cardinalityAsString = instances.includes(activePart) ? activePartCardinality.toLocaleString() : null
3
3
 
4
4
  return (
5
5
  instances.includes(activePart) ? (
6
6
  "<h3>Cardinality</h3>" +
7
- `<p>${cardinalityAsString.length < 16 ? cardinalityAsString : scientific(cardinality, true)}</p>` +
7
+ `<p>${cardinalityAsString.length < 16 ? cardinalityAsString : scientific(activePartCardinality, true)}</p>` +
8
8
  `<hr>` +
9
9
  "<h3>Hartley Entropy</h3>" +
10
- `<p>${toCharms(activePart.cardinality)} (${toBits(activePart.cardinality)})</p>` +
10
+ `<p>${toCharms(activePartCardinality)} (${toBits(activePartCardinality)})</p>` +
11
11
  `<hr>` +
12
12
  `<h3>Equation</h3>` +
13
13
  "<math>" + activePart["equation-variable.html"] + "<mo>=</mo>" + activePart["equation.html"] + "</math>"
@@ -13,7 +13,7 @@ let cardinality = 1n
13
13
 
14
14
  for (let tabCount = 1n, permutationSize = 1n, payloadSize = 1n; tabCount <= subjectCount; tabCount++) {
15
15
 
16
- // Memoize a prototype LSB array to simplify initialization of Fenwick tree instances.
16
+ // TODO: Replace implementation.
17
17
  LSB[tabCount - 1n] = tabCount & -tabCount
18
18
 
19
19
  if (tabCount > maxTabCount)
@@ -62,33 +62,5 @@ tabGroup.define({
62
62
  payloadSizes: { value: payloadSizes },
63
63
  maxTabCount: { value: maxTabCount },
64
64
  tree: { value: null, writable: true },
65
- container: { value: null, writable: true },
66
- FenwickTree: {
67
- value: class FenwickTree {
68
- constructor() {
69
- this.tree = [...LSB]
70
- }
71
- update(i, val) {
72
- for (; i < subjectCount; i += LSB[i])
73
- this.tree[i] += val
74
- }
75
- query(i) {
76
- let sum = 0n
77
- for (; i >= 0n; i -= LSB[i])
78
- sum += this.tree[i]
79
- return sum
80
- }
81
- findNthAvailable(n) {
82
- let nthAvailable = 0n
83
- for (let p = powerFloor; p > 0n; p /= 2n) {
84
- const i = nthAvailable + p
85
- if (i <= subjectCount && this.tree[i - 1n] <= n) {
86
- n -= this.tree[i - 1n]
87
- nthAvailable = i
88
- }
89
- }
90
- return nthAvailable
91
- }
92
- }
93
- }
65
+ container: { value: null, writable: true }
94
66
  })
@@ -1,4 +1,5 @@
1
1
  if (tabGroup.activeTab && !tabGroup.activeTab.filename && !tabGroup.activeTab.part.isAbstract) {
2
- tabGroup.activeTab.part.attach("populate", tabGroup, "listener")
2
+ tabGroup.activeTab.part.attach("add", tabGroup, "listener")
3
+ tabGroup.activeTab.part.attach("update", tabGroup, "listener")
3
4
  tabGroup.activeTab.part.attach("remove", tabGroup, "listener")
4
5
  }
@@ -1,4 +1,5 @@
1
1
  if (tabGroup.viewedActiveTab && !tabGroup.viewedActiveTab.filename && !tabGroup.viewedActiveTab.part.isAbstract) {
2
- tabGroup.viewedActiveTab.part.detach("populate", tabGroup, "listener")
2
+ tabGroup.viewedActiveTab.part.detach("add", tabGroup, "listener")
3
+ tabGroup.viewedActiveTab.part.detach("update", tabGroup, "listener")
3
4
  tabGroup.viewedActiveTab.part.detach("remove", tabGroup, "listener")
4
5
  }
@@ -208,7 +208,7 @@ body.vintage #kireji_app tab- .close-tab:hover {
208
208
  box-shadow: var(--outset);
209
209
  }
210
210
 
211
- body.vintage #kireji_app tab- .close-tab:active {
211
+ body.vintage #kireji_app tab- .close-tab.down {
212
212
  box-shadow: var(--deep-inset);
213
213
  }
214
214
 
@@ -1,26 +1,28 @@
1
1
  {
2
- "HTML-render-tab": [
3
- "TAB_PART",
4
- "TAB_FILENAME",
5
- "TAB_PAYLOAD",
6
- "TAB_INDEX"
7
- ],
8
- "listener": [
9
- "SENDER"
10
- ],
11
- "routeID-get-permutation": [
12
- "TABS"
13
- ],
14
- "routeID-get-payload": [
15
- "TABS"
16
- ],
17
- "routeID-recompute": [
18
- "RECOMPUTE_OPEN_TABS"
19
- ],
20
- "factor-get-permutation": [
21
- "NUMBER_OF_TABS_OPEN",
22
- "CURRENT_TAB_INDEX"
23
- ],
24
- "listeners-attach": [],
25
- "listeners-detach": []
2
+ "methods": {
3
+ "HTML-render-tab": [
4
+ "TAB_PART",
5
+ "TAB_FILENAME",
6
+ "TAB_PAYLOAD",
7
+ "TAB_INDEX"
8
+ ],
9
+ "listener": [
10
+ "SENDER"
11
+ ],
12
+ "routeID-get-permutation": [
13
+ "TABS"
14
+ ],
15
+ "routeID-get-payload": [
16
+ "TABS"
17
+ ],
18
+ "routeID-recompute": [
19
+ "RECOMPUTE_OPEN_TABS"
20
+ ],
21
+ "factor-get-permutation": [
22
+ "NUMBER_OF_TABS_OPEN",
23
+ "CURRENT_TAB_INDEX"
24
+ ],
25
+ "listeners-attach": [],
26
+ "listeners-detach": []
27
+ }
26
28
  }
@@ -34,7 +34,7 @@ if (numberOfTabsOpen !== tabGroup.openTabs.length || tabGroup.permutationRouteID
34
34
  tabGroup.payloadRouteID = payloadRouteID
35
35
 
36
36
  // Prepare an empty Fenwick tree for converting availability-based indices to absolute indices.
37
- tabGroup.tree = new tabGroup.FenwickTree()
37
+ tabGroup.tree = new FenwickTree(BigInt(allSubjects.length))
38
38
 
39
39
  const indexOfLastOpenTab = numberOfTabsOpen - 1n
40
40
  const indexOfLastPossibleTabSubject = BigInt(allSubjects.length) - 1n
@@ -1,7 +1,7 @@
1
1
  const numberOfTabsOpen = BigInt(TABS.length)
2
2
 
3
3
  // Prepare an empty Fenwick tree for converting absolute indices to availability-based indices.
4
- tabGroup.tree = new tabGroup.FenwickTree()
4
+ tabGroup.tree = new FenwickTree(BigInt(allSubjects.length))
5
5
 
6
6
  // Compile the array of unranked indices into a single permutation identifier.
7
7
  let permutationRouteID = 0n
@@ -59,19 +59,10 @@ declare interface IKirejiAppTabGroup
59
59
  readonly previewTabIndex?: number
60
60
  /** The maximum number of tabs that the user can have open, used to mitigate the potentially massive state space of this component. */
61
61
  readonly maxTabCount: bigint
62
- /** A data type which can be used to performantly rank and unrank permutation indices. */
63
- readonly FenwickTree: typeof FenwickTree
64
62
  }
65
63
 
66
64
  declare type IKirejiAppTabGroupTabArray = IKirejiAppTabGroupTab[]
67
65
 
68
- declare class FenwickTree {
69
- constructor(): FenwickTree
70
- update(i: bigint, val: bigint): void
71
- query(i: bigint): bigint
72
- findNthAvailable(n: bigint): bigint
73
- }
74
-
75
66
  declare interface IKirejiAppTabGroupTab {
76
67
  readonly part: IPartAny
77
68
  readonly filename?: string
@@ -4,10 +4,8 @@ tabGroup.viewedPermutationRouteID = tabGroup.permutationRouteID
4
4
  tabGroup.viewedPayloadRouteID = tabGroup.payloadRouteID
5
5
  tabGroup.viewedOpenTabs = [...tabGroup.openTabs]
6
6
  tabGroup.container = Q("#tab-group")
7
-
8
- _.parts.core.client.promise.then(() => {
9
- Q(`tab-[data-active]`)?.scrollIntoView({
10
- behavior: 'smooth',
11
- inline: 'nearest',
12
- })
13
- })
7
+ tabGroup.attachListeners()
8
+ Q(`tab-[data-active]`)?.scrollIntoView({
9
+ behavior: 'smooth',
10
+ inline: 'nearest',
11
+ })
@@ -0,0 +1,115 @@
1
+ const hasNoTabs = !tabGroup.openTabs.length
2
+ const activeTab = tabGroup.activeTab
3
+ const previewTab = tabGroup.previewTab
4
+
5
+ // TODO: Create a "pseudo-part" that has all the same view methods, etc. of a normal part but is dynamically instantiated for dynamic typing.
6
+
7
+ if (tabGroup.openTabs.length !== tabGroup.viewedOpenTabs.length || tabGroup.viewedPermutationRouteID !== tabGroup.permutationRouteID || tabGroup.viewedPayloadRouteID !== tabGroup.payloadRouteID) {
8
+ // TODO: This is a dead-simple approach ... more performant approaches exist.
9
+ const tabContainer = Q("#tab-group")
10
+ const existingTabCount = tabGroup.viewedOpenTabs.length
11
+ const targetTabCount = tabGroup.openTabs.length
12
+ const maxLength = Math.max(existingTabCount, targetTabCount)
13
+
14
+ for (let i = 0; i < maxLength; i++) {
15
+ if (targetTabCount <= i) {
16
+ tabContainer.children[i].remove()
17
+ continue
18
+ }
19
+
20
+ const newOpenTab = tabGroup.openTabs[i]
21
+ const existingOpenTab = tabGroup.viewedOpenTabs[i]
22
+
23
+ if (existingOpenTab === newOpenTab)
24
+ continue
25
+
26
+ const newTabElement = (() => {
27
+ const offscreen = document.createElement("div")
28
+ offscreen.innerHTML = tabGroup.renderTabHTML(newOpenTab.part, newOpenTab.filename, newOpenTab.payload, i)
29
+ return offscreen.querySelector("tab-")
30
+ })()
31
+
32
+ if (existingOpenTab) {
33
+ tabContainer.children[i].replaceWith(newTabElement)
34
+ continue
35
+ }
36
+
37
+ tabContainer.appendChild(newTabElement)
38
+ }
39
+ tabGroup.viewedPermutationRouteID = tabGroup.permutationRouteID
40
+ tabGroup.viewedPayloadRouteID = tabGroup.payloadRouteID
41
+ tabGroup.viewedOpenTabs = [...tabGroup.openTabs]
42
+ }
43
+
44
+ if (tabGroup.viewedActiveTab && tabGroup.viewedActiveTab !== activeTab)
45
+ Q(`tab-[data-active]`)?.removeAttribute("data-active")
46
+
47
+ if (tabGroup.viewedPreviewTab && tabGroup.viewedPreviewTab !== previewTab)
48
+ Q(`tab-[data-preview]`)?.removeAttribute("data-preview")
49
+
50
+ const currentTabLayout = tabGroup.viewedActiveTab ? (tabGroup.viewedActiveTab.filename ? "file" : "summary") : "empty"
51
+
52
+ tabGroup.viewedActiveTab = activeTab
53
+ tabGroup.viewedPreviewTab = previewTab
54
+
55
+ if (!hasNoTabs) {
56
+ const activeTabElement = Q(`tab-:nth-child(${tabGroup.activeTabIndex + 1})`)
57
+
58
+ if (!activeTabElement.hasAttribute("data-active")) {
59
+ activeTabElement.setAttribute("data-active", "")
60
+ activeTabElement.scrollIntoView({
61
+ behavior: "smooth",
62
+ inline: 'nearest',
63
+ })
64
+ }
65
+
66
+ tabGroup.attachListeners()
67
+
68
+ const previewTabElement = tabGroup.previewTabIndex === null ? null : Q(`tab-:nth-child(${tabGroup.previewTabIndex + 1})`)
69
+
70
+ if (previewTabElement && !previewTabElement.hasAttribute("data-preview"))
71
+ previewTabElement.setAttribute("data-preview", "")
72
+ }
73
+
74
+ if (currentTabLayout === "summary") {
75
+ if (hasNoTabs) {
76
+ Q(`editor-view scroll-content`).innerHTML = editor["empty-view.html"]
77
+ } else if (!tabGroup.viewedActiveTab.filename) {
78
+ for (const section of sections) {
79
+ const element = Q(`#info-${section.key}>section`)
80
+ element.innerHTML = section["part.html"]
81
+ if (section.key.startsWith("state")) {
82
+ if (activePart.isAbstract || section.key === "state" && activePart.disabled)
83
+ element.setAttribute("disabled", "")
84
+ else
85
+ element.removeAttribute("disabled")
86
+ }
87
+ }
88
+ } else {
89
+ Q(`editor-view scroll-content`).innerHTML = editor["file-view.html"]
90
+ }
91
+ Q(`crumbs-`).innerHTML = editor["crumbs.html"]
92
+ } else if (currentTabLayout === "file") {
93
+ if (hasNoTabs) {
94
+ Q(`editor-view scroll-content`).innerHTML = editor["empty-view.html"]
95
+ } else if (tabGroup.viewedActiveTab.filename) {
96
+ Q('editor-view scroll-content').innerHTML = editor["file-view.html"]
97
+ } else {
98
+ Q(`editor-view scroll-content`).innerHTML = editor["summary-view.html"]
99
+ }
100
+ Q(`crumbs-`).innerHTML = editor["crumbs.html"]
101
+ } else {
102
+ if (hasNoTabs)
103
+ throw `Unexpected update to empty tab group without adding any new tabs.`
104
+ if (tabGroup.viewedActiveTab.filename) {
105
+ Q(`editor-view scroll-content`).innerHTML = editor["file-view.html"]
106
+ } else {
107
+ Q(`editor-view scroll-content`).innerHTML = editor["summary-view.html"]
108
+ }
109
+ Q(`crumbs-`).innerHTML = editor["crumbs.html"]
110
+ }
111
+
112
+ Q("#sidebar-view summary[data-active]")?.removeAttribute("data-active")
113
+
114
+ if (!hasNoTabs)
115
+ Q(`#sidebar-view summary[data-index="${allParts.indexOf(tabGroup.viewedActiveTab.part)}"]`)?.setAttribute("data-active", "")
@@ -0,0 +1,10 @@
1
+ /** @type {IScroller<IPartOutliner<IKirejiAppSidebar>>} */
2
+ const scroller = sidebar.view.scroller
3
+
4
+ if (part.routeID === 0n) {
5
+ scroller.removeView()
6
+ sidebar.element.remove()
7
+ } else {
8
+ Q("tool-bar").after(sidebar.element)
9
+ scroller.addView()
10
+ }
@@ -1,4 +1,6 @@
1
1
  {
2
2
  "extends": "mix",
3
- "activeTab-frame": []
3
+ "methods": {
4
+ "activeTab-frame": []
5
+ }
4
6
  }
@@ -1,6 +1,8 @@
1
1
  {
2
- "point": [
3
- "POINTER_EVENT",
4
- "TARGET_ELEMENT"
5
- ]
2
+ "methods": {
3
+ "point": [
4
+ "POINTER_EVENT",
5
+ "TARGET_ELEMENT"
6
+ ]
7
+ }
6
8
  }
@@ -1,7 +1,5 @@
1
- if (hydrated) {
2
- Q(`tool-bar>button:nth-child(${part.index + 1})`).setAttribute("data-active", "")
3
- /** @type {IPartOutliner<IKirejiAppSidebar>} */
4
- const newView = sidebar[part.key]
5
- sidebar.element.innerHTML = sidebar["view.html"]
6
- newView.scroller.addView()
7
- }
1
+ Q(`tool-bar>button:nth-child(${part.index + 1})`).setAttribute("data-active", "")
2
+ /** @type {IPartOutliner<IKirejiAppSidebar>} */
3
+ const newView = sidebar[part.key]
4
+ sidebar.element.innerHTML = sidebar["view.html"]
5
+ newView.scroller.addView()
@@ -39,7 +39,7 @@ body.vintage #kireji_app tool-bar>button {
39
39
  box-shadow: var(--deep-outset);
40
40
  }
41
41
 
42
- body.vintage #kireji_app tool-bar>button:active,
42
+ body.vintage #kireji_app tool-bar>button.down,
43
43
  body.vintage #kireji_app:has(side-bar) tool-bar>button[data-active] {
44
44
  box-shadow: var(--deep-inset);
45
45
  background: var(--bg-checker), var(--bg-un-mode);
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "extends": "match",
3
- "point": [
4
- "POINTER_EVENT",
5
- "TARGET_ELEMENT",
6
- "VIEW_INDEX"
7
- ]
3
+ "methods": {
4
+ "point": [
5
+ "POINTER_EVENT",
6
+ "TARGET_ELEMENT",
7
+ "VIEW_INDEX"
8
+ ]
9
+ }
8
10
  }
@@ -5,7 +5,7 @@ document.body.classList.add("unhydrated")
5
5
  const instanceIndex = desktop.windows.instances.findIndex(window => window.application.host === HOST)
6
6
  if (instanceIndex !== -1) {
7
7
  const task = document.querySelectorAll(`task-bar>button.task`)[instanceIndex]
8
- task.classList.add("pressed")
8
+ task.classList.add("preview-pressed", "pressed")
9
9
  }
10
10
 
11
11
  location = targetLocation