Commit 5d6edd41 authored by bdakin's avatar bdakin

Reviewed by Darin.

        Initial implementation of CSS2 counters. See http://
        bugs.webkit.org/show_bug.cgi?id=4980 for more details.

        * WebCore.xcodeproj/project.pbxproj:
        * css/CSSComputedStyleDeclaration.cpp: 
        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Return 
        the increment/reset list now that this is implemented.
        * css/CSSPrimitiveValue.cpp:
        (WebCore::CSSPrimitiveValue::cssText): 
        * css/Counter.h:
        (WebCore::Counter::Counter):
        (WebCore::Counter::~Counter):
        (WebCore::Counter::identifier):
        (WebCore::Counter::listStyle):
        (WebCore::Counter::separator):
        (WebCore::Counter::listStyleNumber):
        (WebCore::Counter::setIdentifier):
        (WebCore::Counter::setListStyle):
        (WebCore::Counter::setSeparator):
        * css/cssparser.cpp:
        (WebCore::CSSParser::addProperty): Take care of reset/increment
        (WebCore::CSSParser::parseValue):
        (WebCore::CSSParser::parseContent): content can now take counters
        (WebCore::CSSParser::parseCounterContent): Parse counter() and 
        counters()
        (WebCore::CSSParser::parseCounter): Parse counter-reset and 
        counter-increment
        * css/cssparser.h:
        * css/cssstyleselector.cpp:
        (WebCore::CSSStyleSelector::matchUARules):
        (WebCore::CSSStyleSelector::applyProperty):
        * platform/PlatformString.h:
        * platform/String.cpp:
        (WebCore::String::insert): Implemented a version of insert that 
        accepts a UChar* and a length.
        * platform/StringImpl.cpp:
        (WebCore::StringImpl::insert): Same as above.
        * platform/StringImpl.h:
        * rendering/CounterListItem.h: Added.
        * rendering/CounterNode.cpp: Added.
        (WebCore::CounterNode::CounterNode):
        (WebCore::CounterNode::insertAfter):
        (WebCore::CounterNode::removeChild):
        (WebCore::CounterNode::remove):
        (WebCore::CounterNode::setUsesSeparator):
        (WebCore::CounterNode::recountAndGetNext):
        (WebCore::CounterNode::recountTree):
        (WebCore::CounterNode::setSelfDirty):
        (WebCore::CounterNode::setParentDirty):
        * rendering/CounterNode.h: Added.
        (WebCore::CounterNode::~CounterNode):
        (WebCore::CounterNode::parent):
        (WebCore::CounterNode::previousSibling):
        (WebCore::CounterNode::nextSibling):
        (WebCore::CounterNode::firstChild):
        (WebCore::CounterNode::lastChild):
        (WebCore::CounterNode::value):
        (WebCore::CounterNode::setValue):
        (WebCore::CounterNode::count):
        (WebCore::CounterNode::setCount):
        (WebCore::CounterNode::setHasSeparator):
        (WebCore::CounterNode::isReset):
        (WebCore::CounterNode::hasSeparator):
        (WebCore::CounterNode::willNeedLayout):
        (WebCore::CounterNode::setWillNeedLayout):
        (WebCore::CounterNode::isRoot):
        (WebCore::CounterNode::setRenderer):
        (WebCore::CounterNode::renderer):
        * rendering/CounterResetNode.cpp: Added.
        (WebCore::CounterResetNode::CounterResetNode):
        (WebCore::CounterResetNode::insertAfter):
        (WebCore::CounterResetNode::removeChild):
        (WebCore::CounterResetNode::recountAndGetNext):
        (WebCore::CounterResetNode::setParentDirty):
        (WebCore::CounterResetNode::updateTotal):
        * rendering/CounterResetNode.h: Added.
        (WebCore::CounterResetNode::firstChild):
        (WebCore::CounterResetNode::lastChild):
        (WebCore::CounterResetNode::isReset):
        (WebCore::CounterResetNode::total):
        * rendering/RenderContainer.cpp:
        (WebCore::RenderContainer::updatePseudoChildForObject): Account for 
        counter content.
        * rendering/RenderCounter.cpp: Added.
        (WebCore::RenderCounter::RenderCounter):
        (WebCore::RenderCounter::layout):
        (WebCore::toRoman):
        (WebCore::toLetterString):
        (WebCore::toHebrew):
        (WebCore::RenderCounter::convertValueToType):
        (WebCore::RenderCounter::calcMinMaxWidth):
        * rendering/RenderCounter.h: Added.
        (WebCore::RenderCounter::renderName):
        (WebCore::RenderCounter::isCounter):
        * rendering/RenderObject.cpp:
        (WebCore::getRenderObjectsToCounterNodeMaps): Maps RenderObjects to 
        maps of CounterNodes
        (WebCore::RenderObject::RenderObject):
        (WebCore::RenderObject::destroy): Destroy the maps.
        (WebCore::RenderObject::findCounter): Finds/creates counters.
        * rendering/RenderObject.h:
        (WebCore::RenderObject::isCounter):
        * rendering/RenderStyle.cpp:
        (WebCore::StyleVisualData::StyleVisualData):
        (WebCore::RenderStyle::arenaDelete):
        (WebCore::RenderStyle::RenderStyle):
        (WebCore::RenderStyle::diff):
        (WebCore::RenderStyle::setContent):
        (WebCore::ContentData::clearContent):
        (WebCore::RenderStyle::counterDataEquivalent):
        (WebCore::hasCounter):
        (WebCore::RenderStyle::hasCounterReset):
        (WebCore::RenderStyle::hasCounterIncrement):
        (WebCore::readCounter):
        (WebCore::RenderStyle::counterReset):
        (WebCore::RenderStyle::counterIncrement):
        * rendering/RenderStyle.h:
        (WebCore::StyleVisualData::operator==):
        (WebCore::CounterData::CounterData):
        (WebCore::CounterData::identifier):
        (WebCore::CounterData::listStyle):
        (WebCore::CounterData::separator):
        (WebCore::ContentData::contentCounter):
        (WebCore::ContentData::):
        (WebCore::RenderStyle::counterIncrement):
        (WebCore::RenderStyle::counterReset):
        (WebCore::RenderStyle::setCounterIncrement):
        (WebCore::RenderStyle::setCounterReset):
        (WebCore::RenderStyle::setCounterResetList):
        (WebCore::RenderStyle::setCounterIncrementList):
        (WebCore::RenderStyle::counterResetValueList):
        (WebCore::RenderStyle::counterIncrementValueList):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@16721 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent af43bf0e
2006-10-02 Beth Dakin <bdakin@apple.com>
Reviewed by Darin.
Initial implementation of CSS2 counters. See http://
bugs.webkit.org/show_bug.cgi?id=4980 for more details.
* WebCore.xcodeproj/project.pbxproj:
* css/CSSComputedStyleDeclaration.cpp:
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Return
the increment/reset list now that this is implemented.
* css/CSSPrimitiveValue.cpp:
(WebCore::CSSPrimitiveValue::cssText):
* css/Counter.h:
(WebCore::Counter::Counter):
(WebCore::Counter::~Counter):
(WebCore::Counter::identifier):
(WebCore::Counter::listStyle):
(WebCore::Counter::separator):
(WebCore::Counter::listStyleNumber):
(WebCore::Counter::setIdentifier):
(WebCore::Counter::setListStyle):
(WebCore::Counter::setSeparator):
* css/cssparser.cpp:
(WebCore::CSSParser::addProperty): Take care of reset/increment
(WebCore::CSSParser::parseValue):
(WebCore::CSSParser::parseContent): content can now take counters
(WebCore::CSSParser::parseCounterContent): Parse counter() and
counters()
(WebCore::CSSParser::parseCounter): Parse counter-reset and
counter-increment
* css/cssparser.h:
* css/cssstyleselector.cpp:
(WebCore::CSSStyleSelector::matchUARules):
(WebCore::CSSStyleSelector::applyProperty):
* platform/PlatformString.h:
* platform/String.cpp:
(WebCore::String::insert): Implemented a version of insert that
accepts a UChar* and a length.
* platform/StringImpl.cpp:
(WebCore::StringImpl::insert): Same as above.
* platform/StringImpl.h:
* rendering/CounterListItem.h: Added.
* rendering/CounterNode.cpp: Added.
(WebCore::CounterNode::CounterNode):
(WebCore::CounterNode::insertAfter):
(WebCore::CounterNode::removeChild):
(WebCore::CounterNode::remove):
(WebCore::CounterNode::setUsesSeparator):
(WebCore::CounterNode::recountAndGetNext):
(WebCore::CounterNode::recountTree):
(WebCore::CounterNode::setSelfDirty):
(WebCore::CounterNode::setParentDirty):
* rendering/CounterNode.h: Added.
(WebCore::CounterNode::~CounterNode):
(WebCore::CounterNode::parent):
(WebCore::CounterNode::previousSibling):
(WebCore::CounterNode::nextSibling):
(WebCore::CounterNode::firstChild):
(WebCore::CounterNode::lastChild):
(WebCore::CounterNode::value):
(WebCore::CounterNode::setValue):
(WebCore::CounterNode::count):
(WebCore::CounterNode::setCount):
(WebCore::CounterNode::setHasSeparator):
(WebCore::CounterNode::isReset):
(WebCore::CounterNode::hasSeparator):
(WebCore::CounterNode::willNeedLayout):
(WebCore::CounterNode::setWillNeedLayout):
(WebCore::CounterNode::isRoot):
(WebCore::CounterNode::setRenderer):
(WebCore::CounterNode::renderer):
* rendering/CounterResetNode.cpp: Added.
(WebCore::CounterResetNode::CounterResetNode):
(WebCore::CounterResetNode::insertAfter):
(WebCore::CounterResetNode::removeChild):
(WebCore::CounterResetNode::recountAndGetNext):
(WebCore::CounterResetNode::setParentDirty):
(WebCore::CounterResetNode::updateTotal):
* rendering/CounterResetNode.h: Added.
(WebCore::CounterResetNode::firstChild):
(WebCore::CounterResetNode::lastChild):
(WebCore::CounterResetNode::isReset):
(WebCore::CounterResetNode::total):
* rendering/RenderContainer.cpp:
(WebCore::RenderContainer::updatePseudoChildForObject): Account for
counter content.
* rendering/RenderCounter.cpp: Added.
(WebCore::RenderCounter::RenderCounter):
(WebCore::RenderCounter::layout):
(WebCore::toRoman):
(WebCore::toLetterString):
(WebCore::toHebrew):
(WebCore::RenderCounter::convertValueToType):
(WebCore::RenderCounter::calcMinMaxWidth):
* rendering/RenderCounter.h: Added.
(WebCore::RenderCounter::renderName):
(WebCore::RenderCounter::isCounter):
* rendering/RenderObject.cpp:
(WebCore::getRenderObjectsToCounterNodeMaps): Maps RenderObjects to
maps of CounterNodes
(WebCore::RenderObject::RenderObject):
(WebCore::RenderObject::destroy): Destroy the maps.
(WebCore::RenderObject::findCounter): Finds/creates counters.
* rendering/RenderObject.h:
(WebCore::RenderObject::isCounter):
* rendering/RenderStyle.cpp:
(WebCore::StyleVisualData::StyleVisualData):
(WebCore::RenderStyle::arenaDelete):
(WebCore::RenderStyle::RenderStyle):
(WebCore::RenderStyle::diff):
(WebCore::RenderStyle::setContent):
(WebCore::ContentData::clearContent):
(WebCore::RenderStyle::counterDataEquivalent):
(WebCore::hasCounter):
(WebCore::RenderStyle::hasCounterReset):
(WebCore::RenderStyle::hasCounterIncrement):
(WebCore::readCounter):
(WebCore::RenderStyle::counterReset):
(WebCore::RenderStyle::counterIncrement):
* rendering/RenderStyle.h:
(WebCore::StyleVisualData::operator==):
(WebCore::CounterData::CounterData):
(WebCore::CounterData::identifier):
(WebCore::CounterData::listStyle):
(WebCore::CounterData::separator):
(WebCore::ContentData::contentCounter):
(WebCore::ContentData::):
(WebCore::RenderStyle::counterIncrement):
(WebCore::RenderStyle::counterReset):
(WebCore::RenderStyle::setCounterIncrement):
(WebCore::RenderStyle::setCounterReset):
(WebCore::RenderStyle::setCounterResetList):
(WebCore::RenderStyle::setCounterIncrementList):
(WebCore::RenderStyle::counterResetValueList):
(WebCore::RenderStyle::counterIncrementValueList):
2006-10-02 Adele Peterson <adele@apple.com>
Reviewed by Adam.
......@@ -1088,6 +1088,13 @@
938E666209F09B87008A48EC /* JSHTMLCanvasElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 938E666109F09B87008A48EC /* JSHTMLCanvasElement.h */; };
938E683C09F0BD7B008A48EC /* GraphicsTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 938E683B09F0BD7A008A48EC /* GraphicsTypes.h */; };
938E685409F0BE04008A48EC /* GraphicsTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 938E685309F0BE04008A48EC /* GraphicsTypes.cpp */; };
9392F1420AD185F400691BD4 /* RenderCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9392F1410AD185F400691BD4 /* RenderCounter.h */; };
9392F1440AD185FE00691BD4 /* RenderCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9392F1430AD185FE00691BD4 /* RenderCounter.cpp */; };
9392F1460AD1860C00691BD4 /* CounterResetNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 9392F1450AD1860C00691BD4 /* CounterResetNode.h */; };
9392F14A0AD1861300691BD4 /* CounterResetNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9392F1490AD1861300691BD4 /* CounterResetNode.cpp */; };
9392F14C0AD1861B00691BD4 /* CounterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 9392F14B0AD1861B00691BD4 /* CounterNode.h */; };
9392F1500AD1862300691BD4 /* CounterNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9392F14F0AD1862300691BD4 /* CounterNode.cpp */; };
9392F1520AD1862B00691BD4 /* CounterListItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 9392F1510AD1862B00691BD4 /* CounterListItem.h */; };
939885C308B7E3D100E707C4 /* EventNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 939885C108B7E3D100E707C4 /* EventNames.cpp */; };
939885C408B7E3D100E707C4 /* EventNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 939885C208B7E3D100E707C4 /* EventNames.h */; };
93A1EAA00A5634C9006960A0 /* ImageDocumentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93A1EA9F0A5634C9006960A0 /* ImageDocumentMac.mm */; };
......@@ -3636,6 +3643,13 @@
938E666109F09B87008A48EC /* JSHTMLCanvasElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSHTMLCanvasElement.h; sourceTree = "<group>"; };
938E683B09F0BD7A008A48EC /* GraphicsTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsTypes.h; sourceTree = "<group>"; };
938E685309F0BE04008A48EC /* GraphicsTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsTypes.cpp; sourceTree = "<group>"; };
9392F1410AD185F400691BD4 /* RenderCounter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderCounter.h; sourceTree = "<group>"; };
9392F1430AD185FE00691BD4 /* RenderCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderCounter.cpp; sourceTree = "<group>"; };
9392F1450AD1860C00691BD4 /* CounterResetNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CounterResetNode.h; sourceTree = "<group>"; };
9392F1490AD1861300691BD4 /* CounterResetNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CounterResetNode.cpp; sourceTree = "<group>"; };
9392F14B0AD1861B00691BD4 /* CounterNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CounterNode.h; sourceTree = "<group>"; };
9392F14F0AD1862300691BD4 /* CounterNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CounterNode.cpp; sourceTree = "<group>"; };
9392F1510AD1862B00691BD4 /* CounterListItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CounterListItem.h; sourceTree = "<group>"; };
9394E0A403AA5BBE008635CE /* WebCorePageState.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebCorePageState.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
9394E0A503AA5BBE008635CE /* WebCorePageState.mm */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCorePageState.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
93955A4103D72932008635CE /* RenderTreeAsText.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeAsText.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
......@@ -7853,6 +7867,11 @@
BCEA4814097D93020094C9E4 /* bidi.h */,
BCEA4815097D93020094C9E4 /* break_lines.cpp */,
BCEA4816097D93020094C9E4 /* break_lines.h */,
9392F1510AD1862B00691BD4 /* CounterListItem.h */,
9392F14F0AD1862300691BD4 /* CounterNode.cpp */,
9392F14B0AD1861B00691BD4 /* CounterNode.h */,
9392F1490AD1861300691BD4 /* CounterResetNode.cpp */,
9392F1450AD1860C00691BD4 /* CounterResetNode.h */,
BCEA4817097D93020094C9E4 /* DataRef.h */,
ABE7B5210A489F830031881C /* DeprecatedRenderSelect.cpp */,
ABE7B5220A489F830031881C /* DeprecatedRenderSelect.h */,
......@@ -7889,6 +7908,8 @@
BCEA4829097D93020094C9E4 /* RenderView.h */,
BCEA482C097D93020094C9E4 /* RenderContainer.cpp */,
BCEA482D097D93020094C9E4 /* RenderContainer.h */,
9392F1430AD185FE00691BD4 /* RenderCounter.cpp */,
9392F1410AD185F400691BD4 /* RenderCounter.h */,
A8EA73AF0A1900E300A8EF5F /* RenderFieldset.cpp */,
A8EA73B00A1900E300A8EF5F /* RenderFieldset.h */,
066C772E0AB603FD00238CC4 /* RenderFileUploadControl.cpp */,
......@@ -9319,6 +9340,10 @@
85004DA60ACEEB5A00C438F6 /* DOMSVGDocumentInternal.h in Headers */,
85004DA70ACEEB5A00C438F6 /* DOMSVGEllipseElementInternal.h in Headers */,
ABB5419F0ACDDFE4002820EB /* RenderListBox.h in Headers */,
9392F1420AD185F400691BD4 /* RenderCounter.h in Headers */,
9392F1460AD1860C00691BD4 /* CounterResetNode.h in Headers */,
9392F14C0AD1861B00691BD4 /* CounterNode.h in Headers */,
9392F1520AD1862B00691BD4 /* CounterListItem.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -10446,6 +10471,9 @@
85004D990ACEEAEF00C438F6 /* DOMSVGDocument.mm in Sources */,
85004D9B0ACEEAEF00C438F6 /* DOMSVGEllipseElement.mm in Sources */,
ABB5419E0ACDDFE4002820EB /* RenderListBox.cpp in Sources */,
9392F1440AD185FE00691BD4 /* RenderCounter.cpp in Sources */,
9392F14A0AD1861300691BD4 /* CounterResetNode.cpp in Sources */,
9392F1500AD1862300691BD4 /* CounterNode.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -602,11 +602,9 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
// FIXME: unimplemented
break;
case CSS_PROP_COUNTER_INCREMENT:
// FIXME: unimplemented
break;
return style->counterIncrementValueList();
case CSS_PROP_COUNTER_RESET:
// FIXME: unimplemented
break;
return style->counterResetValueList();
case CSS_PROP_CURSOR: {
CSSValueList* list = 0;
CSSValue* value = 0;
......
......@@ -524,7 +524,10 @@ String CSSPrimitiveValue::cssText() const
// ###
break;
case CSS_COUNTER:
// ###
text = "counter(";
text += String::number(m_value.num);
text += ")";
// FIXME: Add list-style and separator
break;
case CSS_RECT: {
RectImpl* rectVal = getRectValue();
......
......@@ -23,23 +23,37 @@
#ifndef Counter_H
#define Counter_H
#include "Shared.h"
#include "CSSPrimitiveValue.h"
#include "PlatformString.h"
#include "Shared.h"
#include <wtf/PassRefPtr.h>
namespace WebCore {
class Counter : public Shared<Counter> {
public:
String identifier() const { return m_identifier; }
String listStyle() const { return m_listStyle; }
String separator() const { return m_separator; }
Counter() : m_identifier(0), m_listStyle(0), m_separator(0) { }
Counter(PassRefPtr<CSSPrimitiveValue> identifier, PassRefPtr<CSSPrimitiveValue> listStyle,
PassRefPtr<CSSPrimitiveValue> separator)
: m_identifier(identifier), m_listStyle(listStyle), m_separator(separator) { }
~Counter() { }
String identifier() const { return m_identifier ? m_identifier->getStringValue() : String(); }
String listStyle() const { return m_listStyle ? m_listStyle->getStringValue() : String(); }
String separator() const { return m_separator ? m_separator->getStringValue() : String(); }
private:
String m_identifier;
String m_listStyle;
String m_separator;
};
int listStyleNumber() const { return m_listStyle ? (int) m_listStyle->getFloatValue() : 0; }
void setIdentifier(PassRefPtr<CSSPrimitiveValue> identifier) { m_identifier = identifier; }
void setListStyle(PassRefPtr<CSSPrimitiveValue> listStyle) { m_listStyle = listStyle; }
void setSeparator(PassRefPtr<CSSPrimitiveValue> separator) { m_separator = separator; }
protected:
RefPtr<CSSPrimitiveValue> m_identifier; // String
RefPtr<CSSPrimitiveValue> m_listStyle; // int
RefPtr<CSSPrimitiveValue> m_separator; // String
};
} // namespace
} //namespace
#endif
......@@ -43,6 +43,7 @@
#include "CSSQuirkPrimitiveValue.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "Counter.h"
#include "DashboardRegion.h"
#include "Document.h"
#include "FontFamilyValue.h"
......@@ -335,7 +336,7 @@ bool CSSParser::parseMediaQuery(MediaList* queries, const String& string)
}
void CSSParser::addProperty(int propId, CSSValue *value, bool important)
void CSSParser::addProperty(int propId, PassRefPtr<CSSValue> value, bool important)
{
CSSProperty *prop = new CSSProperty(propId, value, important, m_currentShorthand, m_implicitShorthand);
if (numParsedProperties >= maxParsedProperties) {
......@@ -913,6 +914,16 @@ bool CSSParser::parseValue(int propId, bool important)
else
valid_primitive = (!id && validUnit(value, FNumber|FLength|FPercent, strict));
break;
case CSS_PROP_COUNTER_INCREMENT: // [ <identifier> <integer>? ]+ | none | inherit
if (id != CSS_VAL_NONE)
return parseCounter(propId, 1, important);
valid_primitive = true;
break;
case CSS_PROP_COUNTER_RESET: // [ <identifier> <integer>? ]+ | none | inherit
if (id != CSS_VAL_NONE)
return parseCounter(propId, 0, important);
valid_primitive = true;
break;
case CSS_PROP_FONT_FAMILY:
// [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
{
......@@ -1566,28 +1577,38 @@ bool CSSParser::parse4Values(int propId, const int *properties, bool important)
// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
bool CSSParser::parseContent(int propId, bool important)
{
CSSValueList* values = new CSSValueList;
RefPtr<CSSValueList> values = new CSSValueList;
while (Value* val = valueList->current()) {
CSSValue* parsedValue = 0;
RefPtr<CSSValue> parsedValue;
if (val->unit == CSSPrimitiveValue::CSS_URI) {
// url
String value = parseURL(domString(val->string));
parsedValue = new CSSImageValue(
String(KURL(styleElement->baseURL().deprecatedString(), value.deprecatedString()).url()), styleElement);
} else if (val->unit == Value::Function) {
// attr(X)
// attr(X) | counter(X [,Y]) | counters(X, Y, [,Z])
ValueList *args = val->function->args;
String fname = domString(val->function->name).lower();
if (fname != "attr(" || !args)
if (!args)
return false;
if (args->size() != 1)
if (fname == "attr(") {
if (args->size() != 1)
return false;
Value* a = args->current();
String attrName = domString(a->string);
if (document()->isHTMLDocument())
attrName = attrName.lower();
parsedValue = new CSSPrimitiveValue(attrName, CSSPrimitiveValue::CSS_ATTR);
} else if (fname == "counter(") {
parsedValue = parseCounterContent(args, false);
if (!parsedValue) return false;
} else if (fname == "counters(") {
parsedValue = parseCounterContent(args, true);
if (!parsedValue)
return false;
} else
return false;
Value *a = args->current();
String attrName = domString(a->string);
if (document()->isHTMLDocument())
attrName = attrName.lower();
parsedValue = new CSSPrimitiveValue(attrName, CSSPrimitiveValue::CSS_ATTR);
} else if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
// open-quote
// close-quote
......@@ -1599,17 +1620,16 @@ bool CSSParser::parseContent(int propId, bool important)
}
if (!parsedValue)
break;
values->append(parsedValue);
values->append(parsedValue.release());
valueList->next();
}
if (values->length()) {
addProperty(propId, values, important);
addProperty(propId, values.release(), important);
valueList->next();
return true;
}
delete values;
return false;
}
......@@ -2021,6 +2041,59 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
}
#endif
PassRefPtr<CSSValue> CSSParser::parseCounterContent(ValueList* args, bool counters)
{
unsigned numArgs = args->size();
if (counters && numArgs != 3 && numArgs != 5)
return 0;
if (!counters && numArgs != 1 && numArgs != 3)
return 0;
Value* i = args->current();
RefPtr<CSSPrimitiveValue> identifier = new CSSPrimitiveValue(domString(i->string),
CSSPrimitiveValue::CSS_STRING);
RefPtr<CSSPrimitiveValue> separator;
if (!counters)
separator = new CSSPrimitiveValue(String(), CSSPrimitiveValue::CSS_STRING);
else {
i = args->next();
if (i->unit != Value::Operator || i->iValue != ',')
return 0;
i = args->next();
if (i->unit != CSSPrimitiveValue::CSS_STRING)
return 0;
separator = new CSSPrimitiveValue(domString(i->string), (CSSPrimitiveValue::UnitTypes) i->unit);
}
RefPtr<CSSPrimitiveValue> listStyle;
i = args->next();
if (!i) // Make the list style default decimal
listStyle = new CSSPrimitiveValue(CSS_VAL_DECIMAL - CSS_VAL_DISC, CSSPrimitiveValue::CSS_NUMBER);
else {
if (i->unit != Value::Operator || i->iValue != ',')
return 0;
i = args->next();
if (i->unit != CSSPrimitiveValue::CSS_IDENT)
return 0;
short ls = 0;
if (i->id == CSS_VAL_NONE)
ls = CSS_VAL_KATAKANA_IROHA - CSS_VAL_DISC + 1;
else if (i->id >= CSS_VAL_DISC && i->id <= CSS_VAL_KATAKANA_IROHA)
ls = i->id - CSS_VAL_DISC;
else
return 0;
listStyle = new CSSPrimitiveValue(ls, (CSSPrimitiveValue::UnitTypes) i->unit);
}
return new CSSPrimitiveValue(new Counter(identifier.release(), listStyle.release(), separator.release()));
}
bool CSSParser::parseShape(int propId, bool important)
{
Value *value = valueList->current();
......@@ -2719,6 +2792,48 @@ bool CSSParser::parseBorderImage(int propId, bool important)
return context.failed();
}
bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
{
enum { ID, VAL } state = ID;
RefPtr<CSSValueList> list = new CSSValueList;
RefPtr<CSSPrimitiveValue> counterName;
while (true) {
Value* val = valueList->current();
switch (state) {
case ID:
if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
counterName = new CSSPrimitiveValue(domString(val->string), CSSPrimitiveValue::CSS_STRING);
state = VAL;
valueList->next();
continue;
}
break;
case VAL: {
int i = defaultValue;
if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) {
i = (int)val->fValue;
valueList->next();
}
list->append(new CSSPrimitiveValue(new Pair(counterName.release(),
new CSSPrimitiveValue(i, CSSPrimitiveValue::CSS_NUMBER))));
state = ID;
continue;
}
}
break;
}
if (list->length() > 0) {
addProperty(propId, list.release(), important);
return true;
}
return false;
}
#ifdef CSS_DEBUG
static inline int yyerror(const char *str)
......
......@@ -120,7 +120,7 @@ namespace WebCore {
Document* document() const;
void addProperty(int propId, CSSValue*, bool important);
void addProperty(int propId, PassRefPtr<CSSValue>, bool important);
void rollbackLastProperties(int num);
bool hasProperties() const { return numParsedProperties > 0; }
......@@ -146,11 +146,13 @@ namespace WebCore {
bool parseShape(int propId, bool important);
bool parseFont(bool important);
bool parseCounter(int propId, int defaultValue, bool important);
CSSValueList* parseFontFamily();
bool parseColorParameters(Value*, int* colorValues, bool parseAlpha);
bool parseHSLParameters(Value*, double* colorValues, bool parseAlpha);
CSSPrimitiveValue* parseColor();
CSSPrimitiveValue* parseColorFromValue(Value*);
PassRefPtr<CSSValue> parseCounterContent(ValueList* args, bool counters);
#ifdef SVG_SUPPORT
bool parseSVGValue(int propId, bool important);
......
......@@ -38,6 +38,7 @@
#include "CSSStyleSheet.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "Counter.h"
#include "CachedImage.h"
#include "DashboardRegion.h"
#include "FontFamilyValue.h"
......@@ -757,18 +758,16 @@ RenderStyle* CSSStyleSelector::locateSharedStyle()
void CSSStyleSelector::matchUARules(int& firstUARule, int& lastUARule)
{
// 1. First we match rules from the user agent sheet.
matchRules(defaultStyle, firstUARule, lastUARule);
// First we match rules from the user agent sheet.
CSSRuleSet* userAgentStyleSheet = m_medium->mediaTypeMatch("print")
? defaultPrintStyle : defaultStyle;
matchRules(userAgentStyleSheet, firstUARule, lastUARule);
// 2. In quirks mode, we match rules from the quirks user agent sheet.
// In quirks mode, we match rules from the quirks user agent sheet.
if (!strictParsing)
matchRules(defaultQuirksStyle, firstUARule, lastUARule);
// 3. If our medium is print, then we match rules from the print sheet.
if (m_medium->mediaTypeMatch("print"))
matchRules(defaultPrintStyle, firstUARule, lastUARule);
// 4. If we're in view source mode, then we match rules from the view source style sheet.
// If we're in view source mode, then we match rules from the view source style sheet.
if (view && view->frame() && view->frame()->inViewSourceMode())
matchRules(defaultViewSourceStyle, firstUARule, lastUARule);
}
......@@ -3176,7 +3175,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
for (int i = 0; i < len; i++) {
CSSValue *item = list->item(i);
if (!item->isPrimitiveValue()) continue;
if (!item->isPrimitiveValue())
continue;
CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item);
if (val->primitiveType()==CSSPrimitiveValue::CSS_STRING)
style->setContent(val->getStringValue().impl(), i != 0);
......@@ -3190,19 +3191,28 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
style->setContent(element->getAttribute(attr).impl(), i != 0);
// register the fact that the attribute value affects the style
m_selectorAttrs.add(attr.localName().impl());
}
else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI) {
} else if (val->primitiveType()==CSSPrimitiveValue::CSS_URI) {
CSSImageValue *image = static_cast<CSSImageValue*>(val);
style->setContent(image->image(element->document()->docLoader()), i != 0);
}
} else if (val->primitiveType()==CSSPrimitiveValue::CSS_COUNTER) {
Counter* counterValue = val->getCounterValue();
CounterData counter(counterValue->identifier(),
(EListStyleType)counterValue->listStyleNumber(), counterValue->separator());
style->setContent(new CounterData(counter), i != 0);
}
}
break;
}
case CSS_PROP_COUNTER_INCREMENT:
// list of CSS2CounterIncrement
if (!value->isValueList())
return;
style->setCounterIncrementList(static_cast<CSSValueList*>(value));
break;
case CSS_PROP_COUNTER_RESET:
// list of CSS2CounterReset
if (!value->isValueList())
return;
style->setCounterResetList(static_cast<CSSValueList*>(value));
break;
case CSS_PROP_FONT_FAMILY: {
// list of strings and ids
......
......@@ -91,6 +91,7 @@ public:
void append(char);
void append(UChar);
void insert(const String&, unsigned pos);
void insert(const UChar*, unsigned length, unsigned pos);
String& replace(UChar a, UChar b) { if (m_impl) m_impl = m_impl->replace(a, b); return *this; }
String& replace(UChar a, const String& b) { if (m_impl) m_impl = m_impl->replace(a, b.impl()); return *this; }
......
......@@ -157,6 +157,14 @@ void String::insert(const String& str, unsigned pos)
m_impl->insert(str.m_impl.get(), pos);
}
void String::insert(const UChar* str, unsigned length, unsigned pos)
{
if (!m_impl)
m_impl = new StringImpl(str, length);
else
m_impl->insert(str, length, pos);
}
UChar String::operator[](unsigned i) const
{
if (!m_impl || i >= m_impl->length())
......
......@@ -200,6 +200,27 @@ void StringImpl::insert(const StringImpl* str, unsigned pos)
}
}
void StringImpl::insert(const UChar* str, unsigned length, unsigned pos)
{
assert(!m_inTable);
if (pos >= m_length) {
RefPtr<StringImpl> s = new StringImpl(str, length);