@inkbrick/react 0.0.0-stage → 0.1.0-alpha.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/dist/FormulaPalette-WFRPRHS5.js +320 -0
- package/dist/FormulaPalette-WFRPRHS5.js.map +1 -0
- package/dist/chunk-TPUX4C45.js +2309 -0
- package/dist/chunk-TPUX4C45.js.map +1 -0
- package/dist/index.d.ts +1431 -0
- package/dist/index.js +4880 -0
- package/dist/index.js.map +1 -0
- package/dist/mathCss-FLPE6QBM.js +361 -0
- package/dist/mathCss-FLPE6QBM.js.map +1 -0
- package/package.json +46 -3
- package/src/block-handle/BlockHandleController.ts +93 -0
- package/src/block-handle/BlockHandleHost.tsx +108 -0
- package/src/block-handle/DefaultBlockHandle.tsx +71 -0
- package/src/block-handle/DefaultBlockMenu.tsx +114 -0
- package/src/block-handle/DropIndicatorHost.tsx +58 -0
- package/src/block-handle/actions.tsx +146 -0
- package/src/block-handle/blockDrag.ts +215 -0
- package/src/block-handle/geometry.ts +64 -0
- package/src/block-handle/gripGesture.ts +108 -0
- package/src/block-handle/types.ts +65 -0
- package/src/block-handle/useBlockDrag.ts +21 -0
- package/src/block-handle/useBlockHandles.ts +125 -0
- package/src/blocks/BlockChildren.tsx +17 -0
- package/src/blocks/BlockProps.ts +5 -0
- package/src/blocks/CalloutBlock.tsx +61 -0
- package/src/blocks/CodeBlock.tsx +96 -0
- package/src/blocks/DividerBlock.tsx +15 -0
- package/src/blocks/Editable.tsx +84 -0
- package/src/blocks/FormulaBlock.tsx +173 -0
- package/src/blocks/HeadingBlock.tsx +22 -0
- package/src/blocks/ImageBlock.tsx +362 -0
- package/src/blocks/ListBlock.tsx +86 -0
- package/src/blocks/NoteBlock.tsx +10 -0
- package/src/blocks/PageBlock.tsx +10 -0
- package/src/blocks/ParagraphBlock.tsx +20 -0
- package/src/blocks/QuoteBlock.tsx +18 -0
- package/src/blocks/UnknownBlockView.tsx +27 -0
- package/src/blocks/defineBlock.ts +49 -0
- package/src/clipboard/html/blocks.ts +379 -0
- package/src/clipboard/html/inline.ts +92 -0
- package/src/clipboard/html/style.ts +92 -0
- package/src/clipboard/html/tags.ts +77 -0
- package/src/clipboard/htmlToFragment.ts +41 -0
- package/src/clipboard/useClipboard.ts +296 -0
- package/src/code/highlight.ts +56 -0
- package/src/code/languages.ts +236 -0
- package/src/code/scan/css.ts +164 -0
- package/src/code/scan/generic.ts +328 -0
- package/src/code/scan/html.ts +129 -0
- package/src/code/scan/markdown.ts +58 -0
- package/src/code/scan/shared.ts +81 -0
- package/src/code/scan/yaml.ts +34 -0
- package/src/code/types.ts +34 -0
- package/src/context/EditorContext.ts +9 -0
- package/src/context/EditorProvider.tsx +172 -0
- package/src/controllers/adapters.tsx +63 -0
- package/src/editing/BlockSelectionController.ts +27 -0
- package/src/editing/CaretController.ts +27 -0
- package/src/editing/EditorView.ts +108 -0
- package/src/editing/ViewportController.ts +63 -0
- package/src/editing/beforeInput.ts +276 -0
- package/src/editing/deleteAtBoundary.ts +16 -0
- package/src/editing/inputActions.ts +109 -0
- package/src/editing/renderCode.ts +69 -0
- package/src/editing/renderInline.ts +144 -0
- package/src/editing/selection.ts +262 -0
- package/src/editing/useEditorInput.ts +223 -0
- package/src/editing/useSelectionState.ts +46 -0
- package/src/formula/FormulaController.ts +51 -0
- package/src/formula/FormulaPalette.tsx +79 -0
- package/src/formula/FormulaPopover.tsx +181 -0
- package/src/formula/LazyFormulaPalette.tsx +42 -0
- package/src/formula/actions.ts +138 -0
- package/src/formula/snippet.ts +70 -0
- package/src/formula/symbols.ts +264 -0
- package/src/hooks/useBlock.ts +21 -0
- package/src/hooks/useBlockController.ts +30 -0
- package/src/hooks/useChildren.ts +16 -0
- package/src/hooks/useDocument.ts +16 -0
- package/src/hooks/useEditor.ts +13 -0
- package/src/hooks/useEditorView.ts +13 -0
- package/src/hooks/useHistory.ts +46 -0
- package/src/hooks/useReadOnly.ts +21 -0
- package/src/hooks/useT.ts +10 -0
- package/src/i18n/en.ts +182 -0
- package/src/i18n/ru.ts +174 -0
- package/src/i18n/translate.ts +77 -0
- package/src/icons/ICONS_LICENSE.md +50 -0
- package/src/icons/Icon.tsx +41 -0
- package/src/icons/lucide.ts +234 -0
- package/src/images/ImageError.ts +39 -0
- package/src/images/UploadTracker.ts +49 -0
- package/src/images/insertImages.ts +142 -0
- package/src/images/types.ts +22 -0
- package/src/images/upload.ts +62 -0
- package/src/index.ts +102 -0
- package/src/keymap/defaultKeymap.ts +189 -0
- package/src/keymap/keymap.ts +42 -0
- package/src/keymap/shortcut.ts +105 -0
- package/src/keymap/types.ts +40 -0
- package/src/math/FormulaView.tsx +62 -0
- package/src/math/mathCss.ts +4 -0
- package/src/math/renderer.ts +198 -0
- package/src/registry/defaultBlockComponents.ts +26 -0
- package/src/registry/resolveBlockComponent.ts +14 -0
- package/src/renderer/BlockRenderer.tsx +63 -0
- package/src/renderer/DocumentRenderer.tsx +33 -0
- package/src/renderer/DocumentView.tsx +94 -0
- package/src/renderer/virtual/VirtualChildList.tsx +355 -0
- package/src/renderer/virtual/estimate.ts +62 -0
- package/src/renderer/virtual/virtualRenderer.tsx +35 -0
- package/src/slash/DefaultSlashMenu.tsx +119 -0
- package/src/slash/SlashMenuController.ts +66 -0
- package/src/slash/SlashMenuHost.tsx +48 -0
- package/src/slash/applySlashItem.ts +57 -0
- package/src/slash/defaultSlashItems.tsx +186 -0
- package/src/slash/filter.ts +29 -0
- package/src/slash/items.ts +30 -0
- package/src/slash/syncSlashMenu.ts +67 -0
- package/src/slash/types.ts +21 -0
- package/src/toolbar/DefaultToolbar.tsx +281 -0
- package/src/toolbar/ToolbarController.ts +100 -0
- package/src/toolbar/ToolbarHost.tsx +81 -0
- package/src/toolbar/formatting.ts +75 -0
- package/src/toolbar/rich.ts +58 -0
- package/src/toolbar/syncToolbar.ts +39 -0
- package/src/toolbar/types.ts +21 -0
- package/src/ui/EditorUIContext.ts +26 -0
- package/src/ui/presentation.ts +24 -0
- package/src/ui/types.ts +70 -0
- package/README.md +0 -3
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import type { HighlightTokenType } from './types';
|
|
2
|
+
|
|
3
|
+
export interface LanguageDef {
|
|
4
|
+
keywords?: string;
|
|
5
|
+
types?: string;
|
|
6
|
+
builtins?: string;
|
|
7
|
+
constants?: string;
|
|
8
|
+
ignoreCase?: boolean;
|
|
9
|
+
lineComment?: readonly string[];
|
|
10
|
+
/** Строчный комментарий начинается только в начале слова (bash: `#`, но не `$#`). */
|
|
11
|
+
commentAtWordStart?: boolean;
|
|
12
|
+
blockComment?: readonly [string, string];
|
|
13
|
+
strings?: string;
|
|
14
|
+
multiline?: string;
|
|
15
|
+
triple?: boolean;
|
|
16
|
+
stringPrefixes?: boolean;
|
|
17
|
+
stringKeys?: boolean;
|
|
18
|
+
regex?: boolean;
|
|
19
|
+
preprocessor?: boolean;
|
|
20
|
+
rustAttributes?: boolean;
|
|
21
|
+
lifetimes?: boolean;
|
|
22
|
+
at?: boolean;
|
|
23
|
+
dollar?: boolean;
|
|
24
|
+
flags?: boolean;
|
|
25
|
+
macros?: boolean;
|
|
26
|
+
pascalTypes?: boolean;
|
|
27
|
+
declarations?: Readonly<Record<string, HighlightTokenType>>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const JS_KEYWORDS =
|
|
31
|
+
'break case catch class const continue debugger default delete do else enum export extends finally for function if import in instanceof let new of return static super switch this throw try typeof var void while with yield async await from as implements interface package private protected public readonly abstract declare namespace keyof satisfies override';
|
|
32
|
+
|
|
33
|
+
const JS_DECLARATIONS = {
|
|
34
|
+
function: 'function',
|
|
35
|
+
class: 'type',
|
|
36
|
+
interface: 'type',
|
|
37
|
+
enum: 'type',
|
|
38
|
+
namespace: 'type',
|
|
39
|
+
} as const;
|
|
40
|
+
|
|
41
|
+
const javascript: LanguageDef = {
|
|
42
|
+
keywords: JS_KEYWORDS,
|
|
43
|
+
constants: 'true false null undefined NaN Infinity',
|
|
44
|
+
builtins:
|
|
45
|
+
'console window document Math JSON Object Array String Number Boolean Promise Map Set WeakMap Date Error RegExp Symbol parseInt parseFloat require module exports process globalThis',
|
|
46
|
+
lineComment: ['//'],
|
|
47
|
+
blockComment: ['/*', '*/'],
|
|
48
|
+
strings: '\'"`',
|
|
49
|
+
multiline: '`',
|
|
50
|
+
regex: true,
|
|
51
|
+
at: true,
|
|
52
|
+
pascalTypes: true,
|
|
53
|
+
declarations: JS_DECLARATIONS,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const typescript: LanguageDef = {
|
|
57
|
+
...javascript,
|
|
58
|
+
types:
|
|
59
|
+
'string number boolean any unknown never void object bigint symbol Record Partial Required Readonly Pick Omit Awaited ReturnType',
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const python: LanguageDef = {
|
|
63
|
+
keywords:
|
|
64
|
+
'and as assert async await break class continue def del elif else except finally for from global if import in is lambda nonlocal not or pass raise return try while with yield match case',
|
|
65
|
+
constants: 'True False None',
|
|
66
|
+
builtins:
|
|
67
|
+
'print len range int str float bool list dict set tuple type isinstance open enumerate zip map filter sorted sum min max abs any all input super self cls object Exception',
|
|
68
|
+
lineComment: ['#'],
|
|
69
|
+
strings: '\'"',
|
|
70
|
+
triple: true,
|
|
71
|
+
stringPrefixes: true,
|
|
72
|
+
at: true,
|
|
73
|
+
pascalTypes: true,
|
|
74
|
+
declarations: { def: 'function', class: 'type' },
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const go: LanguageDef = {
|
|
78
|
+
keywords:
|
|
79
|
+
'break case chan const continue default defer else fallthrough for func go goto if import interface map package range return select struct switch type var',
|
|
80
|
+
types:
|
|
81
|
+
'bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr any',
|
|
82
|
+
constants: 'true false nil iota',
|
|
83
|
+
builtins: 'append cap close copy delete len make new panic print println recover',
|
|
84
|
+
lineComment: ['//'],
|
|
85
|
+
blockComment: ['/*', '*/'],
|
|
86
|
+
strings: '\'"`',
|
|
87
|
+
multiline: '`',
|
|
88
|
+
pascalTypes: true,
|
|
89
|
+
declarations: { func: 'function', type: 'type' },
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const rust: LanguageDef = {
|
|
93
|
+
keywords:
|
|
94
|
+
'as async await break const continue crate dyn else enum extern fn for if impl in let loop match mod move mut pub ref return self Self static struct super trait type unsafe use where while',
|
|
95
|
+
types:
|
|
96
|
+
'i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 bool char str String Vec Option Result Box Rc Arc',
|
|
97
|
+
constants: 'true false None Some Ok Err',
|
|
98
|
+
lineComment: ['//'],
|
|
99
|
+
blockComment: ['/*', '*/'],
|
|
100
|
+
strings: '"',
|
|
101
|
+
multiline: '"',
|
|
102
|
+
rustAttributes: true,
|
|
103
|
+
lifetimes: true,
|
|
104
|
+
macros: true,
|
|
105
|
+
pascalTypes: true,
|
|
106
|
+
declarations: { fn: 'function', struct: 'type', enum: 'type', trait: 'type', impl: 'type' },
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const java: LanguageDef = {
|
|
110
|
+
keywords:
|
|
111
|
+
'abstract assert break case catch class continue default do else enum extends final finally for if implements import instanceof interface native new package private protected public return static strictfp super switch synchronized this throw throws transient try void volatile while var record sealed permits',
|
|
112
|
+
types:
|
|
113
|
+
'boolean byte char double float int long short String Integer Long Double Boolean Object List Map Set',
|
|
114
|
+
constants: 'true false null',
|
|
115
|
+
lineComment: ['//'],
|
|
116
|
+
blockComment: ['/*', '*/'],
|
|
117
|
+
strings: '\'"',
|
|
118
|
+
at: true,
|
|
119
|
+
pascalTypes: true,
|
|
120
|
+
declarations: { class: 'type', interface: 'type', enum: 'type', record: 'type' },
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const C_KEYWORDS =
|
|
124
|
+
'auto break case const continue default do else enum extern for goto if inline register restrict return sizeof static struct switch typedef union volatile while';
|
|
125
|
+
|
|
126
|
+
const c: LanguageDef = {
|
|
127
|
+
keywords: C_KEYWORDS,
|
|
128
|
+
types:
|
|
129
|
+
'void char short int long float double signed unsigned size_t bool _Bool int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t FILE',
|
|
130
|
+
constants: 'NULL true false EOF',
|
|
131
|
+
lineComment: ['//'],
|
|
132
|
+
blockComment: ['/*', '*/'],
|
|
133
|
+
strings: '\'"',
|
|
134
|
+
preprocessor: true,
|
|
135
|
+
declarations: { struct: 'type', enum: 'type', union: 'type' },
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const cpp: LanguageDef = {
|
|
139
|
+
...c,
|
|
140
|
+
keywords: `${C_KEYWORDS} class namespace template typename public private protected virtual override final new delete this using try catch throw operator constexpr noexcept static_cast dynamic_cast reinterpret_cast const_cast explicit friend mutable decltype`,
|
|
141
|
+
types: `${c.types} string vector map set unique_ptr shared_ptr std`,
|
|
142
|
+
constants: 'NULL nullptr true false EOF',
|
|
143
|
+
pascalTypes: true,
|
|
144
|
+
declarations: { class: 'type', struct: 'type', enum: 'type', namespace: 'type', union: 'type' },
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const bash: LanguageDef = {
|
|
148
|
+
keywords:
|
|
149
|
+
'if then else elif fi for while until do done case esac in function select time return exit break continue export local readonly declare unset source alias set shift',
|
|
150
|
+
builtins:
|
|
151
|
+
'echo cd ls pwd cat grep sed awk rm cp mv mkdir touch chmod chown curl wget git npm pnpm yarn node python docker sudo kill ps tar test read printf eval exec trap true false',
|
|
152
|
+
lineComment: ['#'],
|
|
153
|
+
commentAtWordStart: true,
|
|
154
|
+
strings: '\'"`',
|
|
155
|
+
multiline: '\'"`',
|
|
156
|
+
dollar: true,
|
|
157
|
+
flags: true,
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const sql: LanguageDef = {
|
|
161
|
+
ignoreCase: true,
|
|
162
|
+
keywords:
|
|
163
|
+
'select from where and or not in is like between exists distinct as join inner left right full outer cross on using group by order having limit offset union all insert into values update set delete create alter drop table index view database schema primary key foreign references unique default check constraint add column case when then else end begin commit rollback transaction with returning asc desc if cascade truncate grant revoke',
|
|
164
|
+
types:
|
|
165
|
+
'int integer bigint smallint tinyint varchar char text boolean bool date time timestamp datetime numeric decimal float double real serial uuid json jsonb blob',
|
|
166
|
+
constants: 'true false null',
|
|
167
|
+
builtins:
|
|
168
|
+
'count sum avg min max coalesce now cast length lower upper trim round abs concat substring',
|
|
169
|
+
lineComment: ['--'],
|
|
170
|
+
blockComment: ['/*', '*/'],
|
|
171
|
+
strings: '\'"',
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const json: LanguageDef = {
|
|
175
|
+
constants: 'true false null',
|
|
176
|
+
lineComment: ['//'],
|
|
177
|
+
blockComment: ['/*', '*/'],
|
|
178
|
+
strings: '"',
|
|
179
|
+
stringKeys: true,
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const yaml: LanguageDef = {
|
|
183
|
+
constants: 'true false null yes no on off ~ True False Null',
|
|
184
|
+
lineComment: ['#'],
|
|
185
|
+
commentAtWordStart: true,
|
|
186
|
+
strings: '\'"',
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const LANGUAGES: Readonly<Record<string, LanguageDef>> = {
|
|
190
|
+
javascript,
|
|
191
|
+
typescript,
|
|
192
|
+
python,
|
|
193
|
+
go,
|
|
194
|
+
rust,
|
|
195
|
+
java,
|
|
196
|
+
c,
|
|
197
|
+
cpp,
|
|
198
|
+
bash,
|
|
199
|
+
sql,
|
|
200
|
+
json,
|
|
201
|
+
yaml,
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
export const ALIASES: Readonly<Record<string, string>> = {
|
|
205
|
+
js: 'javascript',
|
|
206
|
+
jsx: 'javascript',
|
|
207
|
+
mjs: 'javascript',
|
|
208
|
+
cjs: 'javascript',
|
|
209
|
+
ts: 'typescript',
|
|
210
|
+
tsx: 'typescript',
|
|
211
|
+
py: 'python',
|
|
212
|
+
golang: 'go',
|
|
213
|
+
rs: 'rust',
|
|
214
|
+
sh: 'bash',
|
|
215
|
+
shell: 'bash',
|
|
216
|
+
zsh: 'bash',
|
|
217
|
+
console: 'bash',
|
|
218
|
+
'c++': 'cpp',
|
|
219
|
+
cc: 'cpp',
|
|
220
|
+
cxx: 'cpp',
|
|
221
|
+
hpp: 'cpp',
|
|
222
|
+
h: 'c',
|
|
223
|
+
jsonc: 'json',
|
|
224
|
+
json5: 'json',
|
|
225
|
+
yml: 'yaml',
|
|
226
|
+
md: 'markdown',
|
|
227
|
+
xml: 'html',
|
|
228
|
+
svg: 'html',
|
|
229
|
+
htm: 'html',
|
|
230
|
+
scss: 'css',
|
|
231
|
+
less: 'css',
|
|
232
|
+
postgres: 'sql',
|
|
233
|
+
postgresql: 'sql',
|
|
234
|
+
mysql: 'sql',
|
|
235
|
+
sqlite: 'sql',
|
|
236
|
+
};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { type Emit, isDigit, isSpace, matchAt, nextOnLine, scanString } from './shared';
|
|
2
|
+
|
|
3
|
+
export function scanCss(code: string, start: number, end: number, emit: Emit) {
|
|
4
|
+
let i = start;
|
|
5
|
+
let depth = 0;
|
|
6
|
+
let expectProperty = false;
|
|
7
|
+
|
|
8
|
+
while (i < end) {
|
|
9
|
+
const char = code[i];
|
|
10
|
+
|
|
11
|
+
if (isSpace(char)) {
|
|
12
|
+
i++;
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (code.startsWith('/*', i)) {
|
|
17
|
+
const close = code.indexOf('*/', i + 2);
|
|
18
|
+
const stop = close < 0 || close + 2 > end ? end : close + 2;
|
|
19
|
+
|
|
20
|
+
emit(i, stop, 'comment');
|
|
21
|
+
i = stop;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (char === '"' || char === "'") {
|
|
26
|
+
const stop = scanString(code, i, end, char, false, false);
|
|
27
|
+
|
|
28
|
+
emit(i, stop, 'string');
|
|
29
|
+
i = stop;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (char === '{') {
|
|
34
|
+
depth++;
|
|
35
|
+
expectProperty = true;
|
|
36
|
+
i++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (char === '}') {
|
|
41
|
+
depth = Math.max(0, depth - 1);
|
|
42
|
+
expectProperty = depth > 0;
|
|
43
|
+
i++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (char === ';') {
|
|
48
|
+
expectProperty = depth > 0;
|
|
49
|
+
i++;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (char === '@') {
|
|
54
|
+
const name = matchAt(/@[\w-]+/y, code, i);
|
|
55
|
+
|
|
56
|
+
if (name) {
|
|
57
|
+
emit(i, i + name.length, 'keyword');
|
|
58
|
+
i += name.length;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const inValue = depth > 0 && !expectProperty;
|
|
64
|
+
|
|
65
|
+
if (inValue) {
|
|
66
|
+
const hex = matchAt(/#[\da-fA-F]{3,8}\b/y, code, i);
|
|
67
|
+
|
|
68
|
+
if (hex) {
|
|
69
|
+
emit(i, i + hex.length, 'number');
|
|
70
|
+
i += hex.length;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const number = matchAt(/-?(?:\d+\.?\d*|\.\d+)(?:%|[a-zA-Z]+)?/y, code, i);
|
|
75
|
+
|
|
76
|
+
if (number && (isDigit(char) || char === '.' || char === '-')) {
|
|
77
|
+
emit(i, i + number.length, 'number');
|
|
78
|
+
i += number.length;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (code.startsWith('!important', i)) {
|
|
83
|
+
emit(i, i + 10, 'keyword');
|
|
84
|
+
i += 10;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const word = matchAt(/[A-Za-z_-][\w-]*/y, code, i);
|
|
89
|
+
|
|
90
|
+
if (word) {
|
|
91
|
+
if (code[nextOnLine(code, i + word.length, end)] === '(')
|
|
92
|
+
emit(i, i + word.length, 'function');
|
|
93
|
+
i += word.length;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
i++;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (depth > 0 && expectProperty) {
|
|
102
|
+
const property = matchAt(/-{0,2}[A-Za-z_][\w-]*(?=\s*:(?!:))/y, code, i);
|
|
103
|
+
|
|
104
|
+
if (property && !isNestedSelector(code, i + property.length, end)) {
|
|
105
|
+
emit(i, i + property.length, 'property');
|
|
106
|
+
i += property.length;
|
|
107
|
+
expectProperty = false;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const classOrId = matchAt(/[.#][\w-]+/y, code, i);
|
|
113
|
+
|
|
114
|
+
if (classOrId) {
|
|
115
|
+
emit(i, i + classOrId.length, 'function');
|
|
116
|
+
i += classOrId.length;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const pseudo = matchAt(/::?[\w-]+/y, code, i);
|
|
121
|
+
|
|
122
|
+
if (pseudo) {
|
|
123
|
+
emit(i, i + pseudo.length, 'keyword');
|
|
124
|
+
i += pseudo.length;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (char === '[') {
|
|
129
|
+
const close = code.indexOf(']', i);
|
|
130
|
+
const stop = close < 0 || close >= end ? end : close + 1;
|
|
131
|
+
|
|
132
|
+
emit(i, stop, 'attribute');
|
|
133
|
+
i = stop;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const tag = matchAt(/[A-Za-z][\w-]*/y, code, i);
|
|
138
|
+
|
|
139
|
+
if (tag) {
|
|
140
|
+
emit(i, i + tag.length, 'tag');
|
|
141
|
+
i += tag.length;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
i++;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function isNestedSelector(code: string, from: number, end: number): boolean {
|
|
150
|
+
const colon = code.indexOf(':', from);
|
|
151
|
+
|
|
152
|
+
if (colon < 0 || colon >= end) return false;
|
|
153
|
+
|
|
154
|
+
const brace = code.indexOf('{', colon);
|
|
155
|
+
const semicolon = code.indexOf(';', colon);
|
|
156
|
+
const newline = code.indexOf('\n', colon);
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
brace >= 0 &&
|
|
160
|
+
brace < end &&
|
|
161
|
+
(semicolon < 0 || brace < semicolon) &&
|
|
162
|
+
(newline < 0 || brace < newline)
|
|
163
|
+
);
|
|
164
|
+
}
|