1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/css/properties/CSSPropertyAPIContent.h"
#include "core/CSSValueKeywords.h"
#include "core/css/CSSCounterValue.h"
#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSStringValue.h"
#include "core/css/CSSValueList.h"
#include "core/css/parser/CSSParserContext.h"
#include "core/css/parser/CSSPropertyParserHelpers.h"
namespace blink {
namespace {
CSSValue* consumeAttr(CSSParserTokenRange args,
const CSSParserContext* context) {
if (args.peek().type() != IdentToken)
return nullptr;
AtomicString attrName =
args.consumeIncludingWhitespace().value().toAtomicString();
if (!args.atEnd())
return nullptr;
// TODO(esprehn): This should be lowerASCII().
if (context->isHTMLDocument())
attrName = attrName.lower();
CSSFunctionValue* attrValue = CSSFunctionValue::create(CSSValueAttr);
attrValue->append(*CSSCustomIdentValue::create(attrName));
return attrValue;
}
CSSValue* consumeCounterContent(CSSParserTokenRange args, bool counters) {
CSSCustomIdentValue* identifier =
CSSPropertyParserHelpers::consumeCustomIdent(args);
if (!identifier)
return nullptr;
CSSStringValue* separator = nullptr;
if (!counters) {
separator = CSSStringValue::create(String());
} else {
if (!CSSPropertyParserHelpers::consumeCommaIncludingWhitespace(args) ||
args.peek().type() != StringToken)
return nullptr;
separator = CSSStringValue::create(
args.consumeIncludingWhitespace().value().toString());
}
CSSIdentifierValue* listStyle = nullptr;
if (CSSPropertyParserHelpers::consumeCommaIncludingWhitespace(args)) {
CSSValueID id = args.peek().id();
if ((id != CSSValueNone &&
(id < CSSValueDisc || id > CSSValueKatakanaIroha)))
return nullptr;
listStyle = CSSPropertyParserHelpers::consumeIdent(args);
} else {
listStyle = CSSIdentifierValue::create(CSSValueDecimal);
}
if (!args.atEnd())
return nullptr;
return CSSCounterValue::create(identifier, listStyle, separator);
}
} // namespace
const CSSValue* CSSPropertyAPIContent::parseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext* context) {
if (CSSPropertyParserHelpers::identMatches<CSSValueNone, CSSValueNormal>(
range.peek().id()))
return CSSPropertyParserHelpers::consumeIdent(range);
CSSValueList* values = CSSValueList::createSpaceSeparated();
do {
CSSValue* parsedValue =
CSSPropertyParserHelpers::consumeImage(range, context);
if (!parsedValue) {
parsedValue = CSSPropertyParserHelpers::consumeIdent<
CSSValueOpenQuote, CSSValueCloseQuote, CSSValueNoOpenQuote,
CSSValueNoCloseQuote>(range);
}
if (!parsedValue)
parsedValue = CSSPropertyParserHelpers::consumeString(range);
if (!parsedValue) {
if (range.peek().functionId() == CSSValueAttr) {
parsedValue = consumeAttr(
CSSPropertyParserHelpers::consumeFunction(range), context);
} else if (range.peek().functionId() == CSSValueCounter) {
parsedValue = consumeCounterContent(
CSSPropertyParserHelpers::consumeFunction(range), false);
} else if (range.peek().functionId() == CSSValueCounters) {
parsedValue = consumeCounterContent(
CSSPropertyParserHelpers::consumeFunction(range), true);
}
if (!parsedValue)
return nullptr;
}
values->append(*parsedValue);
} while (!range.atEnd());
return values;
}
} // namespace blink
|