/* * 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& names, const Vector >& 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) { CSSValue* 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 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--; } } setNeedsStyleRecalc(); } // 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 setNeedsStyleRecalc(); } void CSSVariablesDeclaration::addParsedVariable(const String& variableName, PassRefPtr variableValue, bool updateNamesList) { // FIXME: Disabling declarations as variable values for now since they no longer have a common base class with CSSValues. #if 0 variableValue->setParent(this); // Needed to connect variables that are CSSMutableStyleDeclarations, since the parent couldn't be set until now. #endif // Don't leak duplicates. For multiple variables with the same name, the last one // declared will win. CSSValue* 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) { CSSValue* result = m_variablesMap.get(variableName).get(); if (result->isValueList()) return static_cast(result); return 0; } CSSMutableStyleDeclaration* CSSVariablesDeclaration::getParsedVariableDeclarationBlock(const String&) { // FIXME: Disabling declarations as variable values for now since they no longer have a common base class with CSSValues. #if 0 StyleBase* result = m_variablesMap.get(variableName).get(); if (result->isMutableStyleDeclaration()) return static_cast(result); #endif 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(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::setNeedsStyleRecalc() { // 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(root)->doc()->updateStyleSelector(); } }