/*
* This file is part of LibCSS
* Licensed under the MIT License,
* http://www.opensource.org/licenses/mit-license.php
* Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
*/
#include "bytecode/bytecode.h"
#include "bytecode/opcodes.h"
#include "select/propset.h"
#include "select/propget.h"
#include "utils/utils.h"
#include "select/properties/properties.h"
#include "select/properties/helpers.h"
css_error css__cascade_quotes(uint32_t opv, css_style *style,
css_select_state *state)
{
uint16_t value = CSS_QUOTES_INHERIT;
lwc_string **quotes = NULL;
uint32_t n_quotes = 0;
if (isInherit(opv) == false) {
uint32_t v = getValue(opv);
value = CSS_QUOTES_STRING;
while (v != QUOTES_NONE) {
lwc_string *open, *close;
lwc_string **temp;
css__stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &open);
advance_bytecode(style, sizeof(css_code_t));
css__stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &close);
advance_bytecode(style, sizeof(css_code_t));
temp = state->computed->alloc(quotes,
(n_quotes + 2) * sizeof(lwc_string *),
state->computed->pw);
if (temp == NULL) {
if (quotes != NULL) {
state->computed->alloc(quotes, 0,
state->computed->pw);
}
return CSS_NOMEM;
}
quotes = temp;
quotes[n_quotes++] = open;
quotes[n_quotes++] = close;
v = *((uint32_t *) style->bytecode);
advance_bytecode(style, sizeof(v));
}
}
/* Terminate array, if required */
if (n_quotes > 0) {
lwc_string **temp;
temp = state->computed->alloc(quotes,
(n_quotes + 1) * sizeof(lwc_string *),
state->computed->pw);
if (temp == NULL) {
state->computed->alloc(quotes, 0, state->computed->pw);
return CSS_NOMEM;
}
quotes = temp;
quotes[n_quotes] = NULL;
}
if (css__outranks_existing(getOpcode(opv), isImportant(opv), state,
isInherit(opv))) {
css_error error;
error = set_quotes(state->computed, value, quotes);
if (error != CSS_OK && quotes != NULL)
state->computed->alloc(quotes, 0, state->computed->pw);
return error;
} else {
if (quotes != NULL)
state->computed->alloc(quotes, 0, state->computed->pw);
}
return CSS_OK;
}
css_error css__set_quotes_from_hint(const css_hint *hint,
css_computed_style *style)
{
lwc_string **item;
css_error error;
error = set_quotes(style, hint->status, hint->data.strings);
for (item = hint->data.strings;
item != NULL && (*item) != NULL; item++) {
lwc_string_unref(*item);
}
if (error != CSS_OK && hint->data.strings != NULL)
style->alloc(hint->data.strings, 0, style->pw);
return error;
}
css_error css__initial_quotes(css_select_state *state)
{
css_hint hint;
css_error error;
error = state->handler->ua_default_for_property(state->pw,
CSS_PROP_QUOTES, &hint);
if (error != CSS_OK)
return error;
return css__set_quotes_from_hint(&hint, state->computed);
}
css_error css__compose_quotes(const css_computed_style *parent,
const css_computed_style *child,
css_computed_style *result)
{
css_error error;
lwc_string **quotes = NULL;
uint8_t type = get_quotes(child, "es);
if (type == CSS_QUOTES_INHERIT || result != child) {
size_t n_quotes = 0;
lwc_string **copy = NULL;
if (type == CSS_QUOTES_INHERIT) {
type = get_quotes(parent, "es);
}
if (quotes != NULL) {
lwc_string **i;
for (i = quotes; (*i) != NULL; i++)
n_quotes++;
copy = result->alloc(NULL, (n_quotes + 1) *
sizeof(lwc_string *),
result->pw);
if (copy == NULL)
return CSS_NOMEM;
memcpy(copy
, quotes
, (n_quotes
+ 1) *
sizeof(lwc_string *));
}
error = set_quotes(result, type, copy);
if (error != CSS_OK && copy != NULL)
result->alloc(copy, 0, result->pw);
return error;
}
return CSS_OK;
}