Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.  */
  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.  */
  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_FONT_FAMILY:
  262.                                 while (value != FONT_FAMILY_END) {
  263.                                         switch (value) {
  264.                                         case FONT_FAMILY_STRING:
  265.                                         case FONT_FAMILY_IDENT_LIST:
  266.                                                 offset++; /* string table entry */
  267.                                                 break;
  268.                                         }
  269.  
  270.                                         value = bytecode[offset];
  271.                                         offset++;
  272.                                 }
  273.                                 break;
  274.  
  275.                         case CSS_PROP_FONT_SIZE:
  276.                                 if (value == FONT_SIZE_DIMENSION)
  277.                                         offset += 2; /* length + units */
  278.                                 break;
  279.  
  280.                         case CSS_PROP_LETTER_SPACING:
  281.                         case CSS_PROP_WORD_SPACING:
  282.                                 assert(LETTER_SPACING_SET ==
  283.                                        (enum op_letter_spacing)WORD_SPACING_SET);
  284.  
  285.                                 if (value == LETTER_SPACING_SET)
  286.                                         offset += 2; /* length + units */
  287.                                 break;
  288.  
  289.                         case CSS_PROP_LINE_HEIGHT:
  290.                                 switch (value) {
  291.                                 case LINE_HEIGHT_NUMBER:
  292.                                         offset++; /* value */
  293.                                         break;
  294.  
  295.                                 case LINE_HEIGHT_DIMENSION:
  296.                                         offset += 2; /* length + units */
  297.                                         break;
  298.                                 }
  299.                                 break;
  300.  
  301.                         case CSS_PROP_MAX_HEIGHT:
  302.                         case CSS_PROP_MAX_WIDTH:
  303.                                 assert(MAX_HEIGHT_SET ==
  304.                                        (enum op_max_height)MAX_WIDTH_SET);
  305.  
  306.                                 if (value == MAX_HEIGHT_SET)
  307.                                         offset += 2; /* length + units */
  308.                                 break;
  309.  
  310.                         case CSS_PROP_PADDING_TOP:
  311.                         case CSS_PROP_PADDING_RIGHT:
  312.                         case CSS_PROP_PADDING_BOTTOM:
  313.                         case CSS_PROP_PADDING_LEFT:
  314.                         case CSS_PROP_MIN_HEIGHT:
  315.                         case CSS_PROP_MIN_WIDTH:
  316.                         case CSS_PROP_PAUSE_AFTER:
  317.                         case CSS_PROP_PAUSE_BEFORE:
  318.                         case CSS_PROP_TEXT_INDENT:
  319.                                 assert(MIN_HEIGHT_SET == (enum op_min_height)MIN_WIDTH_SET);
  320.                                 assert(MIN_HEIGHT_SET == (enum op_min_height)PADDING_SET);
  321.                                 assert(MIN_HEIGHT_SET == (enum op_min_height)PAUSE_AFTER_SET);
  322.                                 assert(MIN_HEIGHT_SET == (enum op_min_height)PAUSE_BEFORE_SET);
  323.                                 assert(MIN_HEIGHT_SET == (enum op_min_height)TEXT_INDENT_SET);
  324.  
  325.                                 if (value == MIN_HEIGHT_SET)
  326.                                         offset += 2; /* length + units */
  327.                                 break;
  328.  
  329.                         case CSS_PROP_OPACITY:
  330.                                 if (value == OPACITY_SET)
  331.                                         offset++; /* value */
  332.                                 break;
  333.  
  334.                         case CSS_PROP_ORPHANS:
  335.                         case CSS_PROP_PITCH_RANGE:
  336.                         case CSS_PROP_RICHNESS:
  337.                         case CSS_PROP_STRESS:
  338.                         case CSS_PROP_WIDOWS:
  339.                                 assert(ORPHANS_SET == (enum op_orphans)PITCH_RANGE_SET);
  340.                                 assert(ORPHANS_SET == (enum op_orphans)RICHNESS_SET);
  341.                                 assert(ORPHANS_SET == (enum op_orphans)STRESS_SET);
  342.                                 assert(ORPHANS_SET == (enum op_orphans)WIDOWS_SET);
  343.  
  344.                                 if (value == ORPHANS_SET)
  345.                                         offset++; /* value */
  346.                                 break;
  347.  
  348.                         case CSS_PROP_OUTLINE_COLOR:
  349.                                 if (value == OUTLINE_COLOR_SET)
  350.                                         offset++; /* color */
  351.                                 break;
  352.  
  353.                         case CSS_PROP_PITCH:
  354.                                 if (value == PITCH_FREQUENCY)
  355.                                         offset += 2; /* length + units */
  356.                                 break;
  357.  
  358.                         case CSS_PROP_PLAY_DURING:
  359.                                 if (value == PLAY_DURING_URI)
  360.                                         offset++; /* string table entry */
  361.                                 break;
  362.  
  363.                         case CSS_PROP_QUOTES:
  364.                                 while (value != QUOTES_NONE) {
  365.                                         offset += 2; /* two string table entries */
  366.  
  367.                                         value = bytecode[offset];
  368.                                         offset++;
  369.                                 }
  370.                                 break;
  371.  
  372.                         case CSS_PROP_SPEECH_RATE:
  373.                                 if (value == SPEECH_RATE_SET)
  374.                                         offset++; /* rate */
  375.                                 break;
  376.  
  377.                         case CSS_PROP_VERTICAL_ALIGN:
  378.                                 if (value == VERTICAL_ALIGN_SET)
  379.                                         offset += 2; /* length + units */
  380.                                 break;
  381.  
  382.                         case CSS_PROP_VOICE_FAMILY:
  383.                                 while (value != VOICE_FAMILY_END) {
  384.                                         switch (value) {
  385.                                         case VOICE_FAMILY_STRING:
  386.                                         case VOICE_FAMILY_IDENT_LIST:
  387.                                                 offset++; /* string table entry */
  388.                                                 break;
  389.                                         }
  390.  
  391.                                         value = bytecode[offset];
  392.                                         offset++;
  393.                                 }
  394.                                 break;
  395.  
  396.                         case CSS_PROP_VOLUME:
  397.                                 switch (value) {
  398.                                 case VOLUME_NUMBER:
  399.                                         offset++; /* value */
  400.                                         break;
  401.  
  402.                                 case VOLUME_DIMENSION:
  403.                                         offset += 2; /* value + units */
  404.                                         break;
  405.                                 }
  406.                                 break;
  407.  
  408.                         case CSS_PROP_Z_INDEX:
  409.                                 if (value == Z_INDEX_SET)
  410.                                         offset++; /* z index */
  411.                                 break;
  412.  
  413.                         default:
  414.                                 break;
  415.                         }
  416.                 }
  417.         }
  418.  
  419. }
  420.  
  421.