1 /*
2 * This file is part of LibCSS.
3 * Licensed under the MIT License,
4 * http://www.opensource.org/licenses/mit-license.php
5 * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
6 */
7
8 #include <assert.h>
9
10 #include "bytecode/bytecode.h"
11 #include "bytecode/opcodes.h"
12 #include "parse/important.h"
13
14 /**
15 * Parse !important
16 *
17 * \param c Parsing context
18 * \param vector Vector of tokens to process
19 * \param ctx Pointer to vector iteration context
20 * \param result Pointer to location to receive result
21 * \return CSS_OK on success,
22 * CSS_INVALID if "S* ! S* important" is not at the start of the vector
23 *
24 * Post condition: \a *ctx is updated with the next token to process
25 * If the input is invalid, then \a *ctx remains unchanged.
26 */
css__parse_important(css_language * c,const parserutils_vector * vector,int * ctx,uint8_t * result)27 css_error css__parse_important(css_language *c,
28 const parserutils_vector *vector, int *ctx,
29 uint8_t *result)
30 {
31 int orig_ctx = *ctx;
32 bool match = false;
33 const css_token *token;
34
35 consumeWhitespace(vector, ctx);
36
37 token = parserutils_vector_iterate(vector, ctx);
38 if (token != NULL && tokenIsChar(token, '!')) {
39 consumeWhitespace(vector, ctx);
40
41 token = parserutils_vector_iterate(vector, ctx);
42 if (token == NULL || token->type != CSS_TOKEN_IDENT) {
43 *ctx = orig_ctx;
44 return CSS_INVALID;
45 }
46
47 if (lwc_string_caseless_isequal(token->idata, c->strings[IMPORTANT],
48 &match) == lwc_error_ok && match) {
49 *result |= FLAG_IMPORTANT;
50 } else {
51 *ctx = orig_ctx;
52 return CSS_INVALID;
53 }
54 } else if (token != NULL) {
55 *ctx = orig_ctx;
56 return CSS_INVALID;
57 }
58
59 return CSS_OK;
60 }
61
62 /**
63 * Make a style important
64 *
65 * \param style The style to modify
66 */
css__make_style_important(css_style * style)67 void css__make_style_important(css_style *style)
68 {
69 css_code_t *bytecode = style->bytecode;
70 uint32_t length = style->used;
71 uint32_t offset = 0;
72
73 while (offset < length) {
74 opcode_t op;
75 uint8_t flags;
76 uint32_t value;
77 css_code_t opv = bytecode[offset];
78
79 /* Extract opv components, setting important flag */
80 op = getOpcode(opv);
81 flags = getFlags(opv) | FLAG_IMPORTANT;
82 value = getValue(opv);
83
84 /* Write OPV back to bytecode */
85 bytecode[offset] = buildOPV(op, flags, value);
86
87 offset++;
88
89 /* Advance past any property-specific data */
90 if (isInherit(opv) == false) {
91 switch (op) {
92 case CSS_PROP_AZIMUTH:
93 if ((value & ~AZIMUTH_BEHIND) == AZIMUTH_ANGLE)
94 offset += 2; /* length + units */
95 break;
96
97 case CSS_PROP_BORDER_TOP_COLOR:
98 case CSS_PROP_BORDER_RIGHT_COLOR:
99 case CSS_PROP_BORDER_BOTTOM_COLOR:
100 case CSS_PROP_BORDER_LEFT_COLOR:
101 case CSS_PROP_BACKGROUND_COLOR:
102 case CSS_PROP_COLUMN_RULE_COLOR:
103 assert(BACKGROUND_COLOR_SET ==
104 (enum op_background_color)BORDER_COLOR_SET);
105 assert(BACKGROUND_COLOR_SET ==
106 (enum op_background_color)COLUMN_RULE_COLOR_SET);
107
108 if (value == BACKGROUND_COLOR_SET)
109 offset++; /* colour */
110 break;
111
112 case CSS_PROP_BACKGROUND_IMAGE:
113 case CSS_PROP_CUE_AFTER:
114 case CSS_PROP_CUE_BEFORE:
115 case CSS_PROP_LIST_STYLE_IMAGE:
116 assert(BACKGROUND_IMAGE_URI ==
117 (enum op_background_image)CUE_AFTER_URI);
118 assert(BACKGROUND_IMAGE_URI ==
119 (enum op_background_image)CUE_BEFORE_URI);
120 assert(BACKGROUND_IMAGE_URI ==
121 (enum op_background_image)LIST_STYLE_IMAGE_URI);
122
123 if (value == BACKGROUND_IMAGE_URI)
124 offset++; /* string table entry */
125 break;
126
127 case CSS_PROP_BACKGROUND_POSITION:
128 if ((value & 0xf0) == BACKGROUND_POSITION_HORZ_SET)
129 offset += 2; /* length + units */
130
131 if ((value & 0x0f) == BACKGROUND_POSITION_VERT_SET)
132 offset += 2; /* length + units */
133 break;
134
135 case CSS_PROP_BORDER_SPACING:
136 if (value == BORDER_SPACING_SET)
137 offset += 4; /* two length + units */
138 break;
139
140 case CSS_PROP_BORDER_TOP_WIDTH:
141 case CSS_PROP_BORDER_RIGHT_WIDTH:
142 case CSS_PROP_BORDER_BOTTOM_WIDTH:
143 case CSS_PROP_BORDER_LEFT_WIDTH:
144 case CSS_PROP_OUTLINE_WIDTH:
145 case CSS_PROP_COLUMN_RULE_WIDTH:
146 assert(BORDER_WIDTH_SET ==
147 (enum op_border_width)OUTLINE_WIDTH_SET);
148 assert(BORDER_WIDTH_SET ==
149 (enum op_border_width)COLUMN_RULE_WIDTH_SET);
150
151 if (value == BORDER_WIDTH_SET)
152 offset += 2; /* length + units */
153 break;
154
155 case CSS_PROP_MARGIN_TOP:
156 case CSS_PROP_MARGIN_RIGHT:
157 case CSS_PROP_MARGIN_BOTTOM:
158 case CSS_PROP_MARGIN_LEFT:
159 case CSS_PROP_BOTTOM:
160 case CSS_PROP_LEFT:
161 case CSS_PROP_RIGHT:
162 case CSS_PROP_TOP:
163 case CSS_PROP_HEIGHT:
164 case CSS_PROP_WIDTH:
165 case CSS_PROP_COLUMN_WIDTH:
166 case CSS_PROP_COLUMN_GAP:
167 assert(BOTTOM_SET == (enum op_bottom)LEFT_SET);
168 assert(BOTTOM_SET == (enum op_bottom)RIGHT_SET);
169 assert(BOTTOM_SET == (enum op_bottom)TOP_SET);
170 assert(BOTTOM_SET == (enum op_bottom)HEIGHT_SET);
171 assert(BOTTOM_SET == (enum op_bottom)MARGIN_SET);
172 assert(BOTTOM_SET == (enum op_bottom)WIDTH_SET);
173 assert(BOTTOM_SET == (enum op_bottom)COLUMN_WIDTH_SET);
174 assert(BOTTOM_SET == (enum op_bottom)COLUMN_GAP_SET);
175
176 if (value == BOTTOM_SET)
177 offset += 2; /* length + units */
178 break;
179
180 case CSS_PROP_CLIP:
181 if ((value & CLIP_SHAPE_MASK) == CLIP_SHAPE_RECT) {
182 if ((value & CLIP_RECT_TOP_AUTO) == 0)
183 offset += 2; /* length + units */
184
185 if ((value & CLIP_RECT_RIGHT_AUTO) == 0)
186 offset += 2; /* length + units */
187
188 if ((value & CLIP_RECT_BOTTOM_AUTO) == 0)
189 offset += 2; /* length + units */
190
191 if ((value & CLIP_RECT_LEFT_AUTO) == 0)
192 offset += 2; /* length + units */
193
194 }
195 break;
196
197 case CSS_PROP_COLOR:
198 if (value == COLOR_SET)
199 offset++; /* colour */
200 break;
201
202 case CSS_PROP_COLUMN_COUNT:
203 if (value == COLUMN_COUNT_SET)
204 offset++; /* colour */
205 break;
206
207 case CSS_PROP_CONTENT:
208 while (value != CONTENT_NORMAL &&
209 value != CONTENT_NONE) {
210 switch (value & 0xff) {
211 case CONTENT_COUNTER:
212 case CONTENT_URI:
213 case CONTENT_ATTR:
214 case CONTENT_STRING:
215 offset++; /* string table entry */
216 break;
217
218 case CONTENT_COUNTERS:
219 offset+=2; /* two string entries */
220 break;
221
222 case CONTENT_OPEN_QUOTE:
223 case CONTENT_CLOSE_QUOTE:
224 case CONTENT_NO_OPEN_QUOTE:
225 case CONTENT_NO_CLOSE_QUOTE:
226 break;
227 }
228
229 value = bytecode[offset];
230 offset++;
231 }
232 break;
233
234 case CSS_PROP_COUNTER_INCREMENT:
235 case CSS_PROP_COUNTER_RESET:
236 assert(COUNTER_INCREMENT_NONE ==
237 (enum op_counter_increment)COUNTER_RESET_NONE);
238
239 while (value != COUNTER_INCREMENT_NONE) {
240 offset+=2; /* string + integer */
241
242 value = bytecode[offset];
243 offset++;
244 }
245 break;
246
247 case CSS_PROP_CURSOR:
248 while (value == CURSOR_URI) {
249 offset++; /* string table entry */
250
251 value = bytecode[offset];
252 offset++;
253 }
254 break;
255
256 case CSS_PROP_ELEVATION:
257 if (value == ELEVATION_ANGLE)
258 offset += 2; /* length + units */
259 break;
260
261 case CSS_PROP_FLEX_BASIS:
262 if (value == FLEX_BASIS_SET)
263 offset += 2; /* length + units */
264 break;
265
266 case CSS_PROP_FLEX_GROW:
267 if (value == FLEX_GROW_SET)
268 offset++; /* value */
269 break;
270
271 case CSS_PROP_FLEX_SHRINK:
272 if (value == FLEX_SHRINK_SET)
273 offset++; /* value */
274 break;
275
276 case CSS_PROP_FONT_FAMILY:
277 while (value != FONT_FAMILY_END) {
278 switch (value) {
279 case FONT_FAMILY_STRING:
280 case FONT_FAMILY_IDENT_LIST:
281 offset++; /* string table entry */
282 break;
283 }
284
285 value = bytecode[offset];
286 offset++;
287 }
288 break;
289
290 case CSS_PROP_FONT_SIZE:
291 if (value == FONT_SIZE_DIMENSION)
292 offset += 2; /* length + units */
293 break;
294
295 case CSS_PROP_LETTER_SPACING:
296 case CSS_PROP_WORD_SPACING:
297 assert(LETTER_SPACING_SET ==
298 (enum op_letter_spacing)WORD_SPACING_SET);
299
300 if (value == LETTER_SPACING_SET)
301 offset += 2; /* length + units */
302 break;
303
304 case CSS_PROP_LINE_HEIGHT:
305 switch (value) {
306 case LINE_HEIGHT_NUMBER:
307 offset++; /* value */
308 break;
309
310 case LINE_HEIGHT_DIMENSION:
311 offset += 2; /* length + units */
312 break;
313 }
314 break;
315
316 case CSS_PROP_MAX_HEIGHT:
317 case CSS_PROP_MAX_WIDTH:
318 assert(MAX_HEIGHT_SET ==
319 (enum op_max_height)MAX_WIDTH_SET);
320
321 if (value == MAX_HEIGHT_SET)
322 offset += 2; /* length + units */
323 break;
324
325 case CSS_PROP_PADDING_TOP:
326 case CSS_PROP_PADDING_RIGHT:
327 case CSS_PROP_PADDING_BOTTOM:
328 case CSS_PROP_PADDING_LEFT:
329 case CSS_PROP_MIN_HEIGHT:
330 case CSS_PROP_MIN_WIDTH:
331 case CSS_PROP_PAUSE_AFTER:
332 case CSS_PROP_PAUSE_BEFORE:
333 case CSS_PROP_TEXT_INDENT:
334 assert(MIN_HEIGHT_SET == (enum op_min_height)MIN_WIDTH_SET);
335 assert(MIN_HEIGHT_SET == (enum op_min_height)PADDING_SET);
336 assert(MIN_HEIGHT_SET == (enum op_min_height)PAUSE_AFTER_SET);
337 assert(MIN_HEIGHT_SET == (enum op_min_height)PAUSE_BEFORE_SET);
338 assert(MIN_HEIGHT_SET == (enum op_min_height)TEXT_INDENT_SET);
339
340 if (value == MIN_HEIGHT_SET)
341 offset += 2; /* length + units */
342 break;
343
344 case CSS_PROP_OPACITY:
345 if (value == OPACITY_SET)
346 offset++; /* value */
347 break;
348
349 case CSS_PROP_ORDER:
350 if (value == ORDER_SET)
351 offset++; /* value */
352 break;
353
354 case CSS_PROP_ORPHANS:
355 case CSS_PROP_PITCH_RANGE:
356 case CSS_PROP_RICHNESS:
357 case CSS_PROP_STRESS:
358 case CSS_PROP_WIDOWS:
359 assert(ORPHANS_SET == (enum op_orphans)PITCH_RANGE_SET);
360 assert(ORPHANS_SET == (enum op_orphans)RICHNESS_SET);
361 assert(ORPHANS_SET == (enum op_orphans)STRESS_SET);
362 assert(ORPHANS_SET == (enum op_orphans)WIDOWS_SET);
363
364 if (value == ORPHANS_SET)
365 offset++; /* value */
366 break;
367
368 case CSS_PROP_OUTLINE_COLOR:
369 if (value == OUTLINE_COLOR_SET)
370 offset++; /* color */
371 break;
372
373 case CSS_PROP_PITCH:
374 if (value == PITCH_FREQUENCY)
375 offset += 2; /* length + units */
376 break;
377
378 case CSS_PROP_PLAY_DURING:
379 if (value & PLAY_DURING_URI)
380 offset++; /* string table entry */
381 break;
382
383 case CSS_PROP_QUOTES:
384 while (value != QUOTES_NONE) {
385 offset += 2; /* two string table entries */
386
387 value = bytecode[offset];
388 offset++;
389 }
390 break;
391
392 case CSS_PROP_SPEECH_RATE:
393 if (value == SPEECH_RATE_SET)
394 offset++; /* rate */
395 break;
396
397 case CSS_PROP_VERTICAL_ALIGN:
398 if (value == VERTICAL_ALIGN_SET)
399 offset += 2; /* length + units */
400 break;
401
402 case CSS_PROP_VOICE_FAMILY:
403 while (value != VOICE_FAMILY_END) {
404 switch (value) {
405 case VOICE_FAMILY_STRING:
406 case VOICE_FAMILY_IDENT_LIST:
407 offset++; /* string table entry */
408 break;
409 }
410
411 value = bytecode[offset];
412 offset++;
413 }
414 break;
415
416 case CSS_PROP_VOLUME:
417 switch (value) {
418 case VOLUME_NUMBER:
419 offset++; /* value */
420 break;
421
422 case VOLUME_DIMENSION:
423 offset += 2; /* value + units */
424 break;
425 }
426 break;
427
428 case CSS_PROP_Z_INDEX:
429 if (value == Z_INDEX_SET)
430 offset++; /* z index */
431 break;
432
433 default:
434 break;
435 }
436 }
437 }
438
439 }
440
441