@vernikr/size-report 2.9.0 → 2.9.1
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/package.json +2 -2
- package/src/locales.js +0 -4
- package/src/page/app.css +4 -6
- package/src/page/build.js +6 -8
- package/src/page/panel.js +3 -4
- package/src/page/payload.js +3 -2
- package/src/page/state.js +40 -111
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vernikr/size-report",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.1",
|
|
4
4
|
"author": "vernikr",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"report"
|
|
66
66
|
],
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@vernikr/size-report": "2.
|
|
68
|
+
"@vernikr/size-report": "2.9.0",
|
|
69
69
|
"c8": "10",
|
|
70
70
|
"dependency-cruiser": "17",
|
|
71
71
|
"eslint": "^9.18.0",
|
package/src/locales.js
CHANGED
|
@@ -41,8 +41,6 @@ export const LOCALES = {
|
|
|
41
41
|
+ 'Включите хотя бы одну в панели выше: без метрик нет ни одной колонки с числом.',
|
|
42
42
|
noFiles: 'Ни один файл не выбран: в таблице остался только общий объём. '
|
|
43
43
|
+ 'Включите файл в панели выше, чтобы увидеть его колонки.',
|
|
44
|
-
linkForeign: 'Ссылка собрана в другом отчёте и не применена: показано то, что '
|
|
45
|
-
+ 'выбрано в этом браузере. Адрес не тронут.',
|
|
46
44
|
linkBroken: 'В адресе испорченный выбор — прочитать его не удалось. Показано то, '
|
|
47
45
|
+ 'что выбрано в этом браузере.',
|
|
48
46
|
linkExtra: 'Часть ссылки пропущена: в этом отчёте нет {n} названных имён. '
|
|
@@ -95,8 +93,6 @@ export const LOCALES = {
|
|
|
95
93
|
+ 'Turn on at least one above: without metrics there is no column holding a number.',
|
|
96
94
|
noFiles: 'No file is selected: the table shows the total only. '
|
|
97
95
|
+ 'Turn on a file above to see its columns.',
|
|
98
|
-
linkForeign: 'The link was built for another report, so it is not applied: you '
|
|
99
|
-
+ 'see what this browser has. The address is left as it is.',
|
|
100
96
|
linkBroken: 'The choice in the address is unreadable. You see what this browser '
|
|
101
97
|
+ 'has.',
|
|
102
98
|
linkExtra: 'Part of the link is skipped: this report has none of the {n} names '
|
package/src/page/app.css
CHANGED
|
@@ -34,8 +34,7 @@ body {
|
|
|
34
34
|
h1 { margin: 0 0 9px; font-size: 21px; font-weight: 650; letter-spacing: -.012em; }
|
|
35
35
|
|
|
36
36
|
/* The panel of choices is a card: it separates the controls from the data and does not merge with the table that begins
|
|
37
|
-
* below. The report's heading opens it
|
|
38
|
-
* names is read from (see the markup in `src/page/build.js`). */
|
|
37
|
+
* below. The report's heading opens it: the page has no band above the numbers (the markup is in `src/page/build.js`). */
|
|
39
38
|
.panel {
|
|
40
39
|
margin: 0 0 var(--gap);
|
|
41
40
|
padding: 12px 14px 13px;
|
|
@@ -164,9 +163,8 @@ h1 { margin: 0 0 9px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
164
163
|
* (`src/page/build.js`), and adding nodes to it for the sake of styling would mean changing the page's shape in two places
|
|
165
164
|
* instead of one. There are three rows, named by subject: the message about a link, the **working row** and the empty
|
|
166
165
|
* state — while the panel of choices spans them all in the left column, its heading inside it. Only the working row
|
|
167
|
-
* stretches
|
|
168
|
-
* "whatever came out" (it would push the table off the screen) but that same working row, inside which it scrolls
|
|
169
|
-
* list longer than the window is the usual case.
|
|
166
|
+
* stretches: the table gets all the remaining height and the panel no more than that; the panel's own height is not
|
|
167
|
+
* "whatever came out" (it would push the table off the screen) but that same working row, inside which it scrolls.
|
|
170
168
|
*
|
|
171
169
|
* The threshold of 900px is the same as the adaptations' below: one border between "wide" and "narrow", or the page would
|
|
172
170
|
* be left with no rule at all between two thresholds. */
|
|
@@ -187,7 +185,7 @@ h1 { margin: 0 0 9px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
187
185
|
#shell { grid-area: 2 / 2 / 3 / 3; }
|
|
188
186
|
#state { grid-area: 3 / 2 / 4 / 3; align-self: start; }
|
|
189
187
|
/* The working row runs the full height, as the table does: the panel ends where it ends. The panel scrolls rather than the
|
|
190
|
-
* page, and its top padding is gone: the heading carries that room instead
|
|
188
|
+
* page, and its top padding is gone: the heading carries that room instead and travels away with the list, while the
|
|
191
189
|
* sticky row of categories stands flush with the card's edge rather than under a band of passing rows. */
|
|
192
190
|
.panel { grid-area: 1 / 1 / -1 / 2; min-height: 0; margin-bottom: 0; padding-top: 0; overflow: auto; }
|
|
193
191
|
.panel h1 { padding-top: 12px; }
|
package/src/page/build.js
CHANGED
|
@@ -85,7 +85,6 @@ function uiText(page, loc) {
|
|
|
85
85
|
foldClose: page.foldClose,
|
|
86
86
|
foldOpen: page.foldOpen,
|
|
87
87
|
all: page.all,
|
|
88
|
-
linkForeign: page.linkForeign,
|
|
89
88
|
linkBroken: page.linkBroken,
|
|
90
89
|
linkExtra: page.linkExtra,
|
|
91
90
|
/* What a host that cannot unpack the block is told: the page's one message about its own file rather than about
|
|
@@ -197,8 +196,8 @@ export function pagePayload(data) {
|
|
|
197
196
|
schema: 2,
|
|
198
197
|
tool: data.tool,
|
|
199
198
|
/* The report's own words are the ones the page reads: `heading` is the artifact's `<h1>`, built before the block,
|
|
200
|
-
* `journal` is null today, and `fixCommand`
|
|
201
|
-
*
|
|
199
|
+
* `journal` is null today, and `fixCommand` belongs to a refusal and to the contract rather than to the page, which
|
|
200
|
+
* builds no heading, prints no journal and suggests no command. */
|
|
202
201
|
report: {
|
|
203
202
|
locale: data.report.locale,
|
|
204
203
|
title: data.report.title,
|
|
@@ -238,11 +237,10 @@ export function pagePacked(text) {
|
|
|
238
237
|
/* The report's page is one file: the data lies in it, the script is pasted in, there are no external references. Hence
|
|
239
238
|
* it opens with a double click and works without a network.
|
|
240
239
|
*
|
|
241
|
-
* The page's chrome is the panel and the table, and nothing stands above the numbers: the
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* rebuilt on every opening, which is why the heading is the card's other child rather than one more field. */
|
|
240
|
+
* The page's chrome is the panel and the table, and nothing stands above the numbers: the heading opens the panel — the
|
|
241
|
+
* one place holding the reader's own controls — and neither the tool, nor its version, nor the artifact's path is printed
|
|
242
|
+
* anywhere, the file lying in a directory whose name already says where. The panel's card is the markup's and its fields
|
|
243
|
+
* are the script's: `#panel` is emptied and rebuilt on every opening, hence the heading is the card's other child. */
|
|
246
244
|
export function pageHtml(data, cfg) {
|
|
247
245
|
const loc = LOCALES[cfg.locale];
|
|
248
246
|
return '<!doctype html>\n<html lang="' + esc(loc.html) + '">\n<head>\n<meta charset="utf-8">\n'
|
package/src/page/panel.js
CHANGED
|
@@ -188,10 +188,9 @@ export function appPanel() {
|
|
|
188
188
|
const metrics = appEl('fieldset');
|
|
189
189
|
metrics.appendChild(appEl('legend', null, appUi.metrics));
|
|
190
190
|
const mrow = appEl('div', 'row');
|
|
191
|
-
/* What a metric is and how its number was obtained stand in
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* switches took the room beside the numbers. */
|
|
191
|
+
/* What a metric is and how its number was obtained stand in the tooltip of the box that switches it: the dictionary
|
|
192
|
+
* and the minifier come from the run's settings, so the reader has to see with what he is counting, and the box is
|
|
193
|
+
* where he looks. */
|
|
195
194
|
appData.metrics.forEach((m) => {
|
|
196
195
|
const box = appBox(m.label, m.note + ' — ' + appUi.methodLabel + ' ' + m.method, appView.metrics[m.key], (e) => {
|
|
197
196
|
appView.metrics[m.key] = e.target.checked;
|
package/src/page/payload.js
CHANGED
|
@@ -146,8 +146,9 @@ function appRowOf(p, r, values) {
|
|
|
146
146
|
};
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
/* The whole block, unrolled into the dense contract the page reads:
|
|
150
|
-
*
|
|
149
|
+
/* The whole block, unrolled into the dense contract the page reads: the block is a shape of that contract rather than a
|
|
150
|
+
* subset of it, so `schema` and `tool` come over with the rest although the page reads neither — the form mark and the
|
|
151
|
+
* author belong to the answer an agent is given, and one shape is cheaper to keep than two. */
|
|
151
152
|
export function appDecode(p) {
|
|
152
153
|
const keys = p.metrics.map((m) => appText(p, m[0]));
|
|
153
154
|
const hist = appUnroll(p, keys);
|
package/src/page/state.js
CHANGED
|
@@ -11,12 +11,11 @@ import { appDecode } from './payload.js';
|
|
|
11
11
|
* network: the styling arrives in the same file, and the cell markup follows the rules of the shared part of the styling
|
|
12
12
|
* (`clip`, a commit's caption).
|
|
13
13
|
*
|
|
14
|
-
* The panel remembers the reader's choice between visits ("the choice's memory" below):
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* still read (`appLinkUse`).
|
|
14
|
+
* The panel remembers the reader's choice between visits ("the choice's memory" below): one record for the browser, under
|
|
15
|
+
* a name of this page's own, keeping the fact of a whole category and the names of the files switched off one by one —
|
|
16
|
+
* only what is off is written down, and a name the report does not hold matches nothing. The choice is the reader's
|
|
17
|
+
* rather than a report's, since all `file://` pages share one storage, and it stays in the browser: a report opened from
|
|
18
|
+
* disk keeps a clean address, and a link made in an earlier release is still read (`appLinkUse`).
|
|
20
19
|
*
|
|
21
20
|
* The page draws no conclusion about how a number was obtained: the method of each metric arrives in the data, and the
|
|
22
21
|
* page prints it. There is no second rule of counting here, and no vocabulary of precision either. */
|
|
@@ -31,8 +30,6 @@ export let appData = null;
|
|
|
31
30
|
export let appView = null;
|
|
32
31
|
export let appMetric = null;
|
|
33
32
|
export let appMeasured = null;
|
|
34
|
-
let appKey = null;
|
|
35
|
-
let appFoldKey = null;
|
|
36
33
|
|
|
37
34
|
/* One place that turns the unpacked block into what the chapters speak: the sparse form is unrolled by the payload
|
|
38
35
|
* chapter into the dense contract every number comes from — snapshots per commit, the texts themselves, "now" as
|
|
@@ -45,10 +42,8 @@ let appFoldKey = null;
|
|
|
45
42
|
* page's tree is the project's tree while the numbers belong to columns only); the name follows the same rule as the
|
|
46
43
|
* choice's record (`appFileAt`), so the tree and the reader's memory cannot drift apart.
|
|
47
44
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* the passport left behind go away at the same moment (`appSweep`): the report is in a position to say what is dead,
|
|
51
|
-
* and nothing of the reader's memory has been read yet. */
|
|
45
|
+
* What other namings left in this storage go at the same moment (`appSweep`), before anything of the reader's memory is
|
|
46
|
+
* read. */
|
|
52
47
|
export function appBoot(text) {
|
|
53
48
|
appData = appDecode(JSON.parse(text));
|
|
54
49
|
/* The tree is folded as it opens: a project's tree is longer than the window, and the reader's first look is at a
|
|
@@ -59,8 +54,6 @@ export function appBoot(text) {
|
|
|
59
54
|
appMeasured = {};
|
|
60
55
|
appData.metrics.forEach((m) => { appView.metrics[m.key] = true; appMetric[m.key] = m; });
|
|
61
56
|
appData.files.forEach((_f, i) => { appView.files.push(true); appMeasured[appFileAt(i)] = i; });
|
|
62
|
-
appKey = APP_FORM + appPassport();
|
|
63
|
-
appFoldKey = appKey + ':tree';
|
|
64
57
|
appSweep();
|
|
65
58
|
}
|
|
66
59
|
|
|
@@ -75,13 +68,11 @@ let appTransient = false;
|
|
|
75
68
|
|
|
76
69
|
/* -------- the reader's memory of his choice -------- */
|
|
77
70
|
|
|
78
|
-
/* The
|
|
79
|
-
*
|
|
80
|
-
* columns stood inside it, so every build of the report had an address of its own and the reader's choice was left
|
|
81
|
-
* behind at the previous one — and because the mark is what lets this release tell the addresses it writes from the
|
|
82
|
-
* addresses of that naming (`appSweep`), without pretending to know whose record lies under the older one. */
|
|
71
|
+
/* The two keys of this page's memory: the choice and the unfolded tree. The namespace is this page's own and it is one
|
|
72
|
+
* for every report — all `file://` pages share a storage, so the memory belongs to the reader rather than to a report. */
|
|
83
73
|
const APP_STORE = 'size-report:';
|
|
84
|
-
const
|
|
74
|
+
const APP_KEY = APP_STORE + 'choice';
|
|
75
|
+
const APP_FOLD_KEY = APP_STORE + 'tree';
|
|
85
76
|
|
|
86
77
|
/* The name of a file for the record is its path at HEAD, or the last of the settings when the file is already gone from
|
|
87
78
|
* there: that is the name it is recognised by in the report. */
|
|
@@ -90,74 +81,22 @@ export function appFileAt(i) {
|
|
|
90
81
|
return f.path === null ? f.paths[0] : f.path;
|
|
91
82
|
}
|
|
92
83
|
|
|
93
|
-
/* The files of one category, in the order of the data: a category is a group
|
|
94
|
-
*
|
|
95
|
-
* the files a second time. */
|
|
84
|
+
/* The files of one category, in the order of the data: a category is a group as the engine named it (`category`), and
|
|
85
|
+
* the panel's boxes, their fields and the record all ask for that group here. */
|
|
96
86
|
export function appCatOf(key) {
|
|
97
87
|
const idx = [];
|
|
98
88
|
appData.files.forEach((f, i) => { if (f.category === key) idx.push(i); });
|
|
99
89
|
return idx;
|
|
100
90
|
}
|
|
101
91
|
|
|
102
|
-
/*
|
|
103
|
-
*
|
|
104
|
-
|
|
105
|
-
let h = 2166136261;
|
|
106
|
-
for (let i = 0; i < text.length; i++) {
|
|
107
|
-
h ^= text.charCodeAt(i);
|
|
108
|
-
h = Math.imul(h, 16777619);
|
|
109
|
-
}
|
|
110
|
-
return (h >>> 0).toString(16);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/* The report's passport: the tool's name, the data schema, the artifact's path, the title and the oldest row of the
|
|
114
|
-
* history. It is what tells one report from another — the record's key is chosen by it, so a choice made in someone
|
|
115
|
-
* else's report is not picked up — and it is what makes the memory the report's rather than a build of it: every later
|
|
116
|
-
* build of the same report counts the same value and finds the same choice.
|
|
117
|
-
*
|
|
118
|
-
* The first four are what the report says about itself, and they are the same in a report of another project (both the
|
|
119
|
-
* artifact's path and the title are defaults there, and all `file://` pages share one memory), which is what the fifth
|
|
120
|
-
* is for: the oldest row is a commit of this history, the same in every clone and every build, and the one commit the
|
|
121
|
-
* history never moves — rows are built from the oldest commit up, so a commit appends rows and leaves that one where it
|
|
122
|
-
* stands.
|
|
123
|
-
*
|
|
124
|
-
* The package version and the top of the history are absent on purpose: updating the tool does not change what a column
|
|
125
|
-
* means, while a grown history is the very history the reader comes back to.
|
|
126
|
-
*
|
|
127
|
-
* The columns were named here once, and they are what does not belong here at all: their labels and their order move
|
|
128
|
-
* with the numbers — a project without settings pinned derives the columns on every run, ordered by size within an
|
|
129
|
-
* extension (`src/project.js`), so every commit that grew or shrank a file gave the report another passport and left the
|
|
130
|
-
* reader's choice at the old address. What a record holds are names, and a name the report no longer has means nothing
|
|
131
|
-
* (`appApply`), so the columns have nothing to guard in the passport.
|
|
132
|
-
*
|
|
133
|
-
* Counted once per document: it is a constant of the report, which depends on nothing the reader can change, and every
|
|
134
|
-
* click asks for it (the key of the memory and the passport of the record). A second count would be a second answer
|
|
135
|
-
* waiting to happen, and the block it reads does not change while the page is open. */
|
|
136
|
-
let appPassportValue = null;
|
|
137
|
-
function appPassport() {
|
|
138
|
-
if (appPassportValue === null) {
|
|
139
|
-
const oldest = appData.rows.length === 0 ? '' : appData.rows[0].sha;
|
|
140
|
-
appPassportValue = appHash([appData.tool.name, appData.schema, appData.report.artifact,
|
|
141
|
-
appData.report.title, oldest].join('\n'));
|
|
142
|
-
}
|
|
143
|
-
return appPassportValue;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/* The addresses an earlier naming left in the browser: every one of them belonged to a single build of a report, and no
|
|
147
|
-
* report ever looks under them again — the memory is read under the address of the report's identity alone. A browser
|
|
148
|
-
* that has lived through a long history holds one such record per commit, so they go away, once, when a report of this
|
|
149
|
-
* release is opened.
|
|
150
|
-
*
|
|
151
|
-
* What is swept is the mark of the form rather than a claim about whose record it is: the older address was counted from
|
|
152
|
-
* the data, so the record under it cannot be attributed to a report — hence a memory left by an older release in this
|
|
153
|
-
* browser goes too, and it is one of a report that was not rebuilt since its reader last clicked (that release moved the
|
|
154
|
-
* address at the next build itself, leaving the memory behind). What this release writes is left alone: under it lies
|
|
155
|
-
* this report's memory and another report's, and the two are told apart by the identity rather than by the form. */
|
|
92
|
+
/* What other namings left in this storage: the memory is read under the two keys above and under nothing else, so any
|
|
93
|
+
* other name in the namespace is dead weight — an address counted per build, a record of an older form. They go once,
|
|
94
|
+
* when a report is opened. */
|
|
156
95
|
function appSweep() {
|
|
157
96
|
try {
|
|
158
97
|
for (let i = window.localStorage.length - 1; i >= 0; i--) {
|
|
159
98
|
const key = window.localStorage.key(i);
|
|
160
|
-
if (key !== null && key.indexOf(APP_STORE) === 0 && key
|
|
99
|
+
if (key !== null && key.indexOf(APP_STORE) === 0 && key !== APP_KEY && key !== APP_FOLD_KEY) {
|
|
161
100
|
window.localStorage.removeItem(key);
|
|
162
101
|
}
|
|
163
102
|
}
|
|
@@ -166,18 +105,15 @@ function appSweep() {
|
|
|
166
105
|
}
|
|
167
106
|
}
|
|
168
107
|
|
|
169
|
-
/* One record of the choice: the facts of the groups
|
|
170
|
-
* decided one by one, and only what is switched off.
|
|
108
|
+
/* One record of the choice: the facts of the groups, the names of the files switched off one by one, and nothing else.
|
|
171
109
|
*
|
|
172
|
-
* A category
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* he switched off go into the record by name (`files`), as they did before this chapter knew categories; such a category
|
|
177
|
-
* is **absent** from `cats`, which is how the record distinguishes "a group fact" from "no group fact to state".
|
|
110
|
+
* A category wholly off or wholly on is written down as that fact — the group is named, so a file joining it later is
|
|
111
|
+
* switched with it and the record does not grow with the project — while a category in the third state cannot speak for
|
|
112
|
+
* the reader, whose choice was made file by file: those files go into `files` by name, and the category stays out of
|
|
113
|
+
* `cats`, which is how a group fact differs from no group fact to state.
|
|
178
114
|
*
|
|
179
|
-
* "Switched on" and "no record" are the same state, hence `null` rather than an empty record
|
|
180
|
-
*
|
|
115
|
+
* "Switched on" and "no record" are the same state, hence `null` rather than an empty record: turning every box back on
|
|
116
|
+
* removes it instead of leaving a trace indistinguishable from a choice. */
|
|
181
117
|
function appRecord() {
|
|
182
118
|
const metrics = {};
|
|
183
119
|
const cats = {};
|
|
@@ -191,12 +127,12 @@ function appRecord() {
|
|
|
191
127
|
});
|
|
192
128
|
const empty = Object.keys(metrics).length === 0 && Object.keys(files).length === 0
|
|
193
129
|
&& Object.keys(cats).every((key) => cats[key] === true);
|
|
194
|
-
return empty ? null : { v: 1,
|
|
130
|
+
return empty ? null : { v: 1, metrics: metrics, cats: cats, files: files };
|
|
195
131
|
}
|
|
196
132
|
|
|
197
|
-
// Whether a record is
|
|
133
|
+
// Whether a record is of this format — one rule for the memory and the address alike.
|
|
198
134
|
function appRecordOk(rec) {
|
|
199
|
-
return rec !== null && typeof rec === 'object' && rec.v === 1
|
|
135
|
+
return rec !== null && typeof rec === 'object' && rec.v === 1;
|
|
200
136
|
}
|
|
201
137
|
|
|
202
138
|
/* A record into the browser's memory or out of it, and what is read back from it: the two halves of the memory, written
|
|
@@ -217,7 +153,7 @@ function appKeep(key, rec) {
|
|
|
217
153
|
}
|
|
218
154
|
|
|
219
155
|
export function appWrite() {
|
|
220
|
-
if (!appTransient) appKeep(
|
|
156
|
+
if (!appTransient) appKeep(APP_KEY, appRecord());
|
|
221
157
|
}
|
|
222
158
|
|
|
223
159
|
/* What the browser saved under a key: its absence, a foreign record, a broken one and a record of another report amount
|
|
@@ -241,10 +177,10 @@ function appAll() {
|
|
|
241
177
|
appData.files.forEach((_f, i) => { appView.files[i] = true; });
|
|
242
178
|
}
|
|
243
179
|
|
|
244
|
-
/* What the address says. It answers either with a record of
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
180
|
+
/* What the address says. It answers either with a record of this format or with a refusal (`linkBroken` — nothing to
|
|
181
|
+
* read): a choice that cannot be read is not applied, but it does not stay silent either — otherwise the reader would not
|
|
182
|
+
* understand why he sees something other than what was sent to him. An address without the link's name is no link at
|
|
183
|
+
* all: silence, so as not to argue with the page's ordinary anchors. */
|
|
248
184
|
function appLinkRead() {
|
|
249
185
|
const hash = window.location.hash || '';
|
|
250
186
|
if (hash.indexOf(APP_LINK) !== 0) return { rec: null, refused: null };
|
|
@@ -259,10 +195,7 @@ function appLinkRead() {
|
|
|
259
195
|
return { rec: null, refused: 'linkBroken' };
|
|
260
196
|
}
|
|
261
197
|
}
|
|
262
|
-
if (!appRecordOk(rec)) {
|
|
263
|
-
return { rec: null, refused: rec === null || typeof rec !== 'object' || rec.v !== 1
|
|
264
|
-
? 'linkBroken' : 'linkForeign' };
|
|
265
|
-
}
|
|
198
|
+
if (!appRecordOk(rec)) return { rec: null, refused: 'linkBroken' };
|
|
266
199
|
return { rec: rec, refused: null, extra: appUnknown(rec) };
|
|
267
200
|
}
|
|
268
201
|
|
|
@@ -303,9 +236,9 @@ export function appLinkUse() {
|
|
|
303
236
|
return 'none';
|
|
304
237
|
}
|
|
305
238
|
|
|
306
|
-
// Reading: the reader's own choice, as he left it
|
|
239
|
+
// Reading: the reader's own choice, as he left it.
|
|
307
240
|
export function appRead() {
|
|
308
|
-
return appLoad(
|
|
241
|
+
return appLoad(APP_KEY);
|
|
309
242
|
}
|
|
310
243
|
|
|
311
244
|
/* Applying goes by name: a file is recognised by its path, a metric by its key, a category by the key the engine gave
|
|
@@ -313,9 +246,8 @@ export function appRead() {
|
|
|
313
246
|
* the settings), while files, categories and metrics that appeared stay switched on — the way someone opening the page
|
|
314
247
|
* for the first time sees them.
|
|
315
248
|
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* and wrote only names — is applied by its names exactly as it was. */
|
|
249
|
+
* The groups go first, the names after them: the file-by-file decision is the finer one, and a record that knows no
|
|
250
|
+
* groups is applied by its names. */
|
|
319
251
|
export function appApply(rec) {
|
|
320
252
|
const metrics = rec.metrics || {};
|
|
321
253
|
const cats = rec.cats || {};
|
|
@@ -335,10 +267,9 @@ export function appApply(rec) {
|
|
|
335
267
|
* what the onlooker looks at rather than about which numbers are read, which is why it never goes into a link and never
|
|
336
268
|
* leaves the browser. The tree opens folded, so **the unfolded folders are what is kept** (`true`) — the default is the
|
|
337
269
|
* absence of the name, the same way "switched on" is the absence of a choice. A folder's name is its path ("src/page"),
|
|
338
|
-
* so a vanished name simply means nothing.
|
|
339
|
-
* is. */
|
|
270
|
+
* so a vanished name simply means nothing. */
|
|
340
271
|
export function appFoldRead() {
|
|
341
|
-
const rec = appLoad(
|
|
272
|
+
const rec = appLoad(APP_FOLD_KEY);
|
|
342
273
|
if (rec === null) return;
|
|
343
274
|
const open = rec.open || {};
|
|
344
275
|
Object.keys(open).forEach((p) => { if (open[p] === true) appView.open[p] = true; });
|
|
@@ -350,7 +281,5 @@ export function appFoldSet(path, open) {
|
|
|
350
281
|
if (open) appView.open[path] = true;
|
|
351
282
|
else delete appView.open[path];
|
|
352
283
|
const names = Object.keys(appView.open);
|
|
353
|
-
appKeep(
|
|
354
|
-
? null
|
|
355
|
-
: { v: 1, passport: appPassport(), open: appView.open });
|
|
284
|
+
appKeep(APP_FOLD_KEY, names.length === 0 ? null : { v: 1, open: appView.open });
|
|
356
285
|
}
|