📄 css_valueimpl.cpp
字号:
/** * This file is part of the DOM implementation for KDE. * * (C) 1999-2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2002 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include "dom/css_value.h"#include "dom/dom_exception.h"#include "dom/dom_string.h"#include "css/css_valueimpl.h"#include "css/css_ruleimpl.h"#include "css/css_stylesheetimpl.h"#include "css/cssparser.h"#include "css/cssproperties.h"#include "css/cssvalues.h"#include "css/cssstyleselector.h"#include "xml/dom_stringimpl.h"#include "xml/dom_docimpl.h"#include "misc/loader.h"#include "rendering/font.h"#include "rendering/render_style.h"#include <kdebug.h>#include <qregexp.h>#include <qpaintdevice.h>#include <qpaintdevicemetrics.h>// Hack for debugging purposesextern DOM::DOMString getPropertyName(unsigned short id);using khtml::FontDef;using khtml::CSSStyleSelector;using namespace DOM;CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent) : StyleBaseImpl(parent){ m_lstValues = 0; m_node = 0;}CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent, QPtrList<CSSProperty> *lstValues) : StyleBaseImpl(parent){ m_lstValues = lstValues; m_node = 0;}CSSStyleDeclarationImpl& CSSStyleDeclarationImpl::operator= (const CSSStyleDeclarationImpl& o){ // don't attach it to the same node, just leave the current m_node value delete m_lstValues; m_lstValues = 0; if (o.m_lstValues) { m_lstValues = new QPtrList<CSSProperty>; m_lstValues->setAutoDelete( true ); QPtrListIterator<CSSProperty> lstValuesIt(*o.m_lstValues); for (lstValuesIt.toFirst(); lstValuesIt.current(); ++lstValuesIt) m_lstValues->append(new CSSProperty(*lstValuesIt.current())); } return *this;}CSSStyleDeclarationImpl::~CSSStyleDeclarationImpl(){ delete m_lstValues; // we don't use refcounting for m_node, to avoid cyclic references (see ElementImpl)}DOMString CSSStyleDeclarationImpl::getPropertyValue( int propertyID ) const{ if(!m_lstValues) return DOMString(); CSSValueImpl* value = getPropertyCSSValue( propertyID ); if ( value ) return value->cssText(); // Shorthand and 4-values properties switch ( propertyID ) { case CSS_PROP_BACKGROUND_POSITION: { // ## Is this correct? The code in cssparser.cpp is confusing const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X, CSS_PROP_BACKGROUND_POSITION_Y }; return getShortHandValue( properties, 2 ); } case CSS_PROP_BACKGROUND: { const int properties[5] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT, CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION, CSS_PROP_BACKGROUND_COLOR }; return getShortHandValue( properties, 5 ); } case CSS_PROP_BORDER: { const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE, CSS_PROP_BORDER_COLOR }; return getShortHandValue( properties, 3 ); } case CSS_PROP_BORDER_TOP: { const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_TOP_COLOR}; return getShortHandValue( properties, 3 ); } case CSS_PROP_BORDER_RIGHT: { const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE, CSS_PROP_BORDER_RIGHT_COLOR}; return getShortHandValue( properties, 3 ); } case CSS_PROP_BORDER_BOTTOM: { const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_BOTTOM_COLOR}; return getShortHandValue( properties, 3 ); } case CSS_PROP_BORDER_LEFT: { const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE, CSS_PROP_BORDER_LEFT_COLOR}; return getShortHandValue( properties, 3 ); } case CSS_PROP_OUTLINE: { const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE, CSS_PROP_OUTLINE_COLOR }; return getShortHandValue( properties, 3 ); } case CSS_PROP_BORDER_COLOR: { const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR, CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR }; return get4Values( properties ); } case CSS_PROP_BORDER_WIDTH: { const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH }; return get4Values( properties ); } case CSS_PROP_BORDER_STYLE: { const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE }; return get4Values( properties ); } case CSS_PROP_MARGIN: { const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT, CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT }; return get4Values( properties ); } case CSS_PROP_PADDING: { const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT, CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT }; return get4Values( properties ); } case CSS_PROP_LIST_STYLE: { const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION, CSS_PROP_LIST_STYLE_IMAGE }; return getShortHandValue( properties, 3 ); } } //kdDebug() << k_funcinfo << "property not found:" << propertyID << endl; return DOMString();}DOMString CSSStyleDeclarationImpl::get4Values( const int* properties ) const{ DOMString res; for ( int i = 0 ; i < 4 ; ++i ) { CSSValueImpl* value = getPropertyCSSValue( properties[i] ); if ( !value ) { // apparently all 4 properties must be specified. return DOMString(); } if ( i > 0 ) res += " "; res += value->cssText(); } return res;}DOMString CSSStyleDeclarationImpl::getShortHandValue( const int* properties, int number ) const{ DOMString res; for ( int i = 0 ; i < number ; ++i ) { CSSValueImpl* value = getPropertyCSSValue( properties[i] ); if ( value ) { // TODO provide default value if !value if ( !res.isNull() ) res += " "; res += value->cssText(); } } return res;} CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( int propertyID ) const{ if(!m_lstValues) return 0; QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); CSSProperty *current; for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt ) if (current->m_id == propertyID) return current->value(); return 0;}DOMString CSSStyleDeclarationImpl::removeProperty(int propertyID, bool notifyChanged){ if(!m_lstValues) return DOMString(); DOMString value; QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); CSSProperty *current; for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt ) if (current->m_id == propertyID) { value = current->value()->cssText(); m_lstValues->removeRef(current); if (notifyChanged) setChanged(); break; } return value;}void CSSStyleDeclarationImpl::setChanged(){ if (m_node) { m_node->setChanged(); return; } // ### quick&dirty hack for KDE 3.0... make this MUCH better! (Dirk) for (StyleBaseImpl* stylesheet = this; stylesheet; stylesheet = stylesheet->parent()) if (stylesheet->isCSSStyleSheet()) { static_cast<CSSStyleSheetImpl*>(stylesheet)->doc()->updateStyleSelector(); break; }}bool CSSStyleDeclarationImpl::getPropertyPriority( int propertyID ) const{ if ( m_lstValues) { QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); CSSProperty *current; for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) { if( propertyID == current->m_id ) return current->m_bImportant; } } return false;}bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool notifyChanged){ if(!m_lstValues) { m_lstValues = new QPtrList<CSSProperty>; m_lstValues->setAutoDelete(true); } removeProperty(id); CSSParser parser( strictParsing ); bool success = parser.parseValue(this, id, value, important); if(!success) kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string() << "] value: [" << value.string() << "]"<< endl; else if (notifyChanged) setChanged(); return success;}void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool notifyChanged){ if(!m_lstValues) { m_lstValues = new QPtrList<CSSProperty>; m_lstValues->setAutoDelete(true); } removeProperty(id); CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value); setParsedValue(id, cssValue, important, m_lstValues); if (notifyChanged) setChanged();}void CSSStyleDeclarationImpl::setStringProperty(int propertyId, const DOMString &value, CSSPrimitiveValue::UnitTypes type, bool important){ if (!m_lstValues) { m_lstValues = new QPtrList<CSSProperty>; m_lstValues->setAutoDelete(true); } removeProperty(propertyId); setParsedValue(propertyId, new CSSPrimitiveValueImpl(value, type), important, m_lstValues); setChanged();}void CSSStyleDeclarationImpl::setImageProperty(int propertyId, const DOMString &URL, bool important){ if (!m_lstValues) { m_lstValues = new QPtrList<CSSProperty>; m_lstValues->setAutoDelete(true); } removeProperty(propertyId); setParsedValue(propertyId, new CSSImageValueImpl(URL, this), important, m_lstValues); setChanged();}void CSSStyleDeclarationImpl::setProperty ( const DOMString &propertyString){ if(!m_lstValues) { m_lstValues = new QPtrList<CSSProperty>; m_lstValues->setAutoDelete( true ); } CSSParser parser(strictParsing); parser.parseDeclaration(this, propertyString); setChanged();}void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool _multiLength ){ bool parseMode = strictParsing; strictParsing = false; multiLength = _multiLength; setProperty( id, value, important); strictParsing = parseMode; multiLength = false;}unsigned long CSSStyleDeclarationImpl::length() const{ return m_lstValues ? m_lstValues->count() : 0;}DOMString CSSStyleDeclarationImpl::item( unsigned long /*index*/ ){ // ### //return m_lstValues->at(index); return DOMString();}CSSRuleImpl *CSSStyleDeclarationImpl::parentRule() const{ return (m_parent && m_parent->isRule() ) ? static_cast<CSSRuleImpl *>(m_parent) : 0;}DOM::DOMString CSSStyleDeclarationImpl::cssText() const{ DOMString result; if ( m_lstValues) { QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues); CSSProperty *current; for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) result += current->cssText(); } return result;}void CSSStyleDeclarationImpl::setCssText(const DOM::DOMString& text){ if (m_lstValues) m_lstValues->clear(); else { m_lstValues = new QPtrList<CSSProperty>; m_lstValues->setAutoDelete(true); } CSSParser parser(strictParsing); parser.parseDeclaration(this, text); setChanged();}bool CSSStyleDeclarationImpl::parseString( const DOMString &/*string*/, bool ){ return false; // ###}// --------------------------------------------------------------------------------------CSSValueImpl::CSSValueImpl() : StyleBaseImpl(){}CSSValueImpl::~CSSValueImpl(){}unsigned short CSSInheritedValueImpl::cssValueType() const{ return CSSValue::CSS_INHERIT;}DOM::DOMString CSSInheritedValueImpl::cssText() const{ return DOMString("inherit");}unsigned short CSSInitialValueImpl::cssValueType() const{ return CSSValue::CSS_INITIAL; }DOM::DOMString CSSInitialValueImpl::cssText() const{ return DOMString("initial");}// ----------------------------------------------------------------------------------------CSSValueListImpl::CSSValueListImpl() : CSSValueImpl(){}CSSValueListImpl::~CSSValueListImpl(){ CSSValueImpl *val = m_values.first(); while( val ) { val->deref(); val = m_values.next(); }}unsigned short CSSValueListImpl::cssValueType() const{ return CSSValue::CSS_VALUE_LIST;}void CSSValueListImpl::append(CSSValueImpl *val){ m_values.append(val); val->ref();}DOM::DOMString CSSValueListImpl::cssText() const{ DOMString result = ""; for (QPtrListIterator<CSSValueImpl> iterator(m_values); iterator.current(); ++iterator) { result += iterator.current()->cssText(); } return result;}// -------------------------------------------------------------------------------------CSSPrimitiveValueImpl::CSSPrimitiveValueImpl() : CSSValueImpl(){ m_type = 0;}CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(int ident) : CSSValueImpl(){ m_value.ident = ident; m_type = CSSPrimitiveValue::CSS_IDENT;}CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type){ m_value.num = num; m_type = type;}CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type){ m_value.string = str.implementation(); if(m_value.string) m_value.string->ref(); m_type = type;}CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const Counter &c){ m_value.counter = c.handle(); if (m_value.counter) m_value.counter->ref(); m_type = CSSPrimitiveValue::CSS_COUNTER;}CSSPrimitiveValueImpl::CSSPrimitiveValueImpl( RectImpl *r){ m_value.rect = r; if (m_value.rect) m_value.rect->ref(); m_type = CSSPrimitiveValue::CSS_RECT;}CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(QRgb color){ m_value.rgbcolor = color; m_type = CSSPrimitiveValue::CSS_RGBCOLOR;}CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl(){ cleanup();}void CSSPrimitiveValueImpl::cleanup()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -