@cardenelabs/dragon 0.12.0 → 0.14.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cardenelabs/dragon",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Dragon — Mermaid 感覚で animated SVG を生成する Text DSL。 cdl engine を内部利用。",
5
5
  "license": "MIT",
6
6
  "author": "cardene777",
package/src/color.ts CHANGED
@@ -106,11 +106,13 @@ export type StrippedPaint = { path: string; value: string };
106
106
  /**
107
107
  * 図の中から、 色を塗る位置に入った外部参照を落とす。
108
108
  *
109
- * 対象は 2 種類ある。
109
+ * 対象は 3 種類ある。
110
110
  *
111
111
  * - 色を塗る key (`fill` / `stroke` / `bg` 等) の値
112
112
  * - 状態の値 (`states[].initial` と、 phase が状態へ入れる値)。 状態は `{名前}` の形で
113
113
  * `fill` に差し込まれるため、 色を塗る位置に届く
114
+ * - つまみの値 (`inputs[].defaultValue` / `defaultValues` / `options`)。 これらも状態を上書きし、
115
+ * 同じ形で paint に届く
114
116
  *
115
117
  * 説明文 (`title` / `subtitle` / `value` / `rows`) は対象外。 文字として出るだけで
116
118
  * 属性にはならないため、 URL を書く正当な用途を壊さない。
@@ -119,23 +121,40 @@ export type StrippedPaint = { path: string; value: string };
119
121
  */
120
122
  export function stripExternalPaint(diagram: unknown): StrippedPaint[] {
121
123
  const stripped: StrippedPaint[] = [];
122
- walk(diagram, "", false, stripped);
124
+ walk(diagram, "", false, stripped, false);
123
125
  return stripped;
124
126
  }
125
127
 
128
+ /** つまみから状態値になり得る文字列の欄。 */
129
+ const INPUT_VALUE_KEYS: ReadonlySet<string> = new Set(["defaultvalue", "defaultvalues", "options"]);
130
+
126
131
  /**
127
132
  * 図の中を辿って外部参照を落とす。
128
133
  *
129
134
  * `inStateValue` = 今見ている場所が状態の値かどうか。 状態は key の名前が `initial` や
130
135
  * 状態名そのもの (phase の `sets`) になるため、 key の名前だけでは色かどうか分からない。
131
136
  * 「状態を入れる箱の中にいる」 ことを引き継いで判断する。
137
+ * `inInputs` は `inputs` の中にいることを示し、値になる欄だけを `inStateValue` へ合流させる。
132
138
  */
133
- function walk(node: unknown, path: string, inStateValue: boolean, out: StrippedPaint[]): void {
139
+ function walk(
140
+ node: unknown,
141
+ path: string,
142
+ inStateValue: boolean,
143
+ out: StrippedPaint[],
144
+ inInputs: boolean,
145
+ ): void {
134
146
  if (node === null || typeof node !== "object") return;
135
147
 
136
148
  if (Array.isArray(node)) {
137
149
  for (let i = 0; i < node.length; i++) {
138
- walk(node[i], `${path}[${i}]`, inStateValue, out);
150
+ const here = `${path}[${i}]`;
151
+ const value = node[i];
152
+ if (inStateValue && typeof value === "string" && pointsOutside(value)) {
153
+ node[i] = SAFE_PAINT;
154
+ out.push({ path: here, value });
155
+ } else {
156
+ walk(value, here, inStateValue, out, inInputs);
157
+ }
139
158
  }
140
159
  return;
141
160
  }
@@ -145,7 +164,13 @@ function walk(node: unknown, path: string, inStateValue: boolean, out: StrippedP
145
164
  const here = path ? `${path}.${key}` : key;
146
165
  const lower = key.toLowerCase();
147
166
  // 状態を入れる箱に入ったら、 その中の値はすべて状態の値として扱う
148
- const nextInState = inStateValue || lower === "states" || lower === "sets" || lower === "tweens";
167
+ const nextInState =
168
+ inStateValue ||
169
+ lower === "states" ||
170
+ lower === "sets" ||
171
+ lower === "tweens" ||
172
+ (inInputs && INPUT_VALUE_KEYS.has(lower));
173
+ const nextInInputs = inInputs || lower === "inputs";
149
174
 
150
175
  if (typeof value === "string") {
151
176
  const isPaint = PAINT_KEYS.has(lower) || (nextInState && (lower === "initial" || lower === "to" || lower === "from" || !isReservedStateKey(lower)));
@@ -155,7 +180,7 @@ function walk(node: unknown, path: string, inStateValue: boolean, out: StrippedP
155
180
  }
156
181
  continue;
157
182
  }
158
- walk(value, here, nextInState, out);
183
+ walk(value, here, nextInState, out, nextInInputs);
159
184
  }
160
185
  }
161
186