source: imaps-frontend/node_modules/css-tree/lib/syntax/node/UnicodeRange.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 4.9 KB
Line 
1var isHexDigit = require('../../tokenizer').isHexDigit;
2var cmpChar = require('../../tokenizer').cmpChar;
3var TYPE = require('../../tokenizer').TYPE;
4var NAME = require('../../tokenizer').NAME;
5
6var IDENT = TYPE.Ident;
7var NUMBER = TYPE.Number;
8var DIMENSION = TYPE.Dimension;
9var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
10var HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
11var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
12var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
13
14function eatHexSequence(offset, allowDash) {
15 for (var pos = this.scanner.tokenStart + offset, len = 0; pos < this.scanner.tokenEnd; pos++) {
16 var code = this.scanner.source.charCodeAt(pos);
17
18 if (code === HYPHENMINUS && allowDash && len !== 0) {
19 if (eatHexSequence.call(this, offset + len + 1, false) === 0) {
20 this.error();
21 }
22
23 return -1;
24 }
25
26 if (!isHexDigit(code)) {
27 this.error(
28 allowDash && len !== 0
29 ? 'HyphenMinus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
30 : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
31 pos
32 );
33 }
34
35 if (++len > 6) {
36 this.error('Too many hex digits', pos);
37 };
38 }
39
40 this.scanner.next();
41 return len;
42}
43
44function eatQuestionMarkSequence(max) {
45 var count = 0;
46
47 while (this.scanner.isDelim(QUESTIONMARK)) {
48 if (++count > max) {
49 this.error('Too many question marks');
50 }
51
52 this.scanner.next();
53 }
54}
55
56function startsWith(code) {
57 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== code) {
58 this.error(NAME[code] + ' is expected');
59 }
60}
61
62// https://drafts.csswg.org/css-syntax/#urange
63// Informally, the <urange> production has three forms:
64// U+0001
65// Defines a range consisting of a single code point, in this case the code point "1".
66// U+0001-00ff
67// Defines a range of codepoints between the first and the second value, in this case
68// the range between "1" and "ff" (255 in decimal) inclusive.
69// U+00??
70// Defines a range of codepoints where the "?" characters range over all hex digits,
71// in this case defining the same as the value U+0000-00ff.
72// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
73//
74// <urange> =
75// u '+' <ident-token> '?'* |
76// u <dimension-token> '?'* |
77// u <number-token> '?'* |
78// u <number-token> <dimension-token> |
79// u <number-token> <number-token> |
80// u '+' '?'+
81function scanUnicodeRange() {
82 var hexLength = 0;
83
84 // u '+' <ident-token> '?'*
85 // u '+' '?'+
86 if (this.scanner.isDelim(PLUSSIGN)) {
87 this.scanner.next();
88
89 if (this.scanner.tokenType === IDENT) {
90 hexLength = eatHexSequence.call(this, 0, true);
91 if (hexLength > 0) {
92 eatQuestionMarkSequence.call(this, 6 - hexLength);
93 }
94 return;
95 }
96
97 if (this.scanner.isDelim(QUESTIONMARK)) {
98 this.scanner.next();
99 eatQuestionMarkSequence.call(this, 5);
100 return;
101 }
102
103 this.error('Hex digit or question mark is expected');
104 return;
105 }
106
107 // u <number-token> '?'*
108 // u <number-token> <dimension-token>
109 // u <number-token> <number-token>
110 if (this.scanner.tokenType === NUMBER) {
111 startsWith.call(this, PLUSSIGN);
112 hexLength = eatHexSequence.call(this, 1, true);
113
114 if (this.scanner.isDelim(QUESTIONMARK)) {
115 eatQuestionMarkSequence.call(this, 6 - hexLength);
116 return;
117 }
118
119 if (this.scanner.tokenType === DIMENSION ||
120 this.scanner.tokenType === NUMBER) {
121 startsWith.call(this, HYPHENMINUS);
122 eatHexSequence.call(this, 1, false);
123 return;
124 }
125
126 return;
127 }
128
129 // u <dimension-token> '?'*
130 if (this.scanner.tokenType === DIMENSION) {
131 startsWith.call(this, PLUSSIGN);
132 hexLength = eatHexSequence.call(this, 1, true);
133
134 if (hexLength > 0) {
135 eatQuestionMarkSequence.call(this, 6 - hexLength);
136 }
137
138 return;
139 }
140
141 this.error();
142}
143
144module.exports = {
145 name: 'UnicodeRange',
146 structure: {
147 value: String
148 },
149 parse: function() {
150 var start = this.scanner.tokenStart;
151
152 // U or u
153 if (!cmpChar(this.scanner.source, start, U)) {
154 this.error('U is expected');
155 }
156
157 if (!cmpChar(this.scanner.source, start + 1, PLUSSIGN)) {
158 this.error('Plus sign is expected');
159 }
160
161 this.scanner.next();
162 scanUnicodeRange.call(this);
163
164 return {
165 type: 'UnicodeRange',
166 loc: this.getLocation(start, this.scanner.tokenStart),
167 value: this.scanner.substrToCursor(start)
168 };
169 },
170 generate: function(node) {
171 this.chunk(node.value);
172 }
173};
Note: See TracBrowser for help on using the repository browser.