diff options
Diffstat (limited to 'WebCore/css/CSSVariablesDeclaration.cpp')
-rw-r--r-- | WebCore/css/CSSVariablesDeclaration.cpp | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/WebCore/css/CSSVariablesDeclaration.cpp b/WebCore/css/CSSVariablesDeclaration.cpp new file mode 100644 index 0000000..bfd5e08 --- /dev/null +++ b/WebCore/css/CSSVariablesDeclaration.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CSSVariablesDeclaration.h" + +#include "CSSParser.h" +#include "CSSRule.h" +#include "CSSValueList.h" +#include "Document.h" +#include "ExceptionCode.h" + +namespace WebCore { + +CSSVariablesDeclaration::CSSVariablesDeclaration(StyleBase* parent, const Vector<String>& names, const Vector<RefPtr<StyleBase> >& values) + : StyleBase(parent) +{ + m_variableNames = names; + ASSERT(names.size() == values.size()); + unsigned s = names.size(); + for (unsigned i = 0; i < s; ++i) + addParsedVariable(names[i], values[i], false); +} + +CSSVariablesDeclaration::~CSSVariablesDeclaration() +{ +} + +String CSSVariablesDeclaration::getVariableValue(const String& variableName) +{ + StyleBase* val = m_variablesMap.get(variableName).get(); + if (val) + return val->cssText(); + return ""; +} + +String CSSVariablesDeclaration::removeVariable(const String& variableName, ExceptionCode&) +{ + // FIXME: The spec has this method taking an exception code but no exceptions are + // specified as being thrown. + RefPtr<StyleBase> val = m_variablesMap.take(variableName); + String result = val ? val->cssText() : ""; + if (val) { + int s = m_variableNames.size(); + for (int i = 0; i < s; ++i) { + if (m_variableNames[i] == variableName) { + m_variableNames.remove(i); + i--; + s--; + } + } + + setChanged(); + } + + // FIXME: Communicate this change so that the document will update. + return result; +} + +void CSSVariablesDeclaration::setVariable(const String& variableName, const String& variableValue, ExceptionCode& excCode) +{ + // Try to parse the variable value into a Value*. If it fails we throw an exception. + CSSParser parser(useStrictParsing()); + if (!parser.parseVariable(this, variableName, variableValue)) // If the parse succeeds, it will call addParsedVariable (our internal method for doing the add) with the parsed Value*. + excCode = SYNTAX_ERR; + else + setChanged(); +} + +void CSSVariablesDeclaration::addParsedVariable(const String& variableName, PassRefPtr<StyleBase> variableValue, bool updateNamesList) +{ + variableValue->setParent(this); // Needed to connect variables that are CSSMutableStyleDeclarations, since the parent couldn't be set until now. + + // Don't leak duplicates. For multiple variables with the same name, the last one + // declared will win. + StyleBase* current = m_variablesMap.take(variableName).get(); + if (!current && updateNamesList) + m_variableNames.append(variableName); + m_variablesMap.set(variableName, variableValue); + + // FIXME: Communicate this change so the document will update. +} + +CSSValueList* CSSVariablesDeclaration::getParsedVariable(const String& variableName) +{ + StyleBase* result = m_variablesMap.get(variableName).get(); + if (result->isValueList()) + return static_cast<CSSValueList*>(result); + return 0; +} + +CSSMutableStyleDeclaration* CSSVariablesDeclaration::getParsedVariableDeclarationBlock(const String& variableName) +{ + StyleBase* result = m_variablesMap.get(variableName).get(); + if (result->isMutableStyleDeclaration()) + return static_cast<CSSMutableStyleDeclaration*>(result); + return 0; +} + +unsigned CSSVariablesDeclaration::length() const +{ + return m_variableNames.size(); +} + +String CSSVariablesDeclaration::item(unsigned index) +{ + if (index >= m_variableNames.size()) + return ""; + return m_variableNames[index]; +} + +CSSRule* CSSVariablesDeclaration::parentRule() +{ + return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0; +} + +String CSSVariablesDeclaration::cssText() const +{ + String result = "{ "; + unsigned s = m_variableNames.size(); + for (unsigned i = 0; i < s; ++i) { + result += m_variableNames[i] + ": "; + result += m_variablesMap.get(m_variableNames[i])->cssText(); + if (i < s - 1) + result += "; "; + } + result += " }"; + return result; +} + +void CSSVariablesDeclaration::setCssText(const String&) +{ + // FIXME: It's not clear if this is actually settable. +} + +void CSSVariablesDeclaration::setChanged() +{ + // FIXME: Make this much better (it has the same problem CSSMutableStyleDeclaration does). + StyleBase* root = this; + while (StyleBase* parent = root->parent()) + root = parent; + if (root->isCSSStyleSheet()) + static_cast<CSSStyleSheet*>(root)->doc()->updateStyleSelector(); +} + +} |