--- /dev/null
+Makefile
+Makefile.in
+libkhtml_la.all_cpp.cpp
+testkhtml
+testcss
+testrender
+SunWS_cache
+ir.out
+testkhtml_static
--- /dev/null
+KHTML CHANGES
+=============
+
+* new start with DOM (Lars 10.8.99)
+
--- /dev/null
+<html>
+<head>
+<title>Internal design of khtml</title>
+<style>
+dt { font-weight: bold; }
+</style>
+<body bgcolor=white>
+<h1>Internal design of khtml</h1>
+
+<p>
+This document tries to give a short overview about the internal design of the khtml
+library. I've written this, because the lib has gotten quite big, and it is hard at first to find your
+way in the source code. This doesn't mean that you'll understand khtml after reading this
+document, but it'll hopefully make it easier for you to read the source code.
+</p>
+<p>
+The library is build up out of several different parts. Basically, when you use the lib, you
+create an instance of a KHTMLPart, and feed data to it. That's more or less all you need to
+know if you want to use khtml for another application. If you want to start hacking khtml,
+here's a sketch of the objects that will get constructed, when eg. running testkhtml with
+a url argument.
+</p>
+<p>
+In the following I'll assume that you're familiar with all the buzzwords used in current web
+techology. In case you aren't here's a more or less complete list of references:
+</p>
+<blockquote>
+<p>
+<b>Document Object model (DOM):</b><br>
+<a href="http://www.w3.org/DOM/">DOM Level1 and 2</a><br>
+We support DOM Level2 except for the events model at the moment.
+</p>
+<p>
+<b>HTML:</b><br>
+<a href="http://www.w3.org/TR/html4/">HTML4 specs</a><br>
+<a href="http://www.w3.org/TR/xhtml1/">xhtml specs</a><br>
+We support almost all of HTML4 and xhtml.
+</p>
+<p>
+<b>Cascading style sheets (CSS):</b><br>
+<a href="http://www.w3.org/TR/REC-CSS2/">CSS2 specs</a><br>
+We support almost all of CSS1, and most parts of CSS2.
+</p>
+<p>
+<b>Javascript:</b><br>
+insert some links here...<br>
+<a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/objects.asp">Microsoft javascript bindings</a><br>
+<a href="http://docs.iplanet.com/docs/manuals/js/client/jsref/contents.htm">Netscape javascript reference</a><br>
+Netscapes javascript bindings are outdated. We shouldn't follow them. Let's focus on getting the bindings
+compatible to IE.
+</p>
+</blockquote>
+
+<p>
+<a href="khtml_part.h">KHTMLPart</a> creates one instance of a
+<a href="khtmlview.h">KHTMLView</a> (derived from QScrollView),
+the widget showing the whole thing. At the same time a DOM tree
+is built up from the HTML or XML found in the specified file.
+<p>
+Let me describe this with an example.
+<p>
+khtml makes use of the document object model (DOM) for storing the document
+in a tree like structure. Imagine a some html like
+<pre>
+<html>
+ <head>
+ <style>
+ h1: { color: red; }
+ </style>
+ </head>
+ <body>
+ <H1>
+ some red text
+ </h1>
+ more text
+ <p>
+ a paragraph with an
+ <img src="foo.png">
+ embedded image.
+ </p>
+ </body>
+</html>
+</pre>
+In the following I'll show how this input will be processed step by step to generate the visible output
+you will finally see on your screen. I'm describing the things as if they happen one after the other,
+to make the priniciple more clear. In reality, to get visible output on the screen as soon as possible,
+all these things (from tokenization to the build up and layouting of the rendering tree) happen
+more or less in parallel.
+
+<h2>Tokenizer and parser</h2>
+<p>
+The first thing that happens when you start parsing a new document is that a
+DocumentImpl* (for XML documents) or an HTMLDocumentImpl* object will get
+created by the Part (in khtml_part.cpp::begin()). A Tokenizer*
+object is created as soon as DocumentImpl::open() is called by the part, also
+in begin() (can be either an XMLTokenizer or an HTMLTokenizer).
+<p>
+The XMLTokenizer uses the QXML classes in Qt to parse the document, and it's SAX interface
+to parse the stuff into khtmls DOM.
+<p>
+For HTML, the tokenizer is located in khtmltokenizer.cpp. The tokenizer uses the contents
+of a HTML-file as input and breaks this contents up in a linked list of
+tokens. The tokenizer recognizes HTML-entities and HTML-tags. Text between
+begin- and end-tags is handled distinctly for several tags. The distinctions
+are in the way how spaces, linefeeds, HTLM-entities and other tags are
+handled.
+<p>
+The tokenizer is completly state-driven on a character by character base.
+All text passed over to the tokenizer is directly tokenized. A complete
+HTML-file can be passed to the tokenizer as a whole, character by character
+(not very efficient) or in blocks of any (variable) size.
+<p>
+The HTMLTokenizer creates an HTMLParser which
+interprets the stream of tokens provided by the tokenizer
+and constructs the tree of Nodes representing the document according
+to the Document Object Model.
+<p>
+One big difference between HTML and XML at the moment is, that the HTML parser and Tokenizer
+can parse incrementally as the data arrives, while the XML Tokenizer (due to a limitation of
+Qts XML parser) can at the moment only parse the document, once it has been loaded completely.
+
+<h2>The DOM in khtml</h2>
+<p>
+Parsing the document given above gives the following DOM tree:
+
+<pre>
+HTMLDocumentElement
+ |--> HTMLHeadElement
+ | \--> HTMLStyleElement
+ | \--> CSSStyleSheet
+ \--> HTMLBodyElement
+ |--> HTMLHeadingElement
+ | \--> Text
+ |--> Text
+ \--> HTMLParagraphElement
+ |--> Text
+ |--> HTMLImageElement
+ \--> Text
+</pre>
+<p>
+Actually, the classes mentioned above are the interfaces for accessing the
+DOM. The actual data is stored in *Impl classes, providing the implementation
+for all of the above mentioned elements. So internally we have a tree
+looking like:
+<pre>
+HTMLDocumentElementImpl*
+ |--> HTMLHeadElementImpl*
+ | \--> HTMLStyleElementImpl*
+ | \--> CSSStyleSheetImpl*
+ \--> HTMLBodyElementImpl*
+ |--> HTMLHeadingElementImpl*
+ | \--> TextImpl*
+ |--> TextImpl*
+ \--> HTMLParagraphElementImpl*
+ |--> TextImpl*
+ |--> HTMLImageElementImpl*
+ \--> TextImpl*
+</pre>
+<p>
+We use a refcounting scheme to assure, that all the objects get deleted, in
+case the root element get deleted (as long as there's no interface class
+holding a pointer to the Implementation).
+<p>
+The interface classes (the ones without the Impl) are defined in the <code>dom/</code>
+subdirectory, and are not used by khtml itself at all. The only place they are used are in the
+javascript bindings, which uses them to access the DOM tree. The big advantage of having this
+separation between interface classes and imlementation classes, is that we can have several
+interface objects pointing to the same implementation. This implements the requirement of
+explicit sharing of the DOM specs.
+<p>
+Another advantage is, that (as the implementation classes are not exported) it gives us a lot
+more freedom to make changes in the implementation without breaking binary compatibility.
+<p>
+You will find almost a one to one correspondence between the interface classes and the implementation
+classes. In the implementation classes we have added a few more intermediate classes, that can
+not be seen from the outside for various reasons (make implementation of shared features easier
+or to reduce memory consumption).
+<p>
+In C++, you can access the whole DOM tree from outside KHTML by using the interface classes.
+For a description see the <a href="http://developer.kde.org/kde2arch/khtml/index.html">introduction to khtml</a> on<a href="http://developer.kde.org/">developer.kde.org</a>.
+
+One thing that has been omitted in the discussion above is the style sheet defined inside the
+<code><style></code> element (as an example of a style sheet) and the image element
+(as an example of an external resource that needs to be loaded). This will be done in the following
+two sections.
+
+<h2>CSS</h2> The contents of the <code><style></code> element (in this
+case the <code>h1 { color: red; }</code> rule) will get passed to the
+<a href="html/html_headimpl.h">HTMLStyleElementImpl object</a>. This object creates an
+<a href="css/cssstylesheetimpl.h">CSSStyleSheetImpl object</a> and passes the
+data to it. The <a href="css/cssparser.h">CSS parser</a> will take
+the data, and parse it into a DOM structure for CSS (similar to the one for
+HTML, see also the DOM level 2 specs). This will be later on used to define the
+look of the HTML elements in the DOM tree.
+<p>
+Actually "later on" is relative, as we will see later, that this happens partly in parallel to
+the build up of the DOM tree.
+
+<h2>Loading external objects</h2>
+<p>
+Some HTML elements (as <code><img>, <link>, <object>, etc.</code>) contain
+references to extrenal objects, that have to be loaded. This is done by the
+Loader and related classes (misc/loader.*). Objects that might need to load external objects
+inherit from <a href="misc/loader_client.h">CachedObjectClient</a>, and can ask
+the <a href="misc/loader.h">loader</a> (that also acts as a memory cache) to
+download the object they need for them from the web.
+<p>
+Once the <a href="misc/loader.h">loader</a> has the requested object ready, it will notify the
+<a href="misc/loader_client.h">CachedObjectClient</a> of this, and the client can
+then process the received data.
+
+<h2>Making it visible</h2>
+
+Now once we have the DOM tree, and the associated style sheets and external objects, how
+do we get the stuff actually displayed on the screen?
+<p>
+For this we have a rendering engine, that is completely based on CSS. The first
+thing that is done is to collect all style sheets that apply to the document
+and create a nice list of style rules that need to be applied to the
+elements. This is done in the <a href="css/cssstyleselector.h">CSSStyleSelector</a> class.
+It takes the <a href="css/html4.css">default HTML style sheet</a> (defined in css/html4.css),
+an optional user defined style sheet, and all style sheets from the document,
+and combines them to a nice list of parsed style rules (optimised for fast
+lookup). The exact rules of how these style sheets should get applied to HTML
+or XML documents can be found in the CSS2 specs.
+<p>
+Once we have this list, we can get a <a
+href="rendering/render_style.h">RenderStyle object</a>
+for every DOM element from the <a
+href="css/cssstyleselector.h">CSSStyleSelector</a> by calling
+"styleForElement(DOM::ElementImpl *".
+The style object describes in a compact form all the
+<a href="css/css_properties.in">CSS properties</a>
+that should get applied to the Node.
+<p>
+After that, a rendering tree gets built up. Using the style object, the
+<a href="xml/dom_nodeimpl.h">DOM Node</a> creates an appropriate render object
+(all these are defined in the rendering subdirectory) and adds it to the
+rendering tree. This will give another tree like structure, that resembles in
+it's general structure the DOM tree, but might have some significant
+differences too. First of all, so called
+ <a href="http://www.w3.org/TR/REC-CSS2/visuren.html#anonymous-block-level">anonymous boxes</a> - (see
+ <a href="http://www.w3.org/TR/REC-CSS2/">CSS specs</a>) that
+have no DOM counterpart might get inserted into the rendering tree to satify
+DOM requirements. Second, the display propery of the style affects which type
+of rendering object is chosen to represent the current DOM object.
+
+<p>
+In the above example we would get the following rendering tree:
+<pre>
+RenderRoot*
+ \--> RenderBody*
+ |--> RenderFlow* (<H1>)
+ | \--> RenderText* ("some red text")
+ |--> RenderFlow* (anonymous box)
+ | \--> RenderText* ("more text")
+ \--> RenderFlow* (<P>)
+ |--> RenderText* ("a paragraph with an")
+ |--> RenderImage*
+ \--> RenderText* ("embedded image.")
+</pre>
+
+<p>
+A call to of <a href="rendering/render_root.cpp">layout()</a> on the
+<a href="rendering/render_root.h">RenderRoot </a> (the root of the rendering tree)
+object causes the rendering tree to layout itself into the available space
+(width) given by the the KHTMLView. After that, the drawContents() method of
+KHTMLView can call RenderRoot->print() with appropriate parameters to actually
+paint the document. This is not 100% correct, when parsing incrementally, but
+is exactly what happens when you resize the document.
+
+
+As you can see, the conversion to the rendering tree removed the head part of
+the HTML code, and inserted an anonymous render object around the string "more
+text". For an explanation why this is done, see the CSS specs.
+<p>
+
+<h2>Directory structure</h2>
+
+A short explanation of the subdirectories in khtml.
+<dl>
+<dt><a href="css/">css:</a>
+<dd>Contains all the stuff relevant to the CSS part of DOM Level2 (implementation classes only),
+the <a href="css/cssparser.h">CSS parser</a>, and the stuff to create
+RenderStyle object out of Nodes and the CSS style sheets.
+<dt><a href="dom/">dom: </a>
+<dd>Contains the external DOM API (the DOM interface classes) for all of the DOM
+<dt><a href="ecma/">ecma:</a>
+<dd>The javascript bindings to the DOM and khtml.
+<dt><a href="html/">html:</a>
+<dd>The html subpart of the DOM (implementation only), the HTML tokenizer and parser and a class
+that defines the DTD to use for HTML (used mainly in the parser).
+<dt><a href="java/">java:</a>
+<dd>Java related stuff.
+<dt><a href="misc/>misc:</a>
+<dd>Some misc stuff needed in khtml. Contains the image loader, some misc definitions and the
+decoder class that converts the incoming stream to unicode.
+<dt><a href="rendering">rendering:</a>
+<dd>Everything thats related to bringing a DOM tree with CSS declarations to the screen. Contains
+the definition of the objects used in the rendering tree, the layouting code, and the RenderStyle objects.
+<dt><a href="xml/">xml:</a>
+<dd>The XML part of the DOM implementation, the xml tokenizer.
+</dl>
+
+<h2>Final words...</h2>
+<p>
+All the above is to give you a quick introduction into the way khtml brings an HTML/XML file to the screen.
+It is by no way complete or even 100% correct. I left out many problems, I will perhaps add either on request
+or when I find some time to do so. Let me name some of the missing things:
+<ul>
+<li>The decoder to convert the incoming stream to Unicode
+<li>interaction with konqueror/applications
+<li>javascript
+<li>dynamic reflow and how to use the DOM to manipulate khtmls visual ouput
+<li>mouse/event handling
+<li>real interactions when parsing incrementally
+<li>java
+</ul>
+
+Still I hope that this short introduction will make it easier for you to get a first hold of khtml and the way it works.
+<p>
+Now before I finish let me add a small <b>warning</b> and <b>advice</b> to all of you who plan hacking khtml themselves:
+<p>
+khtml is by now a quite big library and it takes some time to understand how it works. Don't let yourself get frustrated
+if you don't immediatly understand how it works. On the other hand, it is by now one of the libraries that
+get used a lot, that probably has the biggest number of remaining bugs (even though it's sometimes hard to
+know if some behaviour is really a bug).
+<blockquote>
+Some parts of it's code are however <b>extremely touchy</b> (especially the layouting algorithms),
+and making changes there (that might fix a bug on on web page) might introduce severe bugs.
+All the people developing khtml have already spend huge amounts of time searching for such bugs,
+that only showed up on some web pages, and thus were found only a week after the change that
+introduced the bug was made. This can be very frustrating for us, und we'd appreciate if people
+that are not completely familiar with khtml post changes touching these critical regions to kfm-devel
+for review before applying them.
+</blockquote>
+
+<div style="margin-top: 2em; font-size: large;">
+And now have fun hacking khtml.
+<div style="margin-left: 10em; margin-bottom: 1em;">Lars</div>
+</div>
+<hr>
+<center>$Id$</center>
+</body>
+</html>
--- /dev/null
+# This file is part of the KDE libraries
+# Copyright (C) 1997 Martin Jones (mjones@kde.org)
+# (C) 1997 Torben Weis (weis@kde.org)
+
+# 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.
+
+
+
+#AM_CXXFLAGS += -DTABLE_DEBUG
+#AM_CXXFLAGS += -DDEBUG_LAYOUT
+#AM_CXXFLAGS += -DDEBUG_EVENTS
+#AM_CXXFLAGS += -DTOKEN_DEBUG
+#AM_CXXFLAGS += -DPARSER_DEBUG
+#AM_CXXFLAGS += -DCACHE_DEBUG
+#AM_CXXFLAGS += -DDEBUG=1
+
+# for profiling.
+# command line for line by line profiling (into seperate files):
+# gprof -l -y
+# AM_CXXFLAGS += -pg
+
+SUBDIRS = misc dom css xml html rendering pics java . ecma
+
+lib_LTLIBRARIES = libkhtml.la libkhtmlimage.la
+libkhtml_la_SOURCES = khtmlview.cpp khtml_part.cpp khtml_run.cpp khtml_factory.cpp khtml_settings.cc \
+ khtml_events.cpp khtml_find.cpp khtml_ext.cpp khtml_pagecache.cpp
+
+libkhtml_la_METASOURCES = AUTO
+
+include_HEADERS = khtmlview.h khtml_part.h khtml_events.h khtml_settings.h khtmldefaults.h
+
+noinst_HEADERS = design.h testkhtml.h testrender.h khtml_find.h khtml_ext.h khtml_pagecache.h \
+ khtmlimage.h
+
+libkhtml_la_LDFLAGS = -version-info 3:0 -module -no-undefined $(all_libraries)
+libkhtml_la_LIBADD = ./xml/libkhtmlxml.la ./html/libkhtmlhtml.la \
+ ./rendering/libkhtmlrender.la ./css/libkhtmlcss.la \
+ ./misc/libkhtmlmisc.la ./dom/libkhtmldom.la ./java/libkjava.la \
+ ../kio/libkio.la \
+ $(top_builddir)/kparts/libkparts.la \
+ $(top_builddir)/kfile/libkfile.la \
+ $(top_builddir)/kssl/libkssl.la \
+ $(top_builddir)/kdeprint/libkdeprint.la
+
+libkhtmlimage_la_SOURCES = khtmlimage.cpp
+libkhtmlimage_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries)
+libkhtmlimage_la_LIBADD = libkhtml.la
+
+INCLUDES = -I$(top_srcdir)/kjs -I$(top_srcdir)/kimgio -I$(top_srcdir)/kio \
+ -I$(srcdir)/java -I$(top_srcdir)/dcop -I$(srcdir)/misc \
+ -I$(srcdir)/dom -I$(srcdir)/xml -I$(srcdir)/html -I$(srcdir)/css \
+ -I$(top_srcdir)/kfile -I$(top_srcdir)/libltdl \
+ -I$(top_srcdir)/kssl -I$(top_srcdir)/kdeprint \
+ -I$(top_srcdir) $(all_includes)
+
+servicedir = $(kde_servicesdir)
+service_DATA = khtml.desktop khtmlimage.desktop
+
+rcdir = $(kde_datadir)/khtml
+rc_DATA = khtml.rc khtml_browser.rc khtml_popupmenu.rc
+
+SRCDOC_DEST=$(kde_htmldir)/en/kdelibs/khtml
+
+## generate lib documentation
+srcdoc:
+ $(mkinstalldirs) $(SRCDOC_DEST)
+ kdoc -H -d $(SRCDOC_DEST) kdecore \
+ $(include_HEADERS) -lqt
+
+EXTRA_DIST = CHANGES DESIGN README.HTMLWidget README.tags
+
+parser:
+ cd $(srcdir) && \
+ perl scripts/makeattrs && \
+ bash scripts/maketags && \
+ bash scripts/makeprop
+
+## test program
+check_PROGRAMS = testkhtml testcss testrender testkhtml_static
+testkhtml_SOURCES = testkhtml.cpp domtreeview.cpp
+testkhtml_LDADD = libkhtml.la
+testkhtml_static_SOURCES = testkhtml.cpp domtreeview.cpp $(libkhtml_la_SOURCES)
+testkhtml_static_LDADD = $(LIB_KDEUI) $(libkhtml_la_LIBADD)
+testcss_SOURCES = testcss.cpp
+testcss_LDADD = libkhtml.la
+testrender_SOURCES = testrender.cpp
+testrender_LDADD = libkhtml.la
--- /dev/null
+KDE HTML Widget
+===============
+
+Developers
+----------
+
+The first version was written by
+
+Torben Weis <weis@stud.uni-frankfurt.de>
+
+It was extended by
+
+Josip A. Gracin <grac@fly.cc.fer.hr>,
+Martin Jones <mjones@kde.org>,
+Waldo Bastian <bastian@kde.org>
+Lars Knoll <knoll@kde.org>
+Antti Koivisto <koivisto@iki.fi>
+Dirk Mueller <mueller@kde.org>
+Peter Kelly <pmk@post.com>
+
+It is currently primarily maintained and developed by
+Lars Knoll, Dirk Mueller and Antti Koivisto.
+
+
+Revision History
+----------------
+
+This library is called libkhtml.
+This library used to be called libkhtmlw. With the release of KDE 1.1 a
+source incompatible version called libkhtml has been created.
+libkhtmlw will not be maintained any more, all application writers are
+urgently requested to make use of the new libkhtml library.
+
+
+Starting Point
+--------------
+
+You can add the widget to your program by doing something like:
+
+#include <khtml.h>
+
+ .
+ .
+ .
+
+ KHTMLWidget *view = new KHTMLWidget( parent, "Name" );
+ view->show();
+
+ view->begin( "file:/tmp/test.html" );
+ view->parse();
+ view->write( "<HTML><TITLE>...." );
+ view->write( "..." );
+ .
+ .
+ .
+ view->write( "</HTML>" );
+ view->end();
+
+
+After doing this, control must be returned to the event loop as the HTML
+is parsed in the background using a Qt timer.
+
+For more information see the full documentation in JavaDoc format included
+in the header files.
+
+
--- /dev/null
+All tags known by KHTML are listed in khtmltags.in.
+The maketags script generates a header file from this list.
+It also makes a gperf input file. gperf is than used to create
+the khtmltags.c file which contains a (almost) perfect hash
+function for recognizing HTML-tags.
+
+The HTML-tokenizer converts during parsing all tags to numeric
+tag-IDs. These IDs can then be used to select functions fast and
+to look up relevant CSS data.
+
+khtmlparser.cpp contains a jump-table which indexes from tag-ID
+to the relevant tag-open and tag-close functions. A 0-entry means
+that no function should be called for this tag.
+
+ADDING NEW TAGS
+===============
+
+If you want to add a new tag, you can do so in the file "khtmltags.in".
+Please keep this file sorted. You then have to run ./maketags to
+generate a new khtmltags.h and a new hash-function so that the new tag
+will be recognized. Then you should manually update the jumptable in
+"khtmlparer.cpp". If you do not want to implement the tag you can add
+an entry for the tag at the right position and fill it with two zeros.
+
--- /dev/null
+This document contains internet security issues. Discussion of security
+issues should be directed to kfm-devel@kde.org.
+
+Note to KDE-developers: When adding entries to this document, provide name,
+date and additional URLs.
+
+
+Malicious Redirects
+===================
+Entry By: Waldo Bastian <bastian@kde.org>
+Created: May 9th, 2000
+See also: http://lwn.net/2000/features/Redirect.phtml
+ http://www.zope.org/Members/jim/ZopeSecurity/ClientSideTrojan
+
+I advice the following:
+
+* We should never allow a redirect from a HTTP to any other protocol, including
+ HTTPS. (OK. The current implementation does not allow redirects to other
+ protocols)
+
+* We should provide a HTTP referer header iff the referer is on the same host
+as the requested object. (We currently don't support referer headers)
+
+* Either a) Don't allow POST or GET actions from javascript.
+ or b) _Always_ ask the user for confirmation when javascript requests a
+ POST or GET action.
+ Additional note: Simple requests for e.g. images are also GET actions,
+ disabling them would break a lot of javascript scripts.
+
+
+SSL certificates
+================
+Entry By: Waldo Bastian <bastian@kde.org>
+Created: May 13th, 2000
+See also: http://www.cert.org/advisories/CA-2000-05.html
+
+We never check SSL certificates. This makes https just as insecure as http.
+
+
+ECMAScript
+==========
+Entry By: Peter Kelly <pmk@post.com>
+Created: May 26th, 2000
+See also: http://developer.netscape.com/docs/manuals/js/client/jsguide/index.htm
+ (chapter 14)
+
+Before KDE 2.0 is released we *MUST* make sure there are checks in place for
+what DOM properties are accessable/writable for the ECMAScript binding. Otherwise
+malicious page authors may be able to access/set cookies from other sites, create
+auto-submitting forms that upload files, and a whole host of other attacks. The
+URL above has information about what properties netscape gives protection to.
+
+We will need to make sure we do this at the right level, as if it is done too
+close to the ECMAScript binding, there could be loopholes such as using
+getAttributeNode(), etc to fool it into letting a script change the wrong properties.
+
+
--- /dev/null
+Here's what's still missing (without order):
+
+Rendering:
+ * text-align: Justify missing
+ * allow font elements in a block level context.
+
+StyleSheets:
+ * @ rules in sheets
+ * lots of properties
+ * delete the old cssproperties in a style attribute in case
+ the style attribute changes.
+ * border shorthand properties. Unspecified properties get their default
+ values. border-width: medium; border-color: undefined (== text color)
+
+DOM:
+ * some functions in the Impl classes
+ * fix the set/retrieve functions, which use boolean values
+ -->> mostly done, still need to fix parseAttribute() calls
+ * DOM level 2
+ * DOM stylesheets, changes need to trigger the appropriate changes
+ in the rendering tree
+ * Implementation of NamedAttrMapImpl and Attributes in DOMElementImpl
+ is ugly. MOve aatributes to the elementImpl and make the namedNodeMap
+ point to an element. Think of creating AttrImpl's directly in
+ khtmltoken.cpp
+
+XML:
+ * lots of stuff in the Impl classes
+ * parsing
+ * entities
+ * style sheet processing instructions
+ * proper mimetype detection
+
+misc:
+ * <font size=+3> works as size=+1
+
+Java:
+ * support for the object element
+ --> mostly done
+ * Java <--> HTMLWidget communication
+ * turn kjava into a kpart
+
+Attributes:
+ * check for unimplemented attributes
+
+Memory usage:
+ * use bitfields for lots of things (especially in the
+ DOM/CSS/rendering stuff)
+ * try to make better use of shared objects, especially in the
+ RenderStyle
+ * check for leaks
+ * there's a mem leak with the style objects of anonymous
+ boxes (and ListMarkers).
+
+Other:
+ * there's a bug on correctly retrieving <textarea> text.
+ see test/forms.html and compare it with the way all other
+ browsers handle that code
+ * paste should be enabled (and implemented) if there's pasteable clipboard
+ content and a form element has the focus
--- /dev/null
+Makefile
+Makefile.in
+*.strip
\ No newline at end of file
--- /dev/null
+# This file is part of the KDE libraries
+# Copyright (C) 1997 Martin Jones (mjones@kde.org)
+# (C) 1997 Torben Weis (weis@kde.org)
+
+# 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.
+
+noinst_LTLIBRARIES = libkhtmlcss.la
+libkhtmlcss_la_SOURCES = \
+ css_stylesheetimpl.cpp css_ruleimpl.cpp css_valueimpl.cpp \
+ cssparser.cpp cssstyleselector.cpp csshelper.cpp
+
+#libkhtmlcss_la_LDFLAGS = -no-undefined
+libkhtmlcss_la_METASOURCES = AUTO
+
+noinst_HEADERS = \
+ css_extensionsimpl.h css_stylesheetimpl.h cssparser.h \
+ css_ruleimpl.h css_valueimpl.h \
+ cssstyleselector.h csshelper.h
+
+INCLUDES = -I$(top_srcdir)/kimgio -I$(top_srcdir)/kio -I$(top_srcdir)/dcop \
+ -I$(top_srcdir)/khtml -I$(top_srcdir)/khtml/misc -I$(top_srcdir)/khtml/css \
+ -I$(top_srcdir)/khtml/dom -I$(top_srcdir)/khtml/xml -I$(top_srcdir)/khtml/html \
+ -I$(top_srcdir)/libltdl -I$(top_srcdir) $(all_includes)
+
+
+cssdir = $(kde_datadir)/khtml/css
+css_DATA = html4.css
+
+SRCDOC_DEST=$(kde_htmldir)/en/kdelibs/khtml
+
+## generate lib documentation
+srcdoc:
+ $(mkinstalldirs) $(SRCDOC_DEST)
+ kdoc -H -d $(SRCDOC_DEST) kdecore \
+ $(include_HEADERS) -lqt
+
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2AzimuthImpl.h"
+using namespace DOM;
+
+CSS2AzimuthImpl::CSS2AzimuthImpl(DocumentImpl *doc) : CSSValueImpl(doc)
+{
+}
+
+CSS2AzimuthImpl::~CSS2AzimuthImpl()
+{
+}
+
+unsigned short CSS2AzimuthImpl::azimuthType() const
+{
+}
+
+DOMString CSS2AzimuthImpl::identifier() const
+{
+}
+
+bool CSS2AzimuthImpl::behind() const
+{
+}
+
+void CSS2AzimuthImpl::setAngleValue( const unsigned short &unitType, const float &floatValue )
+{
+}
+
+float CSS2AzimuthImpl::getAngleValue( const unsigned short &unitType )
+{
+}
+
+void CSS2AzimuthImpl::setIdentifier( const DOMString &identifier, const bool &behind )
+{
+}
+
+
+
+
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2BackgroundPositionImpl.h"
+CSS2BackgroundPositionImpl::CSS2BackgroundPositionImpl(DocumentImpl *doc) : CSSValueImpl(doc)
+{
+}
+
+CSS2BackgroundPositionImpl::~CSS2BackgroundPositionImpl()
+{
+}
+
+unsigned short CSS2BackgroundPositionImpl::horizontalType() const
+{
+}
+
+unsigned short CSS2BackgroundPositionImpl::verticalType() const
+{
+}
+
+DOMString CSS2BackgroundPositionImpl::horizontalIdentifier() const
+{
+}
+
+DOMString CSS2BackgroundPositionImpl::verticalIdentifier() const
+{
+}
+
+float CSS2BackgroundPositionImpl::getHorizontalPosition( const float &horizontalType )
+{
+}
+
+float CSS2BackgroundPositionImpl::getVerticalPosition( const float &verticalType )
+{
+}
+
+void CSS2BackgroundPositionImpl::setHorizontalPosition( const unsigned short &horizontalType, const float &value )
+{
+}
+
+void CSS2BackgroundPositionImpl::setVerticalPosition( const unsigned short &verticalType, const float &value )
+{
+}
+
+void CSS2BackgroundPositionImpl::setPositionIdentifier( const DOMString &horizontalIdentifier, const DOMString &verticalIdentifier )
+{
+}
+
+
+
+
+#include "DOMException.h"
+
+#include "CSS2BorderSpacingImpl.h"
+CSS2BorderSpacingImpl::CSS2BorderSpacingImpl(DocumentImpl *doc) : CSSValueImpl(doc)
+{
+}
+
+CSS2BorderSpacingImpl::~CSS2BorderSpacingImpl()
+{
+}
+
+unsigned short CSS2BorderSpacingImpl::horizontalType() const
+{
+}
+
+unsigned short CSS2BorderSpacingImpl::verticalType() const
+{
+}
+
+float CSS2BorderSpacingImpl::getHorizontalSpacing( const float &horizontalType )
+{
+}
+
+float CSS2BorderSpacingImpl::getVerticalSpacing( const float &verticalType )
+{
+}
+
+void CSS2BorderSpacingImpl::setHorizontalSpacing( const unsigned short &horizontalType, const float &value )
+{
+}
+
+void CSS2BorderSpacingImpl::setVerticalSpacing( const unsigned short &verticalType, const float &value )
+{
+}
+
+void CSS2BorderSpacingImpl::setInherit()( )
+{
+}
+
+
+
+
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2CounterIncrementImpl.h"
+CSS2CounterIncrementImpl::CSS2CounterIncrementImpl(DocumentImpl *doc)
+{
+}
+
+CSS2CounterIncrementImpl::~CSS2CounterIncrementImpl()
+{
+}
+
+short CSS2CounterIncrementImpl::increment() const
+{
+}
+
+void CSS2CounterIncrementImpl::setIncrement( const short & )
+{
+}
+
+
+
+
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2CounterResetImpl.h"
+CSS2CounterResetImpl::CSS2CounterResetImpl(DocumentImpl *doc)
+{
+}
+
+CSS2CounterResetImpl::~CSS2CounterResetImpl()
+{
+}
+
+short CSS2CounterResetImpl::reset() const
+{
+}
+
+void CSS2CounterResetImpl::setReset( const short & )
+{
+}
+
+
+
+
+#include "CSSValueList.h"
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2CursorImpl.h"
+CSS2CursorImpl::CSS2CursorImpl(DocumentImpl *doc) : CSSValueImpl(doc)
+{
+}
+
+CSS2CursorImpl::~CSS2CursorImpl()
+{
+}
+
+unsigned short CSS2CursorImpl::cursorType() const
+{
+}
+
+void CSS2CursorImpl::setCursorType( const unsigned short & )
+{
+}
+
+CSSValueList CSS2CursorImpl::uris() const
+{
+}
+
+
+
+
+#include "CSSValueList.h"
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2FontFaceSrcImpl.h"
+CSS2FontFaceSrcImpl::CSS2FontFaceSrcImpl(DocumentImpl *doc)
+{
+}
+
+CSS2FontFaceSrcImpl::~CSS2FontFaceSrcImpl()
+{
+}
+
+CSSValueList CSS2FontFaceSrcImpl::format() const
+{
+}
+
+
+
+
+#include "CSSValueList.h"
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2FontFaceWidthsImpl.h"
+CSS2FontFaceWidthsImpl::CSS2FontFaceWidthsImpl(DocumentImpl *doc)
+{
+}
+
+CSS2FontFaceWidthsImpl::~CSS2FontFaceWidthsImpl()
+{
+}
+
+CSSValueList CSS2FontFaceWidthsImpl::numbers() const
+{
+}
+
+
+
+
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2PageSizeImpl.h"
+CSS2PageSizeImpl::CSS2PageSizeImpl(DocumentImpl *doc) : CSSValueImpl(doc)
+{
+}
+
+CSS2PageSizeImpl::~CSS2PageSizeImpl()
+{
+}
+
+unsigned short CSS2PageSizeImpl::widthType() const
+{
+}
+
+unsigned short CSS2PageSizeImpl::heightType() const
+{
+}
+
+DOMString CSS2PageSizeImpl::identifier() const
+{
+}
+
+float CSS2PageSizeImpl::getWidth( const float &widthType )
+{
+}
+
+float CSS2PageSizeImpl::getHeightSize( const float &heightType )
+{
+}
+
+void CSS2PageSizeImpl::setWidthSize( const unsigned short &widthType, const float &value )
+{
+}
+
+void CSS2PageSizeImpl::setHeightSize( const unsigned short &heightType, const float &value )
+{
+}
+
+void CSS2PageSizeImpl::setIdentifier( const DOMString &identifier )
+{
+}
+
+
+
+
+#include "DOMException.h"
+#include "DOMString.h"
+
+#include "CSS2PlayDuringImpl.h"
+CSS2PlayDuringImpl::CSS2PlayDuringImpl(DocumentImpl *doc) : CSSValueImpl(doc)
+{
+}
+
+CSS2PlayDuringImpl::~CSS2PlayDuringImpl()
+{
+}
+
+unsigned short CSS2PlayDuringImpl::playDuringType() const
+{
+}
+
+bool CSS2PlayDuringImpl::mix() const
+{
+}
+
+void CSS2PlayDuringImpl::setMix( const bool & )
+{
+}
+
+bool CSS2PlayDuringImpl::repeat() const
+{
+}
+
+void CSS2PlayDuringImpl::setRepeat( const bool & )
+{
+}
+
+
+
+
+#include "DOMString.h"
+
+#include "CSS2PropertiesImpl.h"
+CSS2PropertiesImpl::CSS2PropertiesImpl(DocumentImpl *doc)
+{
+}
+
+CSS2PropertiesImpl::~CSS2PropertiesImpl()
+{
+}
+
+
+
+
+#include "CSSValue.h"
+
+#include "CSS2TextShadowImpl.h"
+CSS2TextShadowImpl::CSS2TextShadowImpl(DocumentImpl *doc)
+{
+}
+
+CSS2TextShadowImpl::~CSS2TextShadowImpl()
+{
+}
+
+CSSValue CSS2TextShadowImpl::color() const
+{
+}
+
+CSSValue CSS2TextShadowImpl::horizontal() const
+{
+}
+
+CSSValue CSS2TextShadowImpl::vertical() const
+{
+}
+
+CSSValue CSS2TextShadowImpl::blur() const
+{
+}
+
+
+
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#ifndef _CSS_css_extensionsimpl_h_
+#define _CSS_css_extensionsimpl_h_
+
+#include "css_valueimpl.h"
+#include "dom_string.h"
+
+namespace DOM {
+
+class CSS2AzimuthImpl : public CSSValueImpl
+{
+public:
+ CSS2AzimuthImpl(DocumentImpl *doc);
+
+ ~CSS2AzimuthImpl();
+
+ unsigned short azimuthType() const;
+ DOM::DOMString identifier() const;
+ bool behind() const;
+ void setAngleValue ( const unsigned short &unitType, const float &floatValue );
+ float getAngleValue ( const unsigned short &unitType );
+ void setIdentifier ( const DOM::DOMString &identifier, const bool &behind );
+};
+
+
+class DOM::DOMString;
+
+class CSS2BackgroundPositionImpl : public CSSValueImpl
+{
+public:
+ CSS2BackgroundPositionImpl(DocumentImpl *doc);
+
+ ~CSS2BackgroundPositionImpl();
+
+ unsigned short horizontalType() const;
+ unsigned short verticalType() const;
+ DOM::DOMString horizontalIdentifier() const;
+ DOM::DOMString verticalIdentifier() const;
+ float getHorizontalPosition ( const float &horizontalType );
+ float getVerticalPosition ( const float &verticalType );
+ void setHorizontalPosition ( const unsigned short &horizontalType, const float &value );
+ void setVerticalPosition ( const unsigned short &verticalType, const float &value );
+ void setPositionIdentifier ( const DOM::DOMString &horizontalIdentifier, const DOM::DOMString &verticalIdentifier );
+};
+
+
+
+class CSS2BorderSpacingImpl : public CSSValueImpl
+{
+public:
+ CSS2BorderSpacingImpl(DocumentImpl *doc);
+
+ ~CSS2BorderSpacingImpl();
+
+ unsigned short horizontalType() const;
+ unsigned short verticalType() const;
+ float getHorizontalSpacing ( const float &horizontalType );
+ float getVerticalSpacing ( const float &verticalType );
+ void setHorizontalSpacing ( const unsigned short &horizontalType, const float &value );
+ void setVerticalSpacing ( const unsigned short &verticalType, const float &value );
+ void setInherit() ( );
+};
+
+
+class CSS2CounterIncrementImpl
+{
+public:
+ CSS2CounterIncrementImpl(DocumentImpl *doc);
+
+ ~CSS2CounterIncrementImpl();
+
+ short increment() const;
+ void setIncrement( const short & );
+};
+
+
+class CSS2CounterResetImpl
+{
+public:
+ CSS2CounterResetImpl(DocumentImpl *doc);
+
+ ~CSS2CounterResetImpl();
+
+ short reset() const;
+ void setReset( const short & );
+};
+
+
+class CSS2CursorImpl : public CSSValueImpl
+{
+public:
+ CSS2CursorImpl(DocumentImpl *doc);
+
+ ~CSS2CursorImpl();
+
+ unsigned short cursorType() const;
+ void setCursorType( const unsigned short & );
+
+ CSSValueList uris() const;
+};
+
+
+class CSS2FontFaceSrcImpl
+{
+public:
+ CSS2FontFaceSrcImpl(DocumentImpl *doc);
+
+ ~CSS2FontFaceSrcImpl();
+
+ CSSValueList format() const;
+};
+
+
+class CSS2FontFaceWidthsImpl
+{
+public:
+ CSS2FontFaceWidthsImpl(DocumentImpl *doc);
+
+ ~CSS2FontFaceWidthsImpl();
+
+ CSSValueList numbers() const;
+};
+
+
+class CSS2PageSizeImpl : public CSSValueImpl
+{
+public:
+ CSS2PageSizeImpl(DocumentImpl *doc);
+
+ ~CSS2PageSizeImpl();
+
+ unsigned short widthType() const;
+ unsigned short heightType() const;
+ DOM::DOMString identifier() const;
+ float getWidth ( const float &widthType );
+ float getHeightSize ( const float &heightType );
+ void setWidthSize ( const unsigned short &widthType, const float &value );
+ void setHeightSize ( const unsigned short &heightType, const float &value );
+ void setIdentifier ( const DOM::DOMString &identifier );
+};
+
+
+class CSS2PlayDuringImpl : public CSSValueImpl
+{
+public:
+ CSS2PlayDuringImpl(DocumentImpl *doc);
+
+ ~CSS2PlayDuringImpl();
+
+ unsigned short playDuringType() const;
+ bool mix() const;
+
+ void setMix( const bool & );
+ bool repeat() const;
+
+ void setRepeat( const bool & );
+};
+
+
+class CSS2PropertiesImpl
+{
+public:
+ CSS2PropertiesImpl(DocumentImpl *doc);
+
+ ~CSS2PropertiesImpl();
+};
+
+
+class CSS2TextShadowImpl
+{
+public:
+ CSS2TextShadowImpl(DocumentImpl *doc);
+
+ ~CSS2TextShadowImpl();
+
+ CSSValue color() const;
+ CSSValue horizontal() const;
+ CSSValue vertical() const;
+ CSSValue blur() const;
+};
+
+
+}; // namespace
+
+#endif
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#include "css_ruleimpl.h"
+#include "css_rule.h"
+#include "css_stylesheet.h"
+#include "css_stylesheetimpl.h"
+#include "css_valueimpl.h"
+#include "cssparser.h"
+
+#include "misc/loader.h"
+
+#include "dom_exception.h"
+#include "dom_string.h"
+using namespace DOM;
+
+#include <kdebug.h>
+
+CSSRuleImpl::CSSRuleImpl(StyleBaseImpl *parent)
+ : StyleListImpl(parent)
+{
+ m_type = CSSRule::UNKNOWN_RULE;
+}
+
+CSSRuleImpl::~CSSRuleImpl()
+{
+}
+
+unsigned short CSSRuleImpl::type() const
+{
+ return m_type;
+}
+
+CSSStyleSheetImpl *CSSRuleImpl::parentStyleSheet() const
+{
+ if( !m_parent ) return 0;
+ if( m_parent->isCSSStyleSheet() ) return static_cast<CSSStyleSheetImpl *>(m_parent);
+ return 0;
+}
+
+CSSRuleImpl *CSSRuleImpl::parentRule() const
+{
+ if( !m_parent ) return 0;
+ if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent);
+ return 0;
+}
+
+DOM::DOMString CSSRuleImpl::cssText() const
+{
+ // ###
+ return 0;
+}
+
+void CSSRuleImpl::setCssText(DOM::DOMString /*str*/)
+{
+ // ###
+}
+
+// ---------------------------------------------------------------------------
+
+CSSCharsetRuleImpl::CSSCharsetRuleImpl(StyleBaseImpl *parent)
+ : CSSRuleImpl(parent)
+{
+ m_type = CSSRule::CHARSET_RULE;
+ m_encoding = 0;
+}
+
+CSSCharsetRuleImpl::~CSSCharsetRuleImpl()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+CSSFontFaceRuleImpl::CSSFontFaceRuleImpl(StyleBaseImpl *parent)
+ : CSSRuleImpl(parent)
+{
+ m_type = CSSRule::FONT_FACE_RULE;
+ m_style = 0;
+}
+
+CSSFontFaceRuleImpl::~CSSFontFaceRuleImpl()
+{
+ if(m_style) m_style->deref();
+}
+
+CSSStyleDeclarationImpl *CSSFontFaceRuleImpl::style() const
+{
+ return m_style;
+}
+
+// --------------------------------------------------------------------------
+
+CSSImportRuleImpl::CSSImportRuleImpl(StyleBaseImpl *parent, const DOM::DOMString &href,
+ MediaListImpl *media)
+ : CSSRuleImpl(parent)
+{
+ m_type = CSSRule::IMPORT_RULE;
+ m_lstMedia = media;
+ m_strHref = href;
+ m_styleSheet = 0;
+ kdDebug( 6080 ) << "CSSImportRule: requesting sheet " << href.string() << " " << baseUrl().string() << endl;
+
+ khtml::DocLoader *docLoader = 0;
+ StyleBaseImpl *root = this;
+ while (root->parent())
+ root = root->parent();
+ if (root->isCSSStyleSheet())
+ docLoader = static_cast<CSSStyleSheetImpl*>(root)->docLoader();
+
+ // we must have a docLoader !
+ // ### pass correct charset here!!
+ m_cachedSheet = docLoader->requestStyleSheet(href, baseUrl(), QString::null);
+
+ m_cachedSheet->ref(this);
+ m_loading = true;
+}
+
+CSSImportRuleImpl::~CSSImportRuleImpl()
+{
+ if(m_lstMedia) m_lstMedia->deref();
+ if(m_styleSheet) m_styleSheet->deref();
+ m_cachedSheet->deref(this);
+}
+
+DOMString CSSImportRuleImpl::href() const
+{
+ return m_strHref;
+}
+
+MediaListImpl *CSSImportRuleImpl::media() const
+{
+ return m_lstMedia;
+}
+
+CSSStyleSheetImpl *CSSImportRuleImpl::styleSheet() const
+{
+ return m_styleSheet;
+}
+
+void CSSImportRuleImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet)
+{
+ kdDebug( 6080 ) << "CSSImportRule::setStyleSheet()" << endl;
+
+ m_styleSheet = new CSSStyleSheetImpl(this, url);
+ m_styleSheet->ref();
+ m_styleSheet->parseString(sheet);
+ m_loading = false;
+
+ checkLoaded();
+}
+
+bool CSSImportRuleImpl::isLoading()
+{
+ if(m_loading) return true;
+ if(m_styleSheet->isLoading()) return true;
+ return false;
+}
+// --------------------------------------------------------------------------
+
+
+CSSMediaRuleImpl::CSSMediaRuleImpl(StyleBaseImpl *parent)
+ : CSSRuleImpl(parent)
+{
+ m_type = CSSRule::MEDIA_RULE;
+ m_lstMedia = 0;
+}
+
+CSSMediaRuleImpl::~CSSMediaRuleImpl()
+{
+ if(m_lstMedia) m_lstMedia->deref();
+}
+
+MediaListImpl *CSSMediaRuleImpl::media() const
+{
+ return m_lstMedia;
+}
+
+CSSRuleList CSSMediaRuleImpl::cssRules()
+{
+ return this;
+}
+
+unsigned long CSSMediaRuleImpl::insertRule( const DOMString &/*rule*/, unsigned long /*index*/ )
+{
+ // ###
+ return 0;
+}
+
+void CSSMediaRuleImpl::deleteRule( unsigned long /*index*/ )
+{
+ // ###
+}
+
+// ---------------------------------------------------------------------------
+
+CSSPageRuleImpl::CSSPageRuleImpl(StyleBaseImpl *parent)
+ : CSSRuleImpl(parent)
+{
+ m_type = CSSRule::PAGE_RULE;
+ m_style = 0;
+}
+
+CSSPageRuleImpl::~CSSPageRuleImpl()
+{
+ if(m_style) m_style->deref();
+}
+
+CSSStyleDeclarationImpl *CSSPageRuleImpl::style() const
+{
+ return m_style;
+}
+
+DOM::DOMString CSSPageRuleImpl::selectorText() const
+{
+ // ###
+ return 0;
+}
+
+void CSSPageRuleImpl::setSelectorText(DOM::DOMString /*str*/)
+{
+ // ###
+}
+
+// --------------------------------------------------------------------------
+
+CSSStyleRuleImpl::CSSStyleRuleImpl(StyleBaseImpl *parent)
+ : CSSRuleImpl(parent)
+{
+ m_type = CSSRule::STYLE_RULE;
+ m_style = 0;
+ m_selector = 0;
+}
+
+CSSStyleRuleImpl::~CSSStyleRuleImpl()
+{
+ if(m_style) {
+ m_style->setParent( 0 );
+ m_style->deref();
+ }
+ delete m_selector;
+}
+
+CSSStyleDeclarationImpl *CSSStyleRuleImpl::style() const
+{
+ return m_style;
+}
+
+DOM::DOMString CSSStyleRuleImpl::selectorText() const
+{
+ // ###
+ return 0;
+}
+
+void CSSStyleRuleImpl::setSelectorText(DOM::DOMString /*str*/)
+{
+ // ###
+}
+
+bool CSSStyleRuleImpl::parseString( const DOMString &/*string*/, bool )
+{
+ // ###
+ return false;
+}
+
+void CSSStyleRuleImpl::setSelector( QList<CSSSelector> *selector)
+{
+ m_selector = selector;
+}
+
+void CSSStyleRuleImpl::setDeclaration( CSSStyleDeclarationImpl *style)
+{
+ if(m_style) m_style->deref();
+ m_style = style;
+ if(m_style) m_style->ref();
+}
+
+void CSSStyleRuleImpl::setNonCSSHints()
+{
+ CSSSelector *s = m_selector->first();
+ while ( s ) {
+ s->nonCSSHint = true;
+ s = m_selector->next();
+ }
+}
+
+
+// --------------------------------------------------------------------------
+
+CSSUnknownRuleImpl::CSSUnknownRuleImpl(StyleBaseImpl *parent)
+ : CSSRuleImpl(parent)
+{
+}
+
+CSSUnknownRuleImpl::~CSSUnknownRuleImpl()
+{
+}
+
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#ifndef _CSS_css_ruleimpl_h_
+#define _CSS_css_ruleimpl_h_
+
+#include <dom_string.h>
+//#include <css_stylesheetimpl.h>
+#include <css_rule.h>
+#include "cssparser.h"
+#include "misc/loader_client.h"
+
+namespace khtml {
+ class CachedCSSStyleSheet;
+};
+
+namespace DOM {
+
+class CSSRule;
+class CSSStyleSheet;
+class CSSStyleSheetImpl;
+class CSSStyleDeclarationImpl;
+class MediaListImpl;
+
+// @media needs a list...
+// ### I'd prefer having CSSRuleImpl derived from StyleBaseImpl only, though.
+class CSSRuleImpl : public StyleListImpl
+{
+public:
+ CSSRuleImpl(StyleBaseImpl *parent);
+
+ virtual ~CSSRuleImpl();
+
+ virtual bool isRule() { return true; }
+
+ unsigned short type() const;
+ CSSStyleSheetImpl *parentStyleSheet() const;
+ CSSRuleImpl *parentRule() const;
+
+ DOM::DOMString cssText() const;
+ void setCssText(DOM::DOMString str);
+
+protected:
+ CSSRule::RuleType m_type;
+};
+
+
+class CSSCharsetRuleImpl : public CSSRuleImpl
+{
+public:
+ CSSCharsetRuleImpl(StyleBaseImpl *parent);
+
+ virtual ~CSSCharsetRuleImpl();
+
+ virtual bool isCharsetRule() { return true; }
+
+ DOMString encoding() const { return m_encoding; }
+ void setEncoding(DOMString _encoding) { m_encoding = _encoding; }
+
+protected:
+ DOMString m_encoding;
+};
+
+
+class CSSFontFaceRuleImpl : public CSSRuleImpl
+{
+public:
+ CSSFontFaceRuleImpl(StyleBaseImpl *parent);
+
+ virtual ~CSSFontFaceRuleImpl();
+
+ CSSStyleDeclarationImpl *style() const;
+
+ virtual bool isFontFaceRule() { return true; }
+
+protected:
+ CSSStyleDeclarationImpl *m_style;
+};
+
+
+class CSSImportRuleImpl : public khtml::CachedObjectClient, public CSSRuleImpl
+{
+public:
+ CSSImportRuleImpl(StyleBaseImpl *parent, const DOM::DOMString &href, MediaListImpl *media = 0);
+
+ virtual ~CSSImportRuleImpl();
+
+ DOM::DOMString href() const;
+ MediaListImpl *media() const;
+ CSSStyleSheetImpl *styleSheet() const;
+
+ virtual bool isImportRule() { return true; }
+
+ // from CachedObjectClient
+ virtual void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet);
+
+ bool isLoading();
+protected:
+ DOMString m_strHref;
+ MediaListImpl *m_lstMedia;
+ CSSStyleSheetImpl *m_styleSheet;
+ khtml::CachedCSSStyleSheet *m_cachedSheet;
+ bool m_loading;
+};
+
+
+class MediaList;
+class CSSRuleList;
+
+class CSSMediaRuleImpl : public CSSRuleImpl
+{
+public:
+ CSSMediaRuleImpl(StyleBaseImpl *parent);
+
+ virtual ~CSSMediaRuleImpl();
+
+ MediaListImpl *media() const;
+ CSSRuleList cssRules();
+ unsigned long insertRule ( const DOM::DOMString &rule, unsigned long index );
+ void deleteRule ( unsigned long index );
+
+ virtual bool isMediaRule() { return true; }
+protected:
+ MediaListImpl *m_lstMedia;
+};
+
+
+class CSSPageRuleImpl : public CSSRuleImpl
+{
+public:
+ CSSPageRuleImpl(StyleBaseImpl *parent);
+
+ virtual ~CSSPageRuleImpl();
+
+ CSSStyleDeclarationImpl *style() const;
+
+ virtual bool isPageRule() { return true; }
+
+ DOM::DOMString selectorText() const;
+ void setSelectorText(DOM::DOMString str);
+
+protected:
+ CSSStyleDeclarationImpl *m_style;
+};
+
+
+class CSSStyleRuleImpl : public CSSRuleImpl
+{
+public:
+ CSSStyleRuleImpl(StyleBaseImpl *parent);
+
+ virtual ~CSSStyleRuleImpl();
+
+ CSSStyleDeclarationImpl *style() const;
+
+ virtual bool isStyleRule() { return true; }
+
+ DOM::DOMString selectorText() const;
+ void setSelectorText(DOM::DOMString str);
+
+ virtual bool parseString( const DOMString &string, bool = false );
+
+ void setSelector( QList<CSSSelector> *selector);
+ void setDeclaration( CSSStyleDeclarationImpl *style);
+
+ QList<CSSSelector> *selector() { return m_selector; }
+ CSSStyleDeclarationImpl *declaration() { return m_style; }
+
+ void setNonCSSHints();
+
+protected:
+ CSSStyleDeclarationImpl *m_style;
+ QList<CSSSelector> *m_selector;
+};
+
+
+
+class CSSUnknownRuleImpl : public CSSRuleImpl
+{
+public:
+ CSSUnknownRuleImpl(StyleBaseImpl *parent);
+
+ ~CSSUnknownRuleImpl();
+
+ virtual bool isUnknownRule() { return true; }
+};
+
+class CSSRuleListImpl : public DomShared
+{
+ // ### implement this!
+public:
+ CSSRuleListImpl() {}
+
+ unsigned long length() const { return 0; }
+ CSSRuleImpl *item ( unsigned long /*index*/ ) { return 0; }
+};
+
+}; // namespace
+
+#endif
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+//#define CSS_STYLESHEET_DEBUG
+
+#include "css_stylesheetimpl.h"
+
+#include "css_stylesheet.h"
+#include "css_rule.h"
+#include "css_ruleimpl.h"
+#include "css_valueimpl.h"
+#include "cssparser.h"
+
+#include "dom_string.h"
+#include "dom_exception.h"
+#include "dom_nodeimpl.h"
+#include "html_documentimpl.h"
+#include "misc/loader.h"
+
+#include <kdebug.h>
+
+using namespace DOM;
+using namespace khtml;
+// --------------------------------------------------------------------------------
+
+StyleSheetImpl::StyleSheetImpl(StyleSheetImpl *parentSheet, DOMString href)
+ : StyleListImpl(parentSheet)
+{
+ m_disabled = false;
+ m_media = 0;
+ m_parentNode = 0;
+ m_strHref = href;
+}
+
+
+StyleSheetImpl::StyleSheetImpl(DOM::NodeImpl *parentNode, DOMString href)
+ : StyleListImpl()
+{
+ m_parentNode = parentNode;
+ m_disabled = false;
+ m_media = 0;
+ m_strHref = href;
+}
+
+StyleSheetImpl::StyleSheetImpl(StyleBaseImpl *owner, DOMString href)
+ : StyleListImpl(owner)
+{
+ m_disabled = false;
+ m_media = 0;
+ m_parentNode = 0;
+ m_strHref = href;
+}
+
+StyleSheetImpl::~StyleSheetImpl()
+{
+ if(m_media) m_media->deref();
+}
+
+bool StyleSheetImpl::deleteMe()
+{
+ if(!m_parent && _ref <= 0) return true;
+ return false;
+}
+
+bool StyleSheetImpl::disabled() const
+{
+ return m_disabled;
+}
+
+void StyleSheetImpl::setDisabled( bool disabled )
+{
+ m_disabled = disabled;
+}
+
+NodeImpl *StyleSheetImpl::ownerNode() const
+{
+ return m_parentNode;
+}
+
+StyleSheetImpl *StyleSheetImpl::parentStyleSheet() const
+{
+ if( !m_parent ) return 0;
+ if( m_parent->isStyleSheet() ) return static_cast<StyleSheetImpl *>(m_parent);
+ return 0;
+}
+
+DOMString StyleSheetImpl::href() const
+{
+ return m_strHref;
+}
+
+DOMString StyleSheetImpl::title() const
+{
+ return m_strTitle;
+}
+
+MediaListImpl *StyleSheetImpl::media() const
+{
+ return m_media;
+}
+
+// -----------------------------------------------------------------------
+
+
+CSSStyleSheetImpl::CSSStyleSheetImpl(CSSStyleSheetImpl *parentSheet, DOMString href)
+ : StyleSheetImpl(parentSheet, href)
+{
+ m_lstChildren = new QList<StyleBaseImpl>;
+ m_doc = 0;
+ m_implicit = false;
+}
+
+CSSStyleSheetImpl::CSSStyleSheetImpl(DOM::NodeImpl *parentNode, DOMString href, bool _implicit)
+ : StyleSheetImpl(parentNode, href)
+{
+ m_lstChildren = new QList<StyleBaseImpl>;
+ m_doc = parentNode->nodeType() == Node::DOCUMENT_NODE ? static_cast<DocumentImpl*>(parentNode) : m_doc = parentNode->ownerDocument();
+ m_implicit = _implicit;
+}
+
+CSSStyleSheetImpl::CSSStyleSheetImpl(CSSRuleImpl *ownerRule, DOMString href)
+ : StyleSheetImpl(ownerRule, href)
+{
+ m_lstChildren = new QList<StyleBaseImpl>;
+ m_doc = 0;
+ m_implicit = false;
+}
+
+CSSStyleSheetImpl::CSSStyleSheetImpl(DOM::NodeImpl *parentNode, CSSStyleSheetImpl *orig)
+ : StyleSheetImpl(parentNode, orig->m_strHref)
+{
+ m_lstChildren = new QList<StyleBaseImpl>;
+ StyleBaseImpl *rule;
+ for ( rule = orig->m_lstChildren->first(); rule != 0; rule = orig->m_lstChildren->next() )
+ {
+ m_lstChildren->append(rule);
+ rule->setParent(this);
+ }
+ m_doc = parentNode->nodeType() == Node::DOCUMENT_NODE ? static_cast<DocumentImpl*>(parentNode) : m_doc = parentNode->ownerDocument();
+ m_implicit = false;
+}
+
+CSSStyleSheetImpl::CSSStyleSheetImpl(CSSRuleImpl *ownerRule, CSSStyleSheetImpl *orig)
+ : StyleSheetImpl(ownerRule, orig->m_strHref)
+{
+ m_lstChildren = new QList<StyleBaseImpl>;
+ StyleBaseImpl *rule;
+ for ( rule = orig->m_lstChildren->first(); rule != 0; rule = orig->m_lstChildren->next() )
+ {
+ m_lstChildren->append(rule);
+ rule->setParent(this);
+ }
+ m_doc = 0;
+ m_implicit = false;
+}
+
+CSSStyleSheetImpl::~CSSStyleSheetImpl()
+{
+ // m_lstChildren is deleted in StyleListImpl
+}
+
+CSSRuleImpl *CSSStyleSheetImpl::ownerRule() const
+{
+ if( !m_parent ) return 0;
+ if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent);
+ return 0;
+}
+
+CSSRuleList CSSStyleSheetImpl::cssRules()
+{
+ return this;
+}
+
+unsigned long CSSStyleSheetImpl::insertRule( const DOMString &rule, unsigned long index, int &exceptioncode )
+{
+ exceptioncode = 0;
+ if(index > m_lstChildren->count()) {
+ exceptioncode = DOMException::INDEX_SIZE_ERR;
+ return 0;
+ }
+ const QString preprocessed = preprocess(rule.string());
+ const QChar *curP = preprocessed.unicode();
+ const QChar *endP = preprocessed.unicode() + preprocessed.length();
+ CSSRuleImpl *r = parseRule(curP, endP);
+
+ if(!r) {
+ exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
+ return 0;
+ }
+ // ###
+ // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified index e.g. if an
+ //@import rule is inserted after a standard rule set or other at-rule.
+ m_lstChildren->insert(index, r);
+ return index;
+}
+
+void CSSStyleSheetImpl::deleteRule( unsigned long index, int &exceptioncode )
+{
+ exceptioncode = 0;
+ StyleBaseImpl *b = m_lstChildren->take(index);
+ if(!b) {
+ exceptioncode = DOMException::INDEX_SIZE_ERR;
+ return;
+ }
+ b->deref();
+}
+
+bool CSSStyleSheetImpl::parseString(const DOMString &string, bool strict)
+{
+ strictParsing = strict;
+ const QString preprocessed = preprocess(string.string());
+
+#ifdef CSS_STYLESHEET_DEBUG
+ kdDebug( 6080 ) << "parsing sheet, len=" << string.length() << ", sheet is " << string.string() << endl;
+#endif
+
+ const QChar *curP = preprocessed.unicode();
+ const QChar *endP = preprocessed.unicode() + preprocessed.length();
+
+#ifdef CSS_STYLESHEET_DEBUG
+ kdDebug( 6080 ) << "preprocessed sheet, len=" << preprocessed.length() << ", sheet is " << preprocessed << endl;
+#endif
+
+ while (curP && (curP < endP))
+ {
+ CSSRuleImpl *rule = parseRule(curP, endP);
+ if(rule)
+ {
+ m_lstChildren->append(rule);
+ rule->setParent(this);
+ }
+ }
+ return true;
+}
+
+bool CSSStyleSheetImpl::isLoading()
+{
+ StyleBaseImpl *rule;
+ for ( rule = m_lstChildren->first(); rule != 0; rule = m_lstChildren->next() )
+ {
+ if(rule->isImportRule())
+ {
+ CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(rule);
+#ifdef CSS_STYLESHEET_DEBUG
+ kdDebug( 6080 ) << "found import" << endl;
+#endif
+ if(import->isLoading())
+ {
+#ifdef CSS_STYLESHEET_DEBUG
+ kdDebug( 6080 ) << "--> not loaded" << endl;
+#endif
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void CSSStyleSheetImpl::checkLoaded()
+{
+ if(isLoading()) return;
+ if(m_parent) m_parent->checkLoaded();
+ if(m_parentNode) m_parentNode->sheetLoaded();
+}
+
+void CSSStyleSheetImpl::setNonCSSHints()
+{
+ StyleBaseImpl *rule = m_lstChildren->first();
+ while(rule) {
+ if(rule->isStyleRule()) {
+ static_cast<CSSStyleRuleImpl *>(rule)->setNonCSSHints();
+ }
+ rule = m_lstChildren->next();
+ }
+}
+
+khtml::DocLoader *CSSStyleSheetImpl::docLoader()
+{
+ if ( !m_doc ) // doc is 0 for the user- and default-sheet!
+ return 0;
+
+ // ### remove? (clients just use sheet->doc()->docLoader())
+ return m_doc->docLoader();
+}
+
+// ---------------------------------------------------------------------------------------------
+
+StyleSheetListImpl::StyleSheetListImpl()
+{
+}
+
+StyleSheetListImpl::~StyleSheetListImpl()
+{
+ for ( QListIterator<StyleSheetImpl> it ( styleSheets ); it.current(); ++it )
+ it.current()->deref();
+}
+
+void StyleSheetListImpl::add( StyleSheetImpl* s )
+{
+ if ( !styleSheets.containsRef( s ) ) {
+ s->ref();
+ styleSheets.append( s );
+ }
+}
+
+void StyleSheetListImpl::remove( StyleSheetImpl* s )
+{
+ if ( styleSheets.removeRef( s ) )
+ s->deref();
+}
+
+unsigned long StyleSheetListImpl::length() const
+{
+ // hack so implicit BODY stylesheets don't get counted here
+ unsigned long l = 0;
+ QListIterator<StyleSheetImpl> it(styleSheets);
+ for (; it.current(); ++it) {
+ if (!it.current()->isCSSStyleSheet() || !static_cast<CSSStyleSheetImpl*>(it.current())->implicit())
+ l++;
+ }
+ return l;
+}
+
+StyleSheetImpl *StyleSheetListImpl::item ( unsigned long index )
+{
+ unsigned long l = 0;
+ QListIterator<StyleSheetImpl> it(styleSheets);
+ for (; it.current(); ++it) {
+ if (!it.current()->isCSSStyleSheet() || !static_cast<CSSStyleSheetImpl*>(it.current())->implicit()) {
+ if (l == index)
+ return it.current();
+ l++;
+ }
+ }
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------
+
+MediaListImpl::MediaListImpl(CSSStyleSheetImpl *parentSheet)
+ : StyleBaseImpl(parentSheet)
+{
+}
+
+MediaListImpl::MediaListImpl(CSSRuleImpl *parentRule)
+ : StyleBaseImpl(parentRule)
+{
+}
+
+MediaListImpl::~MediaListImpl()
+{
+}
+
+CSSStyleSheetImpl *MediaListImpl::parentStyleSheet() const
+{
+ if( m_parent->isCSSStyleSheet() ) return static_cast<CSSStyleSheetImpl *>(m_parent);
+ return 0;
+}
+
+CSSRuleImpl *MediaListImpl::parentRule() const
+{
+ if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent);
+ return 0;
+}
+
+unsigned long MediaListImpl::length() const
+{
+ return m_lstMedia.count();
+}
+
+DOMString MediaListImpl::item( unsigned long index )
+{
+ return m_lstMedia[index];
+}
+
+void MediaListImpl::del( const DOMString &oldMedium )
+{
+ for ( QValueList<DOMString>::Iterator it = m_lstMedia.begin(); it != m_lstMedia.end(); ++it ) {
+ if( (*it) == oldMedium ) {
+ m_lstMedia.remove( it );
+ return;
+ }
+ }
+}
+
+void MediaListImpl::append( const DOMString &newMedium )
+{
+ m_lstMedia.append( newMedium );
+}
+
+DOM::DOMString MediaListImpl::mediaText() const
+{
+ DOMString text;
+ for ( QValueList<DOMString>::ConstIterator it = m_lstMedia.begin(); it != m_lstMedia.end(); ++it ) {
+ text += *it;
+ text += ", ";
+ }
+ return text;
+}
+
+void MediaListImpl::setMediaText(const DOM::DOMString &value)
+{
+ m_lstMedia.clear();
+ QString val = value.string();
+ QStringList list = QStringList::split( ',', value.string() );
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ m_lstMedia.append( DOMString( (*it).stripWhiteSpace() ) );
+}
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#ifndef _CSS_css_stylesheetimpl_h_
+#define _CSS_css_stylesheetimpl_h_
+
+#include <qlist.h>
+#include <qvaluelist.h>
+
+#include <dom_string.h>
+
+#include "cssparser.h"
+#include "misc/loader_client.h"
+
+namespace khtml {
+ class CachedCSSStyleSheet;
+ class DocLoader;
+};
+
+namespace DOM {
+
+class StyleSheet;
+class CSSStyleSheet;
+class MediaListImpl;
+class CSSRuleImpl;
+class CSSRuleList;
+class CSSStyleRuleImpl;
+class CSSValueImpl;
+class NodeImpl;
+class DocumentImpl;
+
+class StyleSheetImpl : public StyleListImpl
+{
+public:
+ StyleSheetImpl(DOM::NodeImpl *ownerNode, DOM::DOMString href = 0);
+ StyleSheetImpl(StyleSheetImpl *parentSheet, DOM::DOMString href = 0);
+ StyleSheetImpl(StyleBaseImpl *owner, DOM::DOMString href = 0);
+ StyleSheetImpl(khtml::CachedCSSStyleSheet *cached, DOM::DOMString href = 0);
+
+ virtual ~StyleSheetImpl();
+
+ virtual bool isStyleSheet() { return true; }
+
+ virtual bool deleteMe();
+
+ virtual DOM::DOMString type() const { return 0; }
+
+ bool disabled() const;
+ void setDisabled( bool );
+
+ DOM::NodeImpl *ownerNode() const;
+ StyleSheetImpl *parentStyleSheet() const;
+ DOM::DOMString href() const;
+ DOM::DOMString title() const;
+ MediaListImpl *media() const;
+
+protected:
+ DOM::NodeImpl *m_parentNode;
+ DOM::DOMString m_strHref;
+ DOM::DOMString m_strTitle;
+ MediaListImpl *m_media;
+ bool m_disabled;
+};
+
+class CSSStyleSheetImpl : public StyleSheetImpl
+{
+public:
+ CSSStyleSheetImpl(DOM::NodeImpl *parentNode, DOM::DOMString href = 0, bool _implicit = false);
+ CSSStyleSheetImpl(CSSStyleSheetImpl *parentSheet, DOM::DOMString href = 0);
+ CSSStyleSheetImpl(CSSRuleImpl *ownerRule, DOM::DOMString href = 0);
+ // clone from a cached version of the sheet
+ CSSStyleSheetImpl(DOM::NodeImpl *parentNode, CSSStyleSheetImpl *orig);
+ CSSStyleSheetImpl(CSSRuleImpl *ownerRule, CSSStyleSheetImpl *orig);
+
+ virtual ~CSSStyleSheetImpl();
+
+ virtual bool isCSSStyleSheet() { return true; }
+
+ virtual DOM::DOMString type() const { return "text/css"; }
+
+ CSSRuleImpl *ownerRule() const;
+ CSSRuleList cssRules();
+ unsigned long insertRule ( const DOM::DOMString &rule, unsigned long index, int &exceptioncode );
+ void deleteRule ( unsigned long index, int &exceptioncode );
+
+ virtual bool parseString( const DOMString &string, bool strict = true );
+
+ bool isLoading();
+ void setNonCSSHints();
+
+ virtual void checkLoaded();
+ khtml::DocLoader *docLoader();
+ DocumentImpl *doc() { return m_doc; }
+ bool implicit() { return m_implicit; }
+protected:
+ DocumentImpl *m_doc;
+ bool m_implicit;
+};
+
+// ----------------------------------------------------------------------------
+
+class StyleSheetListImpl : public DomShared
+{
+public:
+ StyleSheetListImpl();
+ virtual ~StyleSheetListImpl();
+
+ // the following two ignore implicit stylesheets
+ unsigned long length() const;
+ StyleSheetImpl *item ( unsigned long index );
+
+ void add(StyleSheetImpl* s);
+ void remove(StyleSheetImpl* s);
+
+ QList<StyleSheetImpl> styleSheets;
+};
+
+// ----------------------------------------------------------------------------
+
+// ### This has different methods from the MediaList class because MediaList has
+// been adjusted to fit to the spec - this class needs to be updated
+
+class MediaListImpl : public StyleBaseImpl
+{
+public:
+ MediaListImpl(CSSStyleSheetImpl *parentSheet);
+ MediaListImpl(CSSRuleImpl *parentRule);
+
+ virtual ~MediaListImpl();
+
+ virtual bool isMediaList() { return true; }
+
+ CSSStyleSheetImpl *parentStyleSheet() const;
+ CSSRuleImpl *parentRule() const;
+ unsigned long length() const;
+ DOM::DOMString item ( unsigned long index );
+ void del ( const DOM::DOMString &oldMedium );
+ void append ( const DOM::DOMString &newMedium );
+
+ DOM::DOMString mediaText() const;
+ void setMediaText(const DOM::DOMString &value);
+
+protected:
+ QValueList<DOM::DOMString> m_lstMedia;
+};
+
+
+}; // namespace
+
+#endif
+
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#include "css_valueimpl.h"
+#include "css_value.h"
+#include "css_ruleimpl.h"
+#include "css_stylesheetimpl.h"
+#include "cssparser.h"
+#include "dom_exception.h"
+#include "dom_string.h"
+#include "dom_stringimpl.h"
+#include "dom_nodeimpl.h"
+
+#include "misc/loader.h"
+
+#include <kdebug.h>
+
+#include "cssvalues.h"
+
+// Hack for debugging purposes
+extern DOM::DOMString getPropertyName(unsigned short id);
+
+using namespace DOM;
+
+CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent)
+ : StyleBaseImpl(parent)
+{
+ m_lstValues = 0;
+ m_node = 0;
+}
+
+CSSStyleDeclarationImpl::CSSStyleDeclarationImpl(CSSRuleImpl *parent, QList<CSSProperty> *lstValues)
+ : StyleBaseImpl(parent)
+{
+ m_lstValues = lstValues;
+ m_node = 0;
+}
+
+CSSStyleDeclarationImpl::~CSSStyleDeclarationImpl()
+{
+ delete m_lstValues;
+ // we don't use refcounting for m_node, to avoid cyclic references (see ElementImpl)
+}
+
+DOMString CSSStyleDeclarationImpl::getPropertyValue( const DOMString &propertyName )
+{
+ CSSValueImpl *val = getPropertyCSSValue( propertyName );
+ if ( !val )
+ return 0;
+ return val->cssText();
+}
+
+DOMString CSSStyleDeclarationImpl::getPropertyValue( int id )
+{
+ CSSValueImpl *val = getPropertyCSSValue( id );
+ if ( !val )
+ return 0;
+ return val->cssText();
+}
+
+CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( const DOMString &propertyName )
+{
+ int id = getPropertyID(propertyName.string().ascii(), propertyName.length());
+ return getPropertyCSSValue(id);
+}
+
+CSSValueImpl *CSSStyleDeclarationImpl::getPropertyCSSValue( int propertyID )
+{
+ if(!m_lstValues) return 0;
+
+ unsigned int i = 0;
+ while(i < m_lstValues->count())
+ {
+ if(propertyID == m_lstValues->at(i)->m_id) return m_lstValues->at(i)->value();
+ i++;
+ }
+ return 0;
+}
+
+
+bool CSSStyleDeclarationImpl::removeProperty( int propertyID, bool onlyNonCSSHints )
+{
+ QListIterator<CSSProperty> lstValuesIt(*m_lstValues);
+ lstValuesIt.toLast();
+ while (lstValuesIt.current() && lstValuesIt.current()->m_id != propertyID)
+ --lstValuesIt;
+ if (lstValuesIt.current()) {
+ if ( onlyNonCSSHints && !lstValuesIt.current()->nonCSSHint )
+ return false;
+ m_lstValues->removeRef(lstValuesIt.current());
+ return true;
+ if (m_node)
+ m_node->setChanged(true);
+ }
+ return true;
+}
+
+
+DOMString CSSStyleDeclarationImpl::removeProperty( const DOMString &propertyName )
+{
+ int id = getPropertyID(propertyName.string().lower().ascii(), propertyName.length());
+ return removeProperty(id);
+}
+
+DOMString CSSStyleDeclarationImpl::removeProperty(int id)
+{
+ if(!m_lstValues) return 0;
+ DOMString value;
+
+ QListIterator<CSSProperty> lstValuesIt(*m_lstValues);
+ lstValuesIt.toLast();
+ while (lstValuesIt.current() && lstValuesIt.current()->m_id != id)
+ --lstValuesIt;
+ if (lstValuesIt.current()) {
+ value = lstValuesIt.current()->value()->cssText();
+ m_lstValues->removeRef(lstValuesIt.current());
+ if (m_node)
+ m_node->setChanged(true);
+ }
+ return value;
+}
+
+DOMString CSSStyleDeclarationImpl::getPropertyPriority( const DOMString &propertyName )
+{
+ int id = getPropertyID(propertyName.string().ascii(), propertyName.length());
+ if(getPropertyPriority(id))
+ return DOMString("important");
+ return DOMString();
+}
+
+bool CSSStyleDeclarationImpl::getPropertyPriority( int propertyID )
+{
+ if(!m_lstValues) return false;
+
+ unsigned int i = 0;
+ while(i < m_lstValues->count())
+ {
+ if(propertyID == m_lstValues->at(i)->m_id ) return m_lstValues->at(i)->m_bImportant;
+ i++;
+ }
+ return false;
+}
+
+void CSSStyleDeclarationImpl::setProperty( const DOMString &propName, const DOMString &value, const DOMString &priority )
+{
+ int id = getPropertyID(propName.string().lower().ascii(), propName.length());
+ if (!id) return;
+
+ bool important = false;
+ QString str = priority.string().lower();
+ if(str.contains("important"))
+ important = true;
+
+ setProperty(id, value, important);
+}
+
+void CSSStyleDeclarationImpl::setProperty(const DOMString &propName, const DOMString &value, bool important, bool nonCSSHint)
+{
+ int id = getPropertyID(propName.string().lower().ascii(), propName.length());
+ if (!id) return;
+ setProperty(id, value, important, nonCSSHint);
+}
+
+
+void CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool nonCSSHint)
+{
+ if(!m_lstValues) {
+ m_lstValues = new QList<CSSProperty>;
+ m_lstValues->setAutoDelete(true);
+ }
+ if ( !removeProperty(id, nonCSSHint ) )
+ return;
+ int pos = m_lstValues->count();
+ DOMString ppValue = preprocess(value.string(),true);
+ parseValue(ppValue.unicode(), ppValue.unicode()+ppValue.length(), id, important, m_lstValues);
+
+ if( nonCSSHint && pos < (int)m_lstValues->count() ) {
+ CSSProperty *p = m_lstValues->at(pos);
+ while ( p ) {
+ p->nonCSSHint = true;
+ p = m_lstValues->next();
+ }
+ } else if((unsigned) pos == m_lstValues->count() )
+ {
+ kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string()
+ << "] value: [" << value.string() << "]"<< endl;
+ }
+ if (m_node)
+ m_node->setChanged(true);
+}
+
+void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool nonCSSHint)
+{
+ if(!m_lstValues) {
+ m_lstValues = new QList<CSSProperty>;
+ m_lstValues->setAutoDelete(true);
+ }
+ if ( !removeProperty(id, nonCSSHint ) )
+ return;
+ int pos = m_lstValues->count();
+ CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value);
+ setParsedValue(id, cssValue, important, m_lstValues);
+
+ if( nonCSSHint && pos < (int)m_lstValues->count() ) {
+ CSSProperty *p = m_lstValues->at(pos);
+ while ( p ) {
+ p->nonCSSHint = true;
+ p = m_lstValues->next();
+ }
+ } else if((unsigned) pos == m_lstValues->count() )
+ {
+ kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string()
+ << "] value: [" << value << "]" << endl;
+ }
+ if (m_node)
+ m_node->setChanged(true);
+}
+
+void CSSStyleDeclarationImpl::setProperty ( const DOMString &propertyString)
+{
+ DOMString ppPropertyString = preprocess(propertyString.string(),true);
+ QList<CSSProperty> *props = parseProperties(ppPropertyString.unicode(),
+ ppPropertyString.unicode()+ppPropertyString.length());
+ if(!props || !props->count())
+ {
+ kdDebug( 6080 ) << "no properties returned!" << endl;
+ return;
+ }
+
+ props->setAutoDelete(false);
+
+ unsigned int i = 0;
+ if(!m_lstValues) {
+ m_lstValues = new QList<CSSProperty>;
+ m_lstValues->setAutoDelete( true );
+ }
+ while(i < props->count())
+ {
+ //kdDebug( 6080 ) << "setting property" << endl;
+ CSSProperty *prop = props->at(i);
+ removeProperty(prop->m_id, false);
+ m_lstValues->append(prop);
+ i++;
+ }
+ delete props;
+ if (m_node)
+ m_node->setChanged(true);
+}
+
+void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOMString &value,
+ bool important, bool nonCSSHint)
+{
+ bool parseMode = strictParsing;
+ strictParsing = false;
+ setProperty( id, value, important, nonCSSHint);
+ strictParsing = parseMode;
+#if 0 // ### FIXME after 2.0
+ if(!value.unicode() || value.length() == 0)
+ return;
+
+ if(!m_lstValues)
+ {
+ m_lstValues = new QList<CSSProperty>;
+ m_lstValues->setAutoDelete(true);
+ }
+
+ CSSValueImpl *v = parseUnit(value.unicode(), value.unicode()+value.length(),
+ INTEGER | PERCENT | LENGTH, );
+ if(!v)
+ {
+ kdDebug( 6080 ) << "invalid length" << endl;
+ return;
+ }
+
+ CSSPrimitiveValueImpl *p = static_cast<CSSPrimitiveValueImpl *>(v);
+ if(p->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
+ {
+ // set the parsed number in pixels
+ p->setPrimitiveType(CSSPrimitiveValue::CSS_PX);
+ }
+ CSSProperty *prop = new CSSProperty();
+ prop->m_id = id;
+ prop->setValue(v);
+ prop->m_bImportant = important;
+ prop->nonCSSHint = nonCSSHint;
+
+ m_lstValues->append(prop);
+#endif
+}
+
+unsigned long CSSStyleDeclarationImpl::length() const
+{
+ if(!m_lstValues) return 0;
+ return m_lstValues->count();
+}
+
+DOMString CSSStyleDeclarationImpl::item( unsigned long /*index*/ )
+{
+ // ###
+ //return m_lstValues->at(index);
+ return 0;
+}
+
+CSSRuleImpl *CSSStyleDeclarationImpl::parentRule() const
+{
+ if( !m_parent ) return 0;
+ if( m_parent->isRule() ) return static_cast<CSSRuleImpl *>(m_parent);
+ return 0;
+}
+
+DOM::DOMString CSSStyleDeclarationImpl::cssText() const
+{
+ return DOM::DOMString();
+ // ###
+}
+
+void CSSStyleDeclarationImpl::setCssText(DOM::DOMString /*str*/)
+{
+ // ###
+}
+
+bool CSSStyleDeclarationImpl::parseString( const DOMString &/*string*/, bool )
+{
+ return false;
+ // ###
+}
+
+
+// --------------------------------------------------------------------------------------
+
+CSSValueImpl::CSSValueImpl()
+ : StyleBaseImpl()
+{
+}
+
+CSSValueImpl::~CSSValueImpl()
+{
+}
+
+DOM::DOMString CSSValueImpl::cssText() const
+{
+ return DOM::DOMString();
+}
+
+void CSSValueImpl::setCssText(DOM::DOMString /*str*/)
+{
+ // ###
+}
+
+DOM::DOMString CSSInheritedValueImpl::cssText() const
+{
+ return DOMString("inherited");
+}
+// ----------------------------------------------------------------------------------------
+
+CSSValueListImpl::CSSValueListImpl()
+ : CSSValueImpl()
+{
+}
+
+CSSValueListImpl::~CSSValueListImpl()
+{
+ CSSValueImpl *val = m_values.first();
+ while( val ) {
+ val->deref();
+ val = m_values.next();
+ }
+}
+
+unsigned short CSSValueListImpl::valueType() const
+{
+ return CSSValue::CSS_VALUE_LIST;
+}
+
+void CSSValueListImpl::append(CSSValueImpl *val)
+{
+ m_values.append(val);
+ val->ref();
+}
+
+DOM::DOMString CSSValueListImpl::cssText() const
+{
+ // ###
+ return DOM::DOMString();
+}
+
+// -------------------------------------------------------------------------------------
+
+CSSPrimitiveValueImpl::CSSPrimitiveValueImpl()
+ : CSSValueImpl()
+{
+ m_type = 0;
+}
+
+CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(int ident)
+ : CSSValueImpl()
+{
+ m_value.ident = ident;
+ m_type = CSSPrimitiveValue::CSS_IDENT;
+}
+
+CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(float 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(const RGBColor &rgb)
+{
+ m_value.rgbcolor = new RGBColor(rgb);
+ m_type = CSSPrimitiveValue::CSS_RGBCOLOR;
+}
+
+CSSPrimitiveValueImpl::CSSPrimitiveValueImpl(const QColor &color)
+{
+ m_value.rgbcolor = new RGBColor(color);
+ m_type = CSSPrimitiveValue::CSS_RGBCOLOR;
+}
+
+CSSPrimitiveValueImpl::~CSSPrimitiveValueImpl()
+{
+ cleanup();
+}
+
+void CSSPrimitiveValueImpl::cleanup()
+{
+ if(m_type == CSSPrimitiveValue::CSS_RGBCOLOR)
+ delete m_value.rgbcolor;
+ else if(m_type < CSSPrimitiveValue::CSS_STRING || m_type == CSSPrimitiveValue::CSS_IDENT)
+ { }
+ else if(m_type < CSSPrimitiveValue::CSS_COUNTER)
+ if(m_value.string) m_value.string->deref();
+ else if(m_type == CSSPrimitiveValue::CSS_COUNTER)
+ m_value.counter->deref();
+ else if(m_type == CSSPrimitiveValue::CSS_RECT)
+ m_value.rect->deref();
+ m_type = 0;
+}
+
+unsigned short CSSPrimitiveValueImpl::primitiveType() const
+{
+ return m_type;
+}
+
+void CSSPrimitiveValueImpl::setFloatValue( unsigned short unitType, float floatValue, int &exceptioncode )
+{
+ exceptioncode = 0;
+ cleanup();
+ // ### check if property supports this type
+ if(m_type > CSSPrimitiveValue::CSS_DIMENSION) {
+ exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
+ return;
+ }
+ //if(m_type > CSSPrimitiveValue::CSS_DIMENSION) throw DOMException(DOMException::INVALID_ACCESS_ERR);
+ m_value.num = floatValue;
+ m_type = unitType;
+}
+
+float CSSPrimitiveValueImpl::getFloatValue( unsigned short /*unitType*/)
+{
+ return m_value.num;
+}
+
+void CSSPrimitiveValueImpl::setStringValue( unsigned short stringType, const DOMString &stringValue, int &exceptioncode )
+{
+ exceptioncode = 0;
+ cleanup();
+ //if(m_type < CSSPrimitiveValue::CSS_STRING) throw DOMException(DOMException::INVALID_ACCESS_ERR);
+ //if(m_type > CSSPrimitiveValue::CSS_ATTR) throw DOMException(DOMException::INVALID_ACCESS_ERR);
+ if(m_type < CSSPrimitiveValue::CSS_STRING || m_type >> CSSPrimitiveValue::CSS_ATTR) {
+ exceptioncode = CSSException::SYNTAX_ERR + CSSException::_EXCEPTION_OFFSET;
+ return;
+ }
+ if(stringType != CSSPrimitiveValue::CSS_IDENT)
+ {
+ m_value.string = stringValue.implementation();
+ m_value.string->ref();
+ m_type = stringType;
+ }
+ // ### parse ident
+}
+
+DOMStringImpl *CSSPrimitiveValueImpl::getStringValue( )
+{
+ if(m_type < CSSPrimitiveValue::CSS_STRING) return 0;
+ if(m_type > CSSPrimitiveValue::CSS_ATTR) return 0;
+ if(m_type == CSSPrimitiveValue::CSS_IDENT)
+ {
+ // ###
+ return 0;
+ }
+ return m_value.string;
+}
+
+CounterImpl *CSSPrimitiveValueImpl::getCounterValue( )
+{
+ if(m_type != CSSPrimitiveValue::CSS_COUNTER) return 0;
+ return m_value.counter;
+}
+
+RectImpl *CSSPrimitiveValueImpl::getRectValue( )
+{
+ if(m_type != CSSPrimitiveValue::CSS_RECT) return 0;
+ return m_value.rect;
+}
+
+RGBColor *CSSPrimitiveValueImpl::getRGBColorValue( )
+{
+ if(m_type != CSSPrimitiveValue::CSS_RGBCOLOR) return 0;
+ return m_value.rgbcolor;
+}
+
+unsigned short CSSPrimitiveValueImpl::valueType() const
+{
+ return CSSValue::CSS_PRIMITIVE_VALUE;
+}
+
+bool CSSPrimitiveValueImpl::parseString( const DOMString &/*string*/, bool )
+{
+ // ###
+ return false;
+}
+
+int CSSPrimitiveValueImpl::getIdent()
+{
+ if(m_type != CSSPrimitiveValue::CSS_IDENT) return 0;
+ return m_value.ident;
+}
+
+DOM::DOMString CSSPrimitiveValueImpl::cssText() const
+{
+ // ### return the original value instead of a generated one (e.g. color
+ // name if it was specified) - check what spec says about this
+ DOMString text;
+ switch ( m_type ) {
+ case CSSPrimitiveValue::CSS_UNKNOWN:
+ // ###
+ break;
+ case CSSPrimitiveValue::CSS_NUMBER:
+ text = DOMString(QString::number( (int)m_value.num ));
+ break;
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
+ text = DOMString(QString::number( m_value.num ) + "%");
+ break;
+ case CSSPrimitiveValue::CSS_EMS:
+ text = DOMString(QString::number( m_value.num ) + "em");
+ break;
+ case CSSPrimitiveValue::CSS_EXS:
+ text = DOMString(QString::number( m_value.num ) + "ex");
+ break;
+ case CSSPrimitiveValue::CSS_PX:
+ text = DOMString(QString::number( m_value.num ) + "px");
+ break;
+ case CSSPrimitiveValue::CSS_CM:
+ text = DOMString(QString::number( m_value.num ) + "cm");
+ break;
+ case CSSPrimitiveValue::CSS_MM:
+ text = DOMString(QString::number( m_value.num ) + "mm");
+ break;
+ case CSSPrimitiveValue::CSS_IN:
+ text = DOMString(QString::number( m_value.num ) + "in");
+ break;
+ case CSSPrimitiveValue::CSS_PT:
+ text = DOMString(QString::number( m_value.num ) + "pt");
+ break;
+ case CSSPrimitiveValue::CSS_PC:
+ text = DOMString(QString::number( m_value.num ) + "pc");
+ break;
+ case CSSPrimitiveValue::CSS_DEG:
+ text = DOMString(QString::number( m_value.num ) + "deg");
+ break;
+ case CSSPrimitiveValue::CSS_RAD:
+ text = DOMString(QString::number( m_value.num ) + "rad");
+ break;
+ case CSSPrimitiveValue::CSS_GRAD:
+ text = DOMString(QString::number( m_value.num ) + "grad");
+ break;
+ case CSSPrimitiveValue::CSS_MS:
+ text = DOMString(QString::number( m_value.num ) + "ms");
+ break;
+ case CSSPrimitiveValue::CSS_S:
+ text = DOMString(QString::number( m_value.num ) + "s");
+ break;
+ case CSSPrimitiveValue::CSS_HZ:
+ text = DOMString(QString::number( m_value.num ) + "hz");
+ break;
+ case CSSPrimitiveValue::CSS_KHZ:
+ text = DOMString(QString::number( m_value.num ) + "khz");
+ break;
+ case CSSPrimitiveValue::CSS_DIMENSION:
+ // ###
+ break;
+ case CSSPrimitiveValue::CSS_STRING:
+ // ###
+ break;
+ case CSSPrimitiveValue::CSS_URI:
+ text = DOMString( m_value.string );
+ break;
+ case CSSPrimitiveValue::CSS_IDENT:
+ text = getValueName(m_value.ident);
+ break;
+ case CSSPrimitiveValue::CSS_ATTR:
+ // ###
+ break;
+ case CSSPrimitiveValue::CSS_COUNTER:
+ // ###
+ break;
+ case CSSPrimitiveValue::CSS_RECT:
+ // ###
+ break;
+ case CSSPrimitiveValue::CSS_RGBCOLOR:
+ text = m_value.rgbcolor->color().name();
+ break;
+ default:
+ break;
+ }
+ return text;
+}
+
+// -----------------------------------------------------------------
+
+RectImpl::RectImpl()
+{
+ m_top = 0;
+ m_right = 0;
+ m_bottom = 0;
+ m_left = 0;
+}
+
+RectImpl::~RectImpl()
+{
+ if (m_top) m_top->deref();
+ if (m_right) m_right->deref();
+ if (m_bottom) m_bottom->deref();
+ if (m_left) m_left->deref();
+}
+
+void RectImpl::setTop( CSSPrimitiveValueImpl *top )
+{
+ if( top ) top->ref();
+ if ( m_top ) m_top->deref();
+ m_top = top;
+}
+
+void RectImpl::setRight( CSSPrimitiveValueImpl *right )
+{
+ if( right ) right->ref();
+ if ( m_right ) m_right->deref();
+ m_right = right;
+}
+
+void RectImpl::setBottom( CSSPrimitiveValueImpl *bottom )
+{
+ if( bottom ) bottom->ref();
+ if ( m_bottom ) m_bottom->deref();
+ m_bottom = bottom;
+}
+
+void RectImpl::setLeft( CSSPrimitiveValueImpl *left )
+{
+ if( left ) left->ref();
+ if ( m_left ) m_left->deref();
+ m_left = left;
+}
+
+// -----------------------------------------------------------------
+
+CSSImageValueImpl::CSSImageValueImpl(const DOMString &url, const DOMString &baseurl, StyleBaseImpl *style)
+ : CSSPrimitiveValueImpl(url, CSSPrimitiveValue::CSS_URI)
+{
+ khtml::DocLoader *docLoader = 0;
+ StyleBaseImpl *root = style;
+ while (root->parent())
+ root = root->parent();
+ if (root->isCSSStyleSheet())
+ docLoader = static_cast<CSSStyleSheetImpl*>(root)->docLoader();
+
+ if (docLoader)
+ m_image = docLoader->requestImage(url, baseurl);
+ else
+ m_image = khtml::Cache::requestImage(0, url, baseurl);
+
+ if(m_image) m_image->ref(this);
+}
+
+CSSImageValueImpl::CSSImageValueImpl()
+ : CSSPrimitiveValueImpl(CSS_VAL_NONE)
+{
+ m_image = 0;
+}
+
+CSSImageValueImpl::~CSSImageValueImpl()
+{
+ if(m_image) m_image->deref(this);
+}
+
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#ifndef _CSS_css_valueimpl_h_
+#define _CSS_css_valueimpl_h_
+
+#include <css_value.h>
+#include "dom_string.h"
+#include "cssparser.h"
+#include "misc/loader_client.h"
+
+#include <qintdict.h>
+
+namespace khtml {
+ class CachedImage;
+};
+
+namespace DOM {
+
+class CSSRuleImpl;
+class CSSValueImpl;
+class NodeImpl;
+class CounterImpl;
+
+
+class CSSStyleDeclarationImpl : public StyleBaseImpl
+{
+public:
+ CSSStyleDeclarationImpl(CSSRuleImpl *parentRule);
+ CSSStyleDeclarationImpl(CSSRuleImpl *parentRule, QList<CSSProperty> *lstValues);
+
+ virtual ~CSSStyleDeclarationImpl();
+
+ unsigned long length() const;
+ CSSRuleImpl *parentRule() const;
+ DOM::DOMString getPropertyValue ( const DOM::DOMString &propertyName );
+ DOM::DOMString getPropertyValue ( int id );
+ CSSValueImpl *getPropertyCSSValue ( const DOM::DOMString &propertyName );
+ bool removeProperty( int propertyID, bool onlyNonCSSHints );
+ DOM::DOMString removeProperty ( const DOM::DOMString &propertyName );
+ DOM::DOMString removeProperty ( int propertyId );
+ DOM::DOMString getPropertyPriority ( const DOM::DOMString &propertyName );
+ void setProperty ( const DOM::DOMString &propertyName, const DOM::DOMString &value,
+ const DOM::DOMString &priority );
+ void setProperty( const DOMString &propName, const DOMString &value, bool important, bool nonCSSHint);
+ void setProperty ( int propertyId, const DOM::DOMString &value, bool important = false, bool nonCSSHint = false);
+ void setProperty ( int propertyId, int value, bool important = false, bool nonCSSHint = false);
+ // this treats integers as pixels!
+ // needed for conversion of html attributes
+ void setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint = true);
+
+ // add a whole, unparsed property
+ void setProperty ( const DOMString &propertyString);
+ DOM::DOMString item ( unsigned long index );
+
+ DOM::DOMString cssText() const;
+ void setCssText(DOM::DOMString str);
+
+ virtual bool isStyleDeclaration() { return true; }
+
+ virtual bool parseString( const DOMString &string, bool = false );
+
+ CSSValueImpl *getPropertyCSSValue( int propertyID );
+ bool getPropertyPriority( int propertyID );
+
+ QList<CSSProperty> *values() { return m_lstValues; }
+ void setNode(NodeImpl *_node) { m_node = _node; }
+
+protected:
+ QList<CSSProperty> *m_lstValues;
+ NodeImpl *m_node;
+};
+
+class CSSValueImpl : public StyleBaseImpl
+{
+public:
+ CSSValueImpl();
+
+ virtual ~CSSValueImpl();
+
+ virtual unsigned short valueType() const = 0;
+ virtual unsigned short cssValueType() { return valueType(); }
+
+ virtual DOM::DOMString cssText() const;
+ void setCssText(DOM::DOMString str);
+
+ virtual bool isValue() { return true; }
+};
+
+class CSSInheritedValueImpl : public CSSValueImpl
+{
+public:
+ CSSInheritedValueImpl() : CSSValueImpl() {}
+ virtual ~CSSInheritedValueImpl() {}
+
+ virtual unsigned short valueType() const { return CSSValue::CSS_INHERIT; }
+ virtual DOM::DOMString cssText() const;
+};
+
+
+class CSSValueListImpl : public CSSValueImpl
+{
+public:
+ CSSValueListImpl();
+
+ virtual ~CSSValueListImpl();
+
+ unsigned long length() const { return m_values.count(); }
+ CSSValueImpl *item ( unsigned long index ) { return m_values.at(index); }
+
+ virtual bool isValueList() { return true; }
+
+ virtual unsigned short valueType() const;
+
+ void append(CSSValueImpl *val);
+ virtual DOM::DOMString cssText() const;
+
+protected:
+ QList<CSSValueImpl> m_values;
+};
+
+
+class Counter;
+class RGBColor;
+class Rect;
+
+class CSSPrimitiveValueImpl : public CSSValueImpl
+{
+public:
+ CSSPrimitiveValueImpl();
+ CSSPrimitiveValueImpl(int ident);
+ CSSPrimitiveValueImpl(float num, CSSPrimitiveValue::UnitTypes type);
+ CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type);
+ CSSPrimitiveValueImpl(const Counter &c);
+ CSSPrimitiveValueImpl( RectImpl *r);
+ CSSPrimitiveValueImpl(const RGBColor &rgb);
+ CSSPrimitiveValueImpl(const QColor &color);
+
+ virtual ~CSSPrimitiveValueImpl();
+
+ void cleanup();
+
+ unsigned short primitiveType() const;
+ // use with care!!!
+ void setPrimitiveType(unsigned short type) { m_type = type; }
+ void setFloatValue ( unsigned short unitType, float floatValue, int &exceptioncode );
+ float getFloatValue ( unsigned short unitType);
+ void setStringValue ( unsigned short stringType, const DOM::DOMString &stringValue, int &exceptioncode );
+ DOM::DOMStringImpl *getStringValue ( );
+ CounterImpl *getCounterValue ( );
+ RectImpl *getRectValue ( );
+ RGBColor *getRGBColorValue ( );
+
+ virtual bool isPrimitiveValue() { return true; }
+ virtual unsigned short valueType() const;
+
+ int getIdent();
+
+ virtual bool parseString( const DOMString &string, bool = false);
+ virtual DOM::DOMString cssText() const;
+
+protected:
+ int m_type;
+ union {
+ int ident;
+ float num;
+ DOM::DOMStringImpl *string;
+ CounterImpl *counter;
+ RectImpl *rect;
+ RGBColor *rgbcolor;
+ } m_value;
+};
+
+class CounterImpl : public DomShared {
+public:
+ CounterImpl() { m_identifier = 0; m_listStyle = 0; m_separator = 0; }
+ DOMString identifier() const { return m_identifier; }
+ DOMString listStyle() const { return m_listStyle; }
+ DOMString separator() const { return m_separator; }
+
+ DOMString m_identifier;
+ DOMString m_listStyle;
+ DOMString m_separator;
+};
+
+class RectImpl : public DomShared {
+public:
+ RectImpl();
+ ~RectImpl();
+
+ CSSPrimitiveValueImpl *top() { return m_top; }
+ CSSPrimitiveValueImpl *right() { return m_right; }
+ CSSPrimitiveValueImpl *bottom() { return m_bottom; }
+ CSSPrimitiveValueImpl *left() { return m_left; }
+
+ void setTop( CSSPrimitiveValueImpl *top );
+ void setRight( CSSPrimitiveValueImpl *right );
+ void setBottom( CSSPrimitiveValueImpl *bottom );
+ void setLeft( CSSPrimitiveValueImpl *left );
+protected:
+ CSSPrimitiveValueImpl *m_top;
+ CSSPrimitiveValueImpl *m_right;
+ CSSPrimitiveValueImpl *m_bottom;
+ CSSPrimitiveValueImpl *m_left;
+};
+
+class CSSImageValueImpl : public CSSPrimitiveValueImpl, public khtml::CachedObjectClient
+{
+public:
+ CSSImageValueImpl(const DOMString &url, const DOMString &baseurl, StyleBaseImpl *style);
+ CSSImageValueImpl();
+ virtual ~CSSImageValueImpl();
+
+ khtml::CachedImage *image() { return m_image; }
+protected:
+ khtml::CachedImage *m_image;
+};
+// ------------------------------------------------------------------------------
+
+}; // namespace
+
+#endif
--- /dev/null
+/*
+ * This file is part of the CSS implementation for KDE.
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#include "csshelper.h"
+
+#include <qfontmetrics.h>
+#include <qfontinfo.h>
+#include <qpaintdevice.h>
+#include <qpaintdevicemetrics.h>
+#include <qfontdatabase.h>
+
+#include <kcharsets.h>
+#include <kglobal.h>
+#include <kdebug.h>
+
+#include "rendering/render_style.h"
+#include "css_valueimpl.h"
+#include "dom/css_value.h"
+#include "misc/helper.h"
+#include "xml/dom_stringimpl.h"
+#include "khtml_settings.h"
+
+using namespace DOM;
+using namespace khtml;
+
+int khtml::computeLength(DOM::CSSPrimitiveValueImpl *val, RenderStyle *style, QPaintDeviceMetrics *devMetrics )
+{
+ return ( int ) computeLengthFloat( val, style, devMetrics );
+}
+
+float khtml::computeLengthFloat(DOM::CSSPrimitiveValueImpl *val, RenderStyle *style, QPaintDeviceMetrics *devMetrics )
+{
+ unsigned short type = val->primitiveType();
+
+ float dpiY = 72.; // fallback
+ if ( devMetrics )
+ dpiY = devMetrics->logicalDpiY();
+ if ( !khtml::printpainter && dpiY < 96 )
+ dpiY = 96.;
+
+ float factor = 1.;
+ switch(type)
+ {
+ case CSSPrimitiveValue::CSS_EMS:
+ factor = style->font().pixelSize();
+ break;
+ case CSSPrimitiveValue::CSS_EXS:
+ {
+ QFontMetrics fm = khtml::fontMetrics(style->font());
+ QRect b = fm.boundingRect('x');
+ factor = b.height();
+ break;
+ }
+ case CSSPrimitiveValue::CSS_PX:
+ break;
+ case CSSPrimitiveValue::CSS_CM:
+ factor = dpiY/2.54; //72dpi/(2.54 cm/in)
+ break;
+ case CSSPrimitiveValue::CSS_MM:
+ factor = dpiY/25.4;
+ break;
+ case CSSPrimitiveValue::CSS_IN:
+ factor = dpiY;
+ break;
+ case CSSPrimitiveValue::CSS_PT:
+ factor = dpiY/72.;
+ break;
+ case CSSPrimitiveValue::CSS_PC:
+ // 1 pc == 12 pt
+ factor = dpiY*12./72.;
+ break;
+ default:
+ return -1;
+ }
+ return val->getFloatValue(type)*factor;
+}
+
+DOMString khtml::parseURL(const DOMString &url)
+{
+ DOMStringImpl* i = url.implementation();
+ if(!i) return DOMString();
+
+ int o = 0;
+ int l = i->l;
+ while(o < l && (i->s[o] <= ' ')) { o++; l--; }
+ while(l > 0 && (i->s[o+l-1] <= ' ')) l--;
+
+ if(l >= 5 &&
+ (i->s[o].lower() == 'u') &&
+ (i->s[o+1].lower() == 'r') &&
+ (i->s[o+2].lower() == 'l') &&
+ i->s[o+3].latin1() == '(' &&
+ i->s[o+l-1].latin1() == ')') {
+ o += 4;
+ l -= 5;
+ }
+
+ while(o < l && (i->s[o] <= ' ')) { o++; l--; }
+ while(l > 0 && (i->s[o+l-1] <= ' ')) l--;
+
+ if(l >= 2 && i->s[o] == i->s[o+l-1] &&
+ (i->s[o].latin1() == '\'' || i->s[o].latin1() == '\"')) {
+ o++;
+ l -= 2;
+ }
+
+ while(o < l && (i->s[o] <= ' ')) { o++; l--; }
+ while(l > 0 && (i->s[o+l-1] <= ' ')) l--;
+
+ DOMStringImpl* j = new DOMStringImpl(i->s+o,l);
+
+ int nl = 0;
+ for(int k = o; k < o+l; k++)
+ if(i->s[k] == '\\')
+ j->s[nl++] = '/';
+ else if(i->s[k].unicode() > '\r')
+ j->s[nl++] = i->s[k];
+
+ j->l = nl;
+
+ return j;
+}
+
+
+void khtml::setFontSize( QFont &f, int pixelsize, const KHTMLSettings *s, QPaintDeviceMetrics *devMetrics )
+{
+ QFontDatabase db;
+
+ float size = pixelsize;
+
+ float toPix = 1.;
+ if ( !khtml::printpainter )
+ toPix = devMetrics->logicalDpiY()/72.;
+
+ // ok, now some magic to get a nice unscaled font
+ // ### all other font properties should be set before this one!!!!
+ // ####### make it use the charset needed!!!!
+ QFont::CharSet cs = s->charset();
+ QString charset = KGlobal::charsets()->xCharsetName( cs );
+
+ if( !db.isSmoothlyScalable(f.family(), db.styleString(f), charset) )
+ {
+ QValueList<int> pointSizes = db.smoothSizes(f.family(), db.styleString(f), charset);
+ // lets see if we find a nice looking font, which is not too far away
+ // from the requested one.
+ //kdDebug() << "khtml::setFontSize family = " << f.family() << " size requested=" << size << endl;
+
+ QValueList<int>::Iterator it;
+ float diff = 1; // ### 100% deviation
+ float bestSize = 0;
+ for( it = pointSizes.begin(); it != pointSizes.end(); ++it )
+ {
+ float newDiff = ((*it)*toPix - size)/size;
+ //kdDebug( 6080 ) << "smooth font size: " << *it << " diff=" << newDiff << endl;
+ if(newDiff < 0) newDiff = -newDiff;
+ if(newDiff < diff)
+ {
+ diff = newDiff;
+ bestSize = *it;
+ }
+ }
+ //kdDebug( 6080 ) << "best smooth font size: " << bestSize << " diff=" << diff << endl;
+ if ( bestSize != 0 && diff < 0.2 ) // 20% deviation, otherwise we use a scaled font...
+ size = bestSize*toPix;
+// else if ( size > 4 && size < 16 )
+// size = float( int( ( size + 1 ) / 2 )*2 );
+ }
+
+ //qDebug(" -->>> using %f pixel font", size);
+
+ f.setPixelSizeFloat( size );
+}
--- /dev/null
+/*
+ * This file is part of the CSS implementation for KDE.
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#ifndef css_helper_h
+#define css_helper_h
+
+#include <qcolor.h>
+#include <qfont.h>
+
+#include "dom/dom_string.h"
+
+class QPaintDeviceMetrics;
+class KHTMLSettings;
+
+namespace DOM
+{
+ class CSSPrimitiveValueImpl;
+};
+
+namespace khtml
+{
+ class RenderStyle;
+
+ /*
+ * computes a length in pixels out of the given CSSValue. Need the RenderStyle to get
+ * the fontinfo in case val is defined in em or ex.
+ *
+ * The metrics have to be a bit different for screen and printer output.
+ * For screen output we assume 1 inch == 72 px, for printer we assume 300 dpi
+ *
+ * this is screen/printer dependent, so we probably need a config option for this,
+ * and some tool to calibrate.
+ */
+ int computeLength(DOM::CSSPrimitiveValueImpl *val, RenderStyle *style, QPaintDeviceMetrics *devMetrics );
+
+ float computeLengthFloat(DOM::CSSPrimitiveValueImpl *val, RenderStyle *style, QPaintDeviceMetrics *devMetrics );
+
+ /*
+ * mostly just removes the url("...") brace
+ */
+ DOM::DOMString parseURL(const DOM::DOMString &url);
+
+ /*
+ Sets the font to the size closest to the requested one while trying not to use a scaled bitmap font
+ */
+ void setFontSize( QFont &f, int pixelSize, const KHTMLSettings *s, QPaintDeviceMetrics *devMetrics );
+
+};
+
+
+
+#endif
--- /dev/null
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * 1999 Waldo Bastian (bastian@kde.org)
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+//#define CSS_DEBUG
+//#define CSS_AURAL
+//#define CSS_DEBUG_BCKGR
+
+#include <assert.h>
+
+#include "css_stylesheetimpl.h"
+#include "css_stylesheet.h"
+#include "css_rule.h"
+#include "css_ruleimpl.h"
+#include "css_valueimpl.h"
+#include "csshelper.h"
+
+#include "dom_string.h"
+#include "xml/dom_nodeimpl.h"
+#include "html/html_documentimpl.h"
+#include "dom_exception.h"
+using namespace DOM;
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kglobalsettings.h> // For system fonts
+#include <kapp.h>
+
+#include "htmlhashes.h"
+#include "misc/helper.h"
+
+//
+// The following file defines the function
+// const struct props *findProp(const char *word, int len)
+//
+// with 'props->id' a CSS property in the range from CSS_PROP_MIN to
+// (and including) CSS_PROP_TOTAL-1
+#include "cssproperties.c"
+#include "cssvalues.c"
+
+int DOM::getPropertyID(const char *tagStr, int len)
+{
+ const struct props *propsPtr = findProp(tagStr, len);
+ if (!propsPtr)
+ return 0;
+
+ return propsPtr->id;
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+bool StyleBaseImpl::deleteMe()
+{
+ if(!m_parent && _ref <= 0) return true;
+ return false;
+}
+
+void StyleBaseImpl::checkLoaded()
+{
+ if(m_parent) m_parent->checkLoaded();
+}
+
+DOMString StyleBaseImpl::baseUrl()
+{
+ // try to find the style sheet. If found look for it's url.
+ // If it has none, look for the parentsheet, or the parentNode and
+ // try to find out about their url
+ StyleBaseImpl *b = this;
+ while(b && !b->isStyleSheet())
+ b = b->parent();
+
+ if(!b) return DOMString();
+
+ StyleSheetImpl *sheet = static_cast<StyleSheetImpl *>(b);
+ if(!sheet->href().isNull())
+ return sheet->href();
+
+ // find parent
+ if(sheet->parent()) return sheet->parent()->baseUrl();
+
+ if(!sheet->ownerNode()) return DOMString();
+
+ DocumentImpl *doc = static_cast<DocumentImpl*>(sheet->ownerNode()->nodeType() == Node::DOCUMENT_NODE ? sheet->ownerNode() : sheet->ownerNode()->ownerDocument());
+
+ return doc->baseURL();
+}
+
+/*
+ * parsing functions for stylesheets
+ */
+
+const QChar *
+StyleBaseImpl::parseSpace(const QChar *curP, const QChar *endP)
+{
+ bool sc = false; // possible start comment?
+ bool ec = false; // possible end comment?
+ bool ic = false; // in comment?
+
+ while (curP < endP)
+ {
+ if (ic)
+ {
+ if (ec && (*curP == '/'))
+ ic = false;
+ else if (*curP == '*')
+ ec = true;
+ else
+ ec = false;
+ }
+ else if (sc && (*curP == '*'))
+ {
+ ic = true;
+ }
+ else if (*curP == '/')
+ {
+ sc = true;
+ }
+ //else if (!isspace(*curP))
+ else if (!(curP->isSpace()))
+ {
+ return(curP);
+ }
+ else
+ {
+ sc = false;
+ }
+ curP++;
+ }
+
+ return(0);
+}
+
+/*
+ * ParseToChar
+ *
+ * Search for an expected character. Deals with escaped characters,
+ * quoted strings, and pairs of braces/parens/brackets.
+ */
+const QChar *
+StyleBaseImpl::parseToChar(const QChar *curP, const QChar *endP, QChar c, bool chkws, bool endAtBlock)
+{
+ //kdDebug( 6080 ) << "parsetochar: \"" << QString(curP, endP-curP) << "\" searching " << c << " ws=" << chkws << endl;
+
+ bool sq = false; /* in single quote? */
+ bool dq = false; /* in double quote? */
+ bool esc = false; /* escape mode? */
+
+ while (curP < endP)
+ {
+ if (esc)
+ esc = false;
+ else if (*curP == '\\')
+ esc = true;
+ else if (!sq && (*curP == '"'))
+ dq = !dq;
+ else if (!dq && (*curP == '\''))
+ sq = !sq;
+ else if (!sq && !dq && *curP == c)
+ return(curP);
+ else if (!sq && !dq && chkws && curP->isSpace()) //isspace(*curP))
+ return(curP);
+ else if(!sq && !dq ) {
+ if (*curP == '{') {
+ if(endAtBlock)
+ return curP;
+ curP = parseToChar(curP + 1, endP, '}', false);
+ if (!curP)
+ return(0);
+ } else if (*curP == '(') {
+ curP = parseToChar(curP + 1, endP, ')', false);
+ if (!curP)
+ return(0);
+ } else if (*curP == '[') {
+ curP = parseToChar(curP + 1, endP, ']', false);
+ if (!curP)
+ return(0);
+ }
+ }
+ curP++;
+ }
+
+ return(0);
+}
+
+CSSRuleImpl *
+StyleBaseImpl::parseAtRule(const QChar *&curP, const QChar *endP)
+{
+ curP++;
+ const QChar *startP = curP;
+ while( *curP != ' ' && *curP != '{' && *curP != '\'')
+ curP++;
+
+ QString rule(startP, curP-startP);
+ rule = rule.lower();
+
+ //kdDebug( 6080 ) << "rule = '" << rule << "'" << endl;
+
+ if(rule == "import")
+ {
+ // load stylesheet and pass it over
+ curP = parseSpace(curP, endP);
+ if(!curP) return 0;
+ startP = curP++;
+ curP = parseToChar(startP, endP, ';', true);
+ // Do not allow @import statements after explicity inlined
+ // declarations. They should simply be ignored per CSS-1
+ // specification section 3.0.
+ if( !curP || hasInlinedDecl ) return 0;
+ DOMString url = khtml::parseURL(DOMString(startP, curP - startP));
+ startP = curP;
+ if(*curP != ';')
+ curP = parseToChar(startP, endP, ';', false, true);
+ if(!curP) return 0;
+ QString media(startP, curP - startP);
+ media = media.stripWhiteSpace();
+ // ### check if at the beginning of the stylesheet (no style rule
+ // before the import rule)
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "at rule: url = '" << url.string()
+ << "' media = '" << media << "'"<< endl;
+#endif
+ // ignore block following @import rule
+ if( *curP == '{' ) {
+ curP++;
+ curP = parseToChar(curP, endP, '}', false);
+ if(curP)
+ curP++;
+ }
+ // ### only media="", "screen and "all" are imported for the moment...
+ // ### add at least "print" here once the MediaList class is implemented
+ if( !media.isEmpty() && !(media.contains("all") || media.contains("screen") ) )
+ return 0;
+ if(!this->isCSSStyleSheet()) return 0;
+ return new CSSImportRuleImpl(this, url, 0);
+ }
+ else if(rule == "charset")
+ {
+ // ### invoke decoder
+ startP = curP++;
+ curP = parseToChar(startP, endP, ';', false);
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "charset = " << QString(startP, curP - startP) << endl;
+#endif
+ }
+ else if(rule == "font-face")
+ {
+ startP = curP++;
+ curP = parseToChar(startP, endP, '{', false);
+ if ( !curP || curP >= endP ) return 0;
+ curP++;
+ curP = parseToChar(curP, endP, '}', false);
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "font rule = " << QString(startP, curP - startP) << endl;
+#endif
+ }
+ else if(rule == "media")
+ {
+ startP = curP++;
+ curP = parseToChar(startP, endP, '{', false);
+ //qDebug("mediaList = '%s'", mediaList.latin1() );
+ if ( !curP || curP >= endP ) return 0;
+ QString mediaList = QString( startP, curP - startP);
+ curP++;
+ startP = curP;
+ if ( curP >= endP ) return 0;
+ curP = parseToChar(curP, endP, '}', false);
+ if ( !curP || startP >= curP )
+ return 0;
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "media rule = " << QString(startP, curP - startP) << endl;
+#endif
+ if ( mediaList.contains( "screen" ) || mediaList.contains( "all" ) )
+ return parseStyleRule(startP, curP);
+ }
+ else if(rule == "page")
+ {
+ startP = curP++;
+ curP = parseToChar(startP, endP, '{', false);
+ if ( !curP || curP >= endP ) return 0;
+ curP++;
+ curP = parseToChar(curP, endP, '}', false);
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "page rule = " << QString(startP, curP - startP) << endl;
+#endif
+ }
+
+
+ return 0;
+}
+
+static DOMString getValue( const QChar *curP, const QChar *endP, const QChar *&endVal)
+{
+ //QString selecString( curP, endP - curP );
+ //kdDebug( 6080 ) << "getValue = \"" << selecString << "\"" << endl;
+ endVal = curP;
+ endVal++; // ignore first char (could be the ':' form the pseudo classes)
+ while( endVal < endP && *endVal != '.' && *endVal != ':' && *endVal != '[' )
+ endVal++;
+ const QChar *end = endVal;
+ if(endVal == endP)
+ endVal = 0;
+ return DOMString( curP, end - curP);
+}
+
+CSSSelector *
+StyleBaseImpl::parseSelector2(const QChar *curP, const QChar *endP,
+ CSSSelector::Relation relation)
+{
+ CSSSelector *cs = new CSSSelector();
+#ifdef CSS_DEBUG
+ QString selecString( curP, endP - curP );
+ kdDebug( 6080 ) << "selectString = \"" << selecString << "\"" << endl;
+#endif
+ const QChar *endVal = 0;
+
+ if (*curP == '#' && (curP < endP && !((*(curP+1)).isDigit())))
+ {
+ cs->tag = -1;
+ cs->attr = ATTR_ID;
+ cs->match = CSSSelector::Exact;
+ cs->value = getValue( curP+1, endP, endVal);
+ }
+ else if (*curP == '.' && (curP < endP && !((*(curP+1)).isDigit())))
+ {
+ cs->tag = -1;
+ cs->attr = ATTR_CLASS;
+ cs->match = CSSSelector::List;
+ cs->value = getValue( curP+1, endP, endVal);
+ }
+ else if (*curP == ':' && (curP < endP && !((*(curP+1)).isDigit())))
+ {
+ // pseudo attributes (:link, :hover, ...), they are case insensitive.
+ cs->tag = -1;
+ cs->match = CSSSelector::Pseudo;
+ cs->value = getValue(curP+1, endP, endVal);
+ cs->value = cs->value.implementation()->lower();
+ }
+ else
+ {
+ const QChar *startP = curP;
+ QString tag;
+ while (curP < endP)
+ {
+ if (*curP =='#' && (curP < endP && !((*(curP+1)).isDigit())))
+ {
+ tag = QString( startP, curP-startP );
+ cs->attr = ATTR_ID;
+ cs->match = CSSSelector::Exact;
+ cs->value = getValue(curP+1, endP, endVal);
+ break;
+ }
+ else if (*curP == '.' && (curP < endP && !((*(curP+1)).isDigit())))
+ {
+ tag = QString( startP, curP - startP );
+ cs->attr = ATTR_CLASS;
+ cs->match = CSSSelector::List;
+ cs->value = getValue(curP+1, endP, endVal);
+ break;
+ }
+ else if (*curP == ':' && (curP < endP && !((*(curP+1)).isDigit())))
+ {
+ // pseudo attributes (:link, :hover, ...), they are case insensitive.
+ tag = QString( startP, curP - startP );
+ cs->match = CSSSelector::Pseudo;
+ cs->value = getValue(curP+1, endP, endVal);
+ cs->value = cs->value.implementation()->lower();
+ break;
+ }
+ else if (*curP == '[')
+ {
+ tag = QString( startP, curP - startP );
+ curP++;
+ if ( curP >= endP ) {
+ delete cs;
+ return 0;
+ }
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "tag = " << tag << endl;
+#endif
+ const QChar *closebracket = parseToChar(curP, endP, ']', false);
+ if (!closebracket)
+ {
+ kdWarning()<<"error in css: closing bracket not found!"<<endl;
+ return 0;
+ }
+ QString attr;
+ const QChar *equal = parseToChar(curP, closebracket, '=', false);
+ if(!equal)
+ {
+ attr = QString( curP, closebracket - curP );
+ attr = attr.stripWhiteSpace();
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "attr = '" << attr << "'" << endl;
+#endif
+ cs->match = CSSSelector::Set;
+ endVal = closebracket + 1;
+ }
+ else
+ {
+ // check relation: = / ~= / |=
+ if(*(equal-1) == '~')
+ {
+ attr = QString( curP, equal - curP - 1 );
+ cs->match = CSSSelector::List;
+ }
+ else if(*(equal-1) == '|')
+ {
+ attr = QString( curP, equal - curP - 1 );
+ cs->match = CSSSelector::Hyphen;
+ }
+ else
+ {
+ attr = QString(curP, equal - curP );
+ cs->match = CSSSelector::Exact;
+ }
+ }
+ attr = attr.stripWhiteSpace();
+ cs->attr = khtml::getAttrID(attr.ascii(), attr.length());
+ if(equal)
+ {
+ equal++;
+ while(equal < endP && *equal == ' ')
+ equal++;
+ if(equal >= endP ) {
+ delete cs;
+ return 0;
+ }
+ endVal = equal;
+ bool hasQuote = false;
+ if(*equal == '\'') {
+ equal++;
+ endVal++;
+ while(endVal < endP && *endVal != '\'')
+ endVal++;
+ hasQuote = true;
+ } else if(*equal == '\"') {
+ equal++;
+ endVal++;
+ while(endVal < endP && *endVal != '\"')
+ endVal++;
+ hasQuote = true;
+ } else {
+ while(endVal < endP && *endVal != ']')
+ endVal++;
+ }
+ cs->value = DOMString(equal, endVal - equal);
+ if ( hasQuote ) {
+ while( endVal < endP - 1 && *endVal != ']' )
+ endVal++;
+ }
+ endVal++;
+ // ### fixme we ignore everything after [..]
+ if( endVal == endP )
+ endVal = 0;
+ }
+ break;
+ }
+ else
+ {
+ curP++;
+ }
+ }
+ if (curP == endP)
+ {
+ tag = QString( startP, curP - startP );
+ }
+ if(tag == "*")
+ {
+ //kdDebug( 6080 ) << "found '*' selector" << endl;
+ cs->tag = -1;
+ }
+ else {
+ StyleBaseImpl *root = this;
+ DocumentImpl *doc = 0;
+ while (root->parent())
+ root = root->parent();
+ if (root->isCSSStyleSheet())
+ doc = static_cast<CSSStyleSheetImpl*>(root)->doc();
+ if (doc && !doc->isHTMLDocument()) {
+ const DOMString s = tag;
+ cs->tag = doc->elementId(s.implementation());
+ } else {
+ int tagID = khtml::getTagID(tag.lower().ascii(), tag.length());
+ if (tagID != 0) {
+ cs->tag = tagID;
+ } else if (!(tag.isEmpty())) {
+ const DOMString s = tag;
+ cs->tag = doc->elementId(s.implementation());
+ } else {
+ kdWarning() << "Error in CSS" << endl;
+ }
+ }
+ }
+ }
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "[Selector: tag=" << cs->tag << " Attribute=" << cs->attr << " match=" << (int)cs->match << " value=" << cs->value.string() << " specificity=" << cs->specificity() << "]" << endl;
+#endif
+
+
+ //stack->print();
+ if( endVal ) {
+ // lets be recursive
+ relation = CSSSelector::SubSelector;
+ CSSSelector *stack = parseSelector2(endVal, endP, relation);
+ cs->tagHistory = stack;
+ cs->relation = relation;
+ }
+
+ return cs;
+}
+
+CSSSelector *
+StyleBaseImpl::parseSelector1(const QChar *curP, const QChar *endP)
+{
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "selector1 is \'" << QString(curP, endP-curP) << "\'" << endl;
+#endif
+
+ CSSSelector *selecStack=0;
+
+ curP = parseSpace(curP, endP);
+ if (!curP)
+ return(0);
+
+ CSSSelector::Relation relation = CSSSelector::Descendant;
+
+ const QChar *startP = curP;
+ while (curP && curP <= endP)
+ {
+ if ((curP == endP) || curP->isSpace() || *curP == '+' || *curP == '>')
+ {
+ CSSSelector *newsel = parseSelector2(startP, curP, relation);
+ if (!newsel) {
+ delete selecStack;
+ return 0;
+ }
+ CSSSelector *end = newsel;
+ while( end->tagHistory )
+ end = end->tagHistory;
+ end->tagHistory = selecStack;
+ end->relation = relation;
+ selecStack = newsel;
+
+ curP = parseSpace(curP, endP);
+ if (!curP) {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "selector stack is:" << endl;
+ selecStack->print();
+ kdDebug( 6080 ) << endl;
+#endif
+ return(selecStack);
+ }
+ relation = CSSSelector::Descendant;
+ if(*curP == '+')
+ {
+ relation = CSSSelector::Sibling;
+ curP++;
+ curP = parseSpace(curP, endP);
+ }
+ else if(*curP == '>')
+ {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "child selector" << endl;
+#endif
+ relation = CSSSelector::Child;
+ curP++;
+ curP = parseSpace(curP, endP);
+ }
+ //if(selecStack)
+ // selecStack->print();
+ startP = curP;
+ }
+ else
+ {
+ curP++;
+ }
+ }
+#ifdef CSS_DEBUG
+ selecStack->print();
+#endif
+ return(selecStack);
+}
+
+QList<CSSSelector> *
+StyleBaseImpl::parseSelector(const QChar *curP, const QChar *endP)
+{
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "selector is \'" << QString(curP, endP-curP) << "\'" << endl;
+#endif
+
+ QList<CSSSelector> *slist = 0;
+ const QChar *startP;
+
+ while (curP < endP)
+ {
+ startP = curP;
+ curP = parseToChar(curP, endP, ',', false);
+ if (!curP)
+ curP = endP;
+
+ CSSSelector *selector = parseSelector1(startP, curP);
+ if (selector)
+ {
+ if (!slist)
+ {
+ slist = new QList<CSSSelector>;
+ slist->setAutoDelete(true);
+ }
+ slist->append(selector);
+ }
+ else
+ {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "invalid selector" << endl;
+#endif
+ // invalid selector, delete
+ delete slist;
+ return 0;
+ }
+ curP++;
+ }
+ return slist;
+}
+
+
+void StyleBaseImpl::parseProperty(const QChar *curP, const QChar *endP)
+{
+ m_bImportant = false;
+ // Get rid of space in front of the declaration
+
+ curP = parseSpace(curP, endP);
+ if (!curP)
+ return;
+
+ // Search for the required colon or white space
+ const QChar *colon = parseToChar(curP, endP, ':', true);
+ if (!colon)
+ return;
+
+ const QString propName( curP, colon - curP );
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "Property-name = \"" << propName << "\"" << endl;
+#endif
+
+ // May have only reached white space before
+ if (*colon != ':')
+ {
+ // Search for the required colon
+ colon = parseToChar(curP, endP, ':', false);
+ if (!colon)
+ return;
+ }
+ curP = colon+1;
+ // remove space in front of the value
+ while(curP < endP && *curP == ' ')
+ curP++;
+ if ( curP >= endP )
+ return;
+
+ // search for !important
+ const QChar *exclam = parseToChar(curP, endP, '!', false);
+ if(exclam)
+ {
+ //const QChar *imp = parseSpace(exclam+1, endP);
+ QString s(exclam+1, endP - exclam - 1);
+ s = s.stripWhiteSpace();
+ s = s.lower();
+ if(s != "important")
+ return;
+ m_bImportant = true;
+ endP = exclam;
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "important property!" << endl;
+#endif
+ }
+
+ // remove space after the value;
+ while (endP > curP)
+ {
+ //if (!isspace(*(endP-1)))
+ if (!((endP-1)->isSpace()))
+ break;
+ endP--;
+ }
+
+#ifdef CSS_DEBUG
+ QString propVal( curP , endP - curP );
+ kdDebug( 6080 ) << "Property-value = \"" << propVal.latin1() << "\"" << endl;
+#endif
+
+ const struct props *propPtr = findProp(propName.lower().ascii(), propName.length());
+ if (!propPtr)
+ {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "Unknown property" << propName << endl;
+#endif
+ return;
+ }
+
+ unsigned int numProps = m_propList->count();
+ if(!parseValue(curP, endP, propPtr->id)) {
+#ifdef CSS_DEBUG
+ kdDebug(6080) << "invalid property, removing added properties from m_propList" << endl;
+#endif
+ while(m_propList->count() > numProps)
+ m_propList->removeLast();
+ }
+}
+
+QList<CSSProperty> *StyleBaseImpl::parseProperties(const QChar *curP, const QChar *endP)
+{
+ m_propList = new QList<CSSProperty>;
+ m_propList->setAutoDelete(true);
+ while (curP < endP)
+ {
+ const QChar *startP = curP;
+ curP = parseToChar(curP, endP, ';', false);
+ if (!curP)
+ curP = endP;
+
+#ifdef CSS_DEBUG
+ QString propVal( startP , curP - startP );
+ kdDebug( 6080 ) << "Property = \"" << propVal.latin1() << "\"" << endl;
+#endif
+
+ parseProperty(startP, curP);
+ curP++;
+ }
+ if(!m_propList->isEmpty()) {
+ return m_propList;
+ } else {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "empty property list" << endl;
+#endif
+ delete m_propList;
+ return 0;
+ }
+}
+
+static const QChar *getNext( const QChar *curP, const QChar *endP, bool &last )
+{
+ last = false;
+ const QChar *nextP = curP;
+ bool ignoreSpace = false;
+ while(nextP <= endP) {
+ if ( *nextP == '(' ) {
+ ignoreSpace = true;
+ } else if ( *nextP == ')' ) {
+ ignoreSpace = false;
+ }
+ if ( *nextP == ' ' && !ignoreSpace ) {
+ if (nextP == endP) {
+ last = true;
+ }
+ break;
+ }
+ if ( *nextP == ';' || nextP == endP ) {
+ last = true;
+ break;
+ }
+ nextP++;
+ }
+ return nextP;
+}
+// ------------------- begin font property ---------------------
+/*
+ Parser for the font property of CSS. See
+ http://www.w3.org/TR/REC-CSS2/fonts.html#propdef-font for details.
+
+ Written by Jasmin Blanchette (jasmin@trolltech.com) on 2000-08-16.
+*/
+
+class FontParser {
+public:
+ enum { TOK_NONE, TOK_EOI, TOK_SLASH, TOK_COMMA, TOK_STRING, TOK_SYMBOL };
+
+ QChar m_yyChar;
+ QString m_yyIn, m_yyStr;
+ unsigned int m_yyPos;
+ int m_yyTok;
+ bool strictParsing;
+
+ int getChar() {
+ return ( m_yyPos == m_yyIn.length() ) ? QChar('\0') : QChar(m_yyIn[m_yyPos++]);
+ }
+
+ void startTokenizer( const QString& str, bool _strictParsing ) {
+ m_yyIn = str.simplifyWhiteSpace();
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "startTokenizer: [" << m_yyIn << "]" << endl;
+#endif
+ m_yyPos = 0;
+ m_yyChar = getChar();
+ strictParsing = _strictParsing;
+ m_yyTok = TOK_NONE;
+ }
+
+ int getToken()
+ {
+ m_yyStr = QString::null;
+
+ if ( m_yyChar == '\0' )
+ return TOK_EOI;
+ if ( m_yyChar == QChar(' ') )
+ m_yyChar = getChar();
+
+ if ( m_yyChar == QChar('/') ) {
+ m_yyChar = getChar();
+ return TOK_SLASH;
+ } else if ( m_yyChar == QChar(',') ) {
+ m_yyChar = getChar();
+ return TOK_COMMA;
+ } else if ( m_yyChar == QChar('"') ) {
+ m_yyChar = getChar();
+ while ( m_yyChar != QChar('"') && m_yyChar != '\0' ) {
+ m_yyStr += m_yyChar;
+ m_yyChar = getChar();
+ }
+ m_yyChar = getChar();
+ return TOK_STRING;
+ } else if ( m_yyChar == QChar('\'') ) {
+ m_yyChar = getChar();
+ while ( m_yyChar != QChar('\'') && m_yyChar != '\0' ) {
+ m_yyStr += m_yyChar;
+ m_yyChar = getChar();
+ }
+ m_yyChar = getChar();
+ return TOK_STRING;
+ } else {
+ while ( m_yyChar != '/' && m_yyChar != ',' && m_yyChar != '\0' && m_yyChar != ' ') {
+ m_yyStr += m_yyChar;
+ m_yyChar = getChar();
+ }
+ return TOK_SYMBOL;
+ }
+ }
+
+ bool match( int tok )
+ {
+ if ( m_yyTok == tok ) {
+ m_yyTok = getToken();
+ return true;
+ }
+ return false;
+ }
+
+ bool matchFontStyle( QString *fstyle )
+ {
+ if ( m_yyTok == TOK_SYMBOL ) {
+ const struct css_value *cssval = findValue(m_yyStr.latin1(), m_yyStr.length());
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_NORMAL || id == CSS_VAL_ITALIC ||
+ id == CSS_VAL_OBLIQUE || id == CSS_VAL_INHERIT ) {
+ *fstyle = m_yyStr;
+ m_yyTok = getToken();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool matchFontVariant( QString *fvariant )
+ {
+ if ( m_yyTok == TOK_SYMBOL ) {
+ const struct css_value *cssval = findValue(m_yyStr.latin1(), m_yyStr.length());
+ if (cssval) {
+ int id = cssval->id;
+ if (id == CSS_VAL_NORMAL || id == CSS_VAL_SMALL_CAPS || id == CSS_VAL_INHERIT) {
+ *fvariant = m_yyStr;
+ m_yyTok = getToken();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool matchFontWeight( QString *fweight )
+ {
+ if ( m_yyTok == TOK_SYMBOL ) {
+ const struct css_value *cssval = findValue(m_yyStr.latin1(), m_yyStr.length());
+ if (cssval) {
+ int id = cssval->id;
+ if ((id >= CSS_VAL_NORMAL && id <= CSS_VAL_900) || id == CSS_VAL_INHERIT ) {
+ *fweight = m_yyStr;
+ m_yyTok = getToken();
+ return true;
+ }
+ }
+ }
+ return false ;
+ }
+
+ bool matchFontSize( QString *fsize )
+ {
+ if ( m_yyTok == TOK_SYMBOL ) {
+ *fsize = m_yyStr;
+ m_yyTok = getToken();
+ return true;
+ }
+ return false;
+ }
+
+ bool matchLineHeight( QString *lheight )
+ {
+ if ( m_yyTok == TOK_SYMBOL ) {
+ *lheight = m_yyStr;
+ m_yyTok = getToken();
+ return true;
+ }
+ return false;
+ }
+
+ bool matchNameFamily( QString *ffamily )
+ {
+ //kdDebug( 6080 ) << "matchNameFamily: [" << *ffamily << "]" << endl;
+ bool matched = false;
+ if ( m_yyTok == TOK_SYMBOL || ( m_yyTok == TOK_STRING && !strictParsing ) ) {
+ // accept quoted "serif" only in non strict mode.
+ *ffamily = m_yyStr;
+ // unquoted courier new should return courier new
+ while( (m_yyTok = getToken()) == TOK_SYMBOL ) {
+ *ffamily += " " + m_yyStr;
+ }
+ matched = true;
+ } else if ( m_yyTok == TOK_STRING ) {
+ //kdDebug( 6080 ) << "[" << m_yyStr << "]" << endl;
+ const struct css_value *cssval = findValue(m_yyStr.latin1(), m_yyStr.length());
+ if (!cssval || !(cssval->id >= CSS_VAL_SERIF && cssval->id <= CSS_VAL_MONOSPACE)) {
+ *ffamily = m_yyStr;
+ m_yyTok = getToken();
+ matched = true;
+ }
+ }
+ return matched;
+ }
+
+ bool matchFontFamily( QString *ffamily )
+ {
+ //kdDebug( 6080 ) << "matchFontFamily: [" << *ffamily << "]" << endl;
+ QStringList t;
+ if ( !matchFontFamily( &t ) )
+ return false;
+
+ *ffamily = t.join(", ");
+ return TRUE;
+ }
+
+ bool matchFontFamily ( QStringList *ffamily )
+ {
+ if ( m_yyTok == TOK_NONE )
+ m_yyTok = getToken();
+#if 0
+ // ###
+ if ( m_yyTok == TOK_STRING && m_yyStr == "inherit" ) {
+ ffamily->clear();
+ m_yyTok = getToken();
+ return TRUE;
+ }
+#endif
+
+ QString name;
+ do {
+ if ( !matchNameFamily(&name) )
+ return FALSE;
+ ffamily->append( name );
+ } while ( match(TOK_COMMA) );
+
+ return true;
+ }
+
+ bool matchRealFont( QString *fstyle, QString *fvariant, QString *fweight,
+ QString *fsize, QString *lheight, QString *ffamily )
+ {
+ //kdDebug( 6080 ) << "matchRealFont(..)" << endl;
+ bool metFstyle = matchFontStyle( fstyle );
+ bool metFvariant = matchFontVariant( fvariant );
+ matchFontWeight( fweight );
+ if ( !metFstyle )
+ metFstyle = matchFontStyle( fstyle );
+ if ( !metFvariant )
+ matchFontVariant( fvariant );
+ if ( !metFstyle )
+ matchFontStyle( fstyle );
+
+ if ( !matchFontSize(fsize) )
+ return FALSE;
+ if ( match(TOK_SLASH) ) {
+ if ( !matchLineHeight(lheight) )
+ return FALSE;
+ }
+ if ( !matchFontFamily(ffamily) )
+ return FALSE;
+ return true;
+ }
+};
+
+bool StyleBaseImpl::parseFont(const QChar *curP, const QChar *endP)
+{
+ QString str( curP, endP - curP );
+ QString fstyle, fvariant, fweight, fsize, lheight, ffamily;
+
+ FontParser fontParser;
+ fontParser.startTokenizer( str, strictParsing );
+
+ //kdDebug( 6080 ) << str << endl;
+ const struct css_value *cssval = findValue(fontParser.m_yyIn.latin1(), fontParser.m_yyIn.length());
+
+ if (cssval) {
+ //kdDebug( 6080 ) << "System fonts requested: [" << str << "]" << endl;
+ QFont sysFont;
+ switch (cssval->id) {
+ case CSS_VAL_MENU:
+ sysFont = KGlobalSettings::menuFont();
+ break;
+ case CSS_VAL_CAPTION:
+ sysFont = KGlobalSettings::windowTitleFont();
+ break;
+ case CSS_VAL_STATUS_BAR:
+ case CSS_VAL_ICON:
+ case CSS_VAL_MESSAGE_BOX:
+ case CSS_VAL_SMALL_CAPTION:
+ default:
+ sysFont = KGlobalSettings::generalFont();
+ break;
+ }
+ if (sysFont.italic()) {
+ fstyle = "italic";
+ } else {
+ fstyle = "normal";
+ }
+ if (sysFont.bold()) {
+ fweight = "bold";
+ } else {
+ fweight = "normal";
+ }
+ fsize.sprintf("%dpx", sysFont.pixelSize());
+ ffamily = sysFont.family();
+
+ } else {
+ fontParser.m_yyTok = fontParser.getToken();
+ if (!(fontParser.matchRealFont(&fstyle, &fvariant, &fweight, &fsize, &lheight, &ffamily)))
+ {
+ return false;
+ }
+ }
+ //kdDebug(6080) << "[" << fstyle << "] [" << fvariant << "] [" << fweight << "] ["
+ // << fsize << "] / [" << lheight << "] [" << ffamily << "]" << endl;
+
+ if(!fstyle.isNull())
+ parseValue(fstyle.unicode(), fstyle.unicode()+fstyle.length(), CSS_PROP_FONT_STYLE);
+ if(!fvariant.isNull())
+ parseValue(fvariant.unicode(), fvariant.unicode()+fvariant.length(), CSS_PROP_FONT_VARIANT);
+ if(!fweight.isNull())
+ parseValue(fweight.unicode(), fweight.unicode()+fweight.length(), CSS_PROP_FONT_WEIGHT);
+ if(!fsize.isNull())
+ parseValue(fsize.unicode(), fsize.unicode()+fsize.length(), CSS_PROP_FONT_SIZE);
+ if(!lheight.isNull())
+ parseValue(lheight.unicode(), lheight.unicode()+lheight.length(), CSS_PROP_LINE_HEIGHT);
+ if(!ffamily.isNull())
+ parseValue(ffamily.unicode(), ffamily.unicode()+ffamily.length(), CSS_PROP_FONT_FAMILY);
+ return true;
+}
+
+// ---------------- end font property --------------------------
+
+bool StyleBaseImpl::parseValue( const QChar *curP, const QChar *endP, int propId, bool important,
+ QList<CSSProperty> *propList)
+{
+ m_bImportant = important;
+ m_propList = propList;
+ return parseValue(curP, endP, propId);
+}
+
+bool StyleBaseImpl::parseValue( const QChar *curP, const QChar *endP, int propId)
+{
+ if (curP==endP) {return 0; /* e.g.: width="" */}
+
+ QString value(curP, endP - curP);
+ value = value.lower().stripWhiteSpace();
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "id [" << getPropertyName(propId).string() << "] parseValue [" << value << "]" << endl;
+#endif
+ int len = value.length();
+ const char *val = value.latin1();
+
+ CSSValueImpl *parsedValue = 0;
+
+ // We are using this so often
+ const struct css_value *cssval = findValue(val, len);
+ if (cssval && cssval->id == CSS_VAL_INHERIT) {
+ parsedValue = new CSSInheritedValueImpl(); // inherited value
+ } else {
+ switch(propId)
+ {
+ /* The comment to the left defines all valid value of this properties as defined
+ * in CSS 2, Appendix F. Property index
+ */
+
+ /* All the CSS properties are not supported by the renderer at the moment.
+ * Note that all the CSS2 Aural properties are only checked, if CSS_AURAL is defined
+ * (see parseAuralValues). As we don't support them at all this seems reasonable.
+ */
+
+ case CSS_PROP_SIZE: // <length>{1,2} | auto | portrait | landscape | inherit
+ case CSS_PROP_QUOTES: // [<string> <string>]+ | none | inherit
+ case CSS_PROP_TEXT_SHADOW: // none | [<color> || <length> <length> <length>? ,]*
+ // [<color> || <length> <length> <length>?] | inherit
+ case CSS_PROP_CONTENT: // [ <string> | <uri> | <counter> | attr(X) | open-quote |
+ // close-quote | no-open-quote | no-close-quote ]+ | inherit
+ case CSS_PROP_UNICODE_BIDI: // normal | embed | bidi-override | inherit
+ case CSS_PROP_WHITE_SPACE: // normal | pre | nowrap | inherit
+ case CSS_PROP_FONT_STRETCH:
+ // normal | wider | narrower | ultra-condensed | extra-condensed | condensed |
+ // semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded |
+ // inherit
+ case CSS_PROP_PAGE: // <identifier> | auto // ### CHECK
+ case CSS_PROP_PAGE_BREAK_AFTER: // auto | always | avoid | left | right | inherit
+ case CSS_PROP_PAGE_BREAK_BEFORE: // auto | always | avoid | left | right | inherit
+ case CSS_PROP_PAGE_BREAK_INSIDE: // avoid | auto | inherit
+ case CSS_PROP_POSITION: // static | relative | absolute | fixed | inherit
+ case CSS_PROP_EMPTY_CELLS: // show | hide | inherit
+ case CSS_PROP_TABLE_LAYOUT: // auto | fixed | inherit
+ {
+ const struct css_value *cssval = findValue(val, len);
+ if (cssval)
+ {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ }
+ // ### To be done
+ break;
+ }
+
+ case CSS_PROP_CLIP: // <shape> | auto | inherit
+ {
+ int i;
+ if ( cssval && cssval->id == CSS_VAL_AUTO )
+ parsedValue = new CSSPrimitiveValueImpl( cssval->id );
+ else {
+ // only shape in CSS2 is rect( top right bottom left )
+ QString str = QConstString( const_cast<QChar*>( curP ), endP - curP ).string();
+ // the CSS specs are not really clear if there should be commas in here or not. We accept both spaces and commas.
+ str.replace( QRegExp( "," ), " " );
+ str = str.simplifyWhiteSpace();
+ if ( str.find( "rect", 0, false ) != 0 )
+ break;
+ int pos = str.find( '(', 4 );
+ int end = str.findRev( ')' );
+ if ( end <= pos )
+ break;
+ str = str.mid( pos + 1, end - pos - 1 );
+ str = str.simplifyWhiteSpace();
+ str += " ";
+ //qDebug("rect = '%s'", str.latin1() );
+
+ pos = 0;
+ RectImpl *rect = new RectImpl();
+ for ( i = 0; i < 4; i++ ) {
+ int space;
+ space = str.find( ' ', pos );
+ const QChar *start = str.unicode() + pos;
+ const QChar *end = str.unicode() + space;
+ //qDebug("part: from=%d, to=%d", pos, space );
+ if ( start >= end )
+ goto cleanup;
+ CSSPrimitiveValueImpl *length = 0;
+ if ( str.find( "auto", pos, FALSE ) == pos )
+ length = new CSSPrimitiveValueImpl(value, CSSPrimitiveValue::CSS_PX);
+ else
+ length = parseUnit( start, end, LENGTH );
+ if ( !length )
+ goto cleanup;
+ switch ( i ) {
+ case 0:
+ rect->setTop( length );
+ break;
+ case 1:
+ rect->setRight( length );
+ break;
+ case 2:
+ rect->setBottom( length );
+ break;
+ case 3:
+ rect->setLeft( length );
+ break;
+ }
+ pos = space + 1;
+ }
+ parsedValue = new CSSPrimitiveValueImpl( rect );
+ //qDebug(" passed rectangle parsing");
+ break;
+
+ cleanup:
+ qDebug(" rectangle parsing failed, i=%d", i);
+ delete rect;
+ }
+ break;
+ }
+
+ /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
+ * correctly and allows optimization in khtml::applyRule(..)
+ */
+ case CSS_PROP_CAPTION_SIDE: // top | bottom | left | right | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT || id == CSS_VAL_TOP || id == CSS_VAL_BOTTOM) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_BORDER_COLLAPSE: // collapse | separate | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_COLLAPSE || id == CSS_VAL_SEPARATE ) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_VISIBILITY: // visible | hidden | collapse | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_COLLAPSE) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_OVERFLOW: // visible | hidden | scroll | auto | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_VISIBLE || id == CSS_VAL_HIDDEN || id == CSS_VAL_SCROLL || id == CSS_VAL_AUTO ) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_LIST_STYLE_POSITION: // inside | outside | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_INSIDE || id == CSS_VAL_OUTSIDE ) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_LIST_STYLE_TYPE:
+ // disc | circle | square | decimal | decimal-leading-zero | lower-roman |
+ // upper-roman | lower-greek | lower-alpha | lower-latin | upper-alpha |
+ // upper-latin | hebrew | armenian | georgian | cjk-ideographic | hiragana |
+ // katakana | hiragana-iroha | katakana-iroha | none | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ((id >= CSS_VAL_CIRCLE && id <= CSS_VAL_KATAKANA_IROHA) || id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_DISPLAY:
+ // inline | block | list-item | run-in | compact | -konq-ruler | marker | table |
+ // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
+ // table-column-group | table-column | table-cell | table-caption | none | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ((id >= CSS_VAL_INLINE && id <= CSS_VAL_TABLE_CAPTION) || id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_DIRECTION: // ltr | rtl | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_LTR || id == CSS_VAL_RTL ) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_TEXT_TRANSFORM: // capitalize | uppercase | lowercase | none | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ((id >= CSS_VAL_CAPITALIZE && id <= CSS_VAL_LOWERCASE) || id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_FLOAT: // left | right | none | inherit + center for buggy CSS
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id == CSS_VAL_LEFT || id == CSS_VAL_RIGHT
+ || id == CSS_VAL_NONE || id == CSS_VAL_CENTER) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_CLEAR: // none | left | right | both | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id == CSS_VAL_NONE || id == CSS_VAL_LEFT
+ || id == CSS_VAL_RIGHT|| id == CSS_VAL_BOTH) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_TEXT_ALIGN:
+ // left | right | center | justify | konq_center | <string> | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id >= CSS_VAL_LEFT && id <= CSS_VAL__KONQ_CENTER) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ break;
+ }
+ } else {
+ parsedValue = new CSSPrimitiveValueImpl(DOMString(curP, endP - curP),
+ CSSPrimitiveValue::CSS_STRING);
+ }
+ break;
+ }
+ case CSS_PROP_OUTLINE_STYLE: // <border-style> | inherit
+ case CSS_PROP_BORDER_TOP_STYLE: //// <border-style> | inherit
+ case CSS_PROP_BORDER_RIGHT_STYLE: // Defined as: none | hidden | dotted | dashed |
+ case CSS_PROP_BORDER_BOTTOM_STYLE: // solid | double | groove | ridge | inset | outset
+ case CSS_PROP_BORDER_LEFT_STYLE: ////
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id >= CSS_VAL_NONE && id <= CSS_VAL_OUTSET) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_FONT_WEIGHT: // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 |
+ // 500 | 600 | 700 | 800 | 900 | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id) {
+ if (id >= CSS_VAL_NORMAL && id <= CSS_VAL_LIGHTER) {
+ // Allready correct id
+ } else if (id >= CSS_VAL_100 && id <= CSS_VAL_500) {
+ id = CSS_VAL_NORMAL;
+ } else if (id >= CSS_VAL_600 && id <= CSS_VAL_900) {
+ id = CSS_VAL_BOLD;
+ }
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_BACKGROUND_REPEAT: // repeat | repeat-x | repeat-y | no-repeat | inherit
+ {
+#ifdef CSS_DEBUG_BCKGR
+ kdDebug( 6080 ) << "CSS_PROP_BACKGROUND_REPEAT: " << val << endl;
+#endif
+ if (cssval) {
+ int id = cssval->id;
+ if ( id >= CSS_VAL_REPEAT && id <= CSS_VAL_NO_REPEAT ) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_BACKGROUND_ATTACHMENT: // scroll | fixed
+ {
+#ifdef CSS_DEBUG_BCKGR
+ kdDebug( 6080 ) << "CSS_PROP_BACKGROUND_ATTACHEMENT: " << val << endl;
+#endif
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_SCROLL || id == CSS_VAL_FIXED ) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_BACKGROUND_POSITION:
+ {
+#ifdef CSS_DEBUG_BCKGR
+ kdDebug( 6080 ) << "CSS_PROP_BACKGROUND_POSITION: " << val << endl;
+#endif
+ /* Problem: center is ambigous
+ * In case of 'center' center defines X and Y coords
+ * In case of 'center top', center defines the Y coord
+ * in case of 'center left', center defines the X coord
+ */
+ bool isLast;
+ const QChar* nextP = getNext(curP, endP, isLast);
+ QConstString property1(const_cast<QChar*>( curP ), nextP - curP);
+ const struct css_value *cssval1 = findValue( property1.string().ascii(),
+ property1.string().length());
+ if ( !cssval1 ) {
+ int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X,
+ CSS_PROP_BACKGROUND_POSITION_Y };
+ return parseShortHand(curP, endP, properties, 2);
+ }
+ const struct css_value *cssval2 = 0;
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "prop 1: [" << property1.string() << "]" << " isLast: " << isLast << endl;
+#endif
+ if ( !isLast) {
+ curP = nextP+1;
+ nextP = getNext(curP, endP, isLast);
+ QConstString property2(const_cast<QChar*>( curP ), nextP - curP);
+ cssval2 = findValue( property2.string().ascii(), property2.string().length());
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "prop 2: [" << property2.string() << "]" << " isLast: " << isLast << endl;
+#endif
+ }
+
+ int valX = -1;
+ int valY = -1;
+ int id1 = cssval1 ? cssval1->id : -1;
+ int id2 = cssval2 ? cssval2->id : CSS_VAL_CENTER;
+ // id1 will influence X and id2 will influence Y
+ if ( id2 == CSS_VAL_LEFT || id2 == CSS_VAL_RIGHT ||
+ id1 == CSS_VAL_TOP || id1 == CSS_VAL_BOTTOM) {
+ int h = id1; id1 = id2; id2 = h;
+ }
+
+ switch( id1 ) {
+ case CSS_VAL_LEFT: valX = 0; break;
+ case CSS_VAL_CENTER: valX = 50; break;
+ case CSS_VAL_RIGHT: valX = 100; break;
+ default: break;
+ }
+
+ switch ( id2 ) {
+ case CSS_VAL_TOP: valY = 0; break;
+ case CSS_VAL_CENTER: valY = 50; break;
+ case CSS_VAL_BOTTOM: valY = 100; break;
+ default: break;
+ }
+
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "valX: " << valX << " valY: " << valY << endl;
+#endif
+ /* CSS 14.2
+ * Keywords cannot be combined with percentage values or length values.
+ * -> No mix between keywords and other units.
+ */
+ if (valX !=-1 && valY !=-1) {
+ setParsedValue( CSS_PROP_BACKGROUND_POSITION_X,
+ new CSSPrimitiveValueImpl(valX, CSSPrimitiveValue::CSS_PERCENTAGE));
+ setParsedValue( CSS_PROP_BACKGROUND_POSITION_Y,
+ new CSSPrimitiveValueImpl(valY, CSSPrimitiveValue::CSS_PERCENTAGE));
+ return true;
+ }
+ break;
+ }
+ case CSS_PROP_BACKGROUND_POSITION_X:
+ case CSS_PROP_BACKGROUND_POSITION_Y:
+ {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "CSS_PROP_BACKGROUND_POSITION_{X|Y}: " << val << endl;
+#endif
+ parsedValue = parseUnit(curP, endP, PERCENT | NUMBER | LENGTH);
+ break;
+ }
+ case CSS_PROP_BORDER_SPACING:
+ {
+ // ### should be able to have two values
+ parsedValue = parseUnit(curP, endP, LENGTH | NONNEGATIVE);
+ break;
+ }
+ case CSS_PROP_OUTLINE_COLOR: // <color> | invert | inherit
+ {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "CSS_PROP_OUTLINE_COLOR: " << val << endl;
+#endif
+ // outline has "invert" as additional keyword. we handle
+ // it as invalid color and add a special case during rendering
+ if (cssval && cssval->id == CSS_VAL_INVERT) {
+ parsedValue = new CSSPrimitiveValueImpl( QColor() );
+ break;
+ }
+ // Break is explictly missing, looking for <color>
+ }
+ case CSS_PROP_BACKGROUND_COLOR: // <color> | transparent | inherit
+ {
+#ifdef CSS_DEBUG_BCKGR
+ kdDebug( 6080 ) << "CSS_PROP_BACKGROUND_COLOR: " << val << endl;
+#endif
+ if (cssval && cssval->id == CSS_VAL_TRANSPARENT) {
+ parsedValue = new CSSPrimitiveValueImpl( QColor() );
+ break;
+ }
+ // Break is explictly missing, looking for <color>
+ }
+ case CSS_PROP_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_TOP_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_RIGHT_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_BOTTOM_COLOR: // <color> | inherit
+ case CSS_PROP_BORDER_LEFT_COLOR: // <color> | inherit
+ case CSS_PROP_TEXT_DECORATION_COLOR: //
+ case CSS_PROP_SCROLLBAR_FACE_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_SHADOW_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_TRACK_COLOR: // IE5.5
+ case CSS_PROP_SCROLLBAR_ARROW_COLOR: // IE5.5
+ {
+ const QString val2( value.stripWhiteSpace() );
+ //kdDebug(6080) << "parsing color " << val2 << endl;
+ QColor c;
+ khtml::setNamedColor(c, val2);
+ if(!c.isValid() && (val2 != "transparent" ) && !val2.isEmpty() ) return false;
+ //kdDebug( 6080 ) << "color is: " << c.red() << ", " << c.green() << ", " << c.blue() << endl;
+ parsedValue = new CSSPrimitiveValueImpl(c);
+ break;
+ }
+ case CSS_PROP_BACKGROUND_IMAGE: // <uri> | none | inherit
+#ifdef CSS_DEBUG_BCKGR
+ {
+ kdDebug( 6080 ) << "CSS_PROP_BACKGROUND_IMAGE: " << val << endl;
+ }
+#endif
+ case CSS_PROP_CURSOR:
+ // [ [<uri> ,]* [ auto | crosshair | default | pointer | move | e-resize | ne-resize |
+ // nw-resize | // n-resize | se-resize | sw-resize | s-resize | w-resize | text |
+ // wait | help ] ] | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id >= CSS_VAL_AUTO && id <= CSS_VAL_HELP) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ break;
+ }
+ } else {
+ // Break is explictly missing, looking for <uri>
+ // ### Only supports parsing the first uri
+ }
+ }
+ case CSS_PROP_LIST_STYLE_IMAGE: // <uri> | none | inherit
+ {
+ if (cssval && cssval->id == CSS_VAL_NONE)
+ {
+ parsedValue = new CSSImageValueImpl();
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "empty image " << endl;
+#endif
+ } else {
+ const QString str(value.stripWhiteSpace()); // ### Optimize
+ if (str.left(4).lower() == "url(") {
+ DOMString value(curP, endP - curP);
+ value = khtml::parseURL(value);
+ parsedValue = new CSSImageValueImpl(value, baseUrl(), this);
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "image, url=" << value.string() << " base=" << baseUrl().string() << endl;
+#endif
+ }
+ }
+ break;
+ }
+ case CSS_PROP_OUTLINE_WIDTH: // <border-width> | inherit
+ case CSS_PROP_BORDER_TOP_WIDTH: //// <border-width> | inherit
+ case CSS_PROP_BORDER_RIGHT_WIDTH: // Which is defined as
+ case CSS_PROP_BORDER_BOTTOM_WIDTH: // thin | medium | thick | <length>
+ case CSS_PROP_BORDER_LEFT_WIDTH: ////
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id == CSS_VAL_THIN || id == CSS_VAL_MEDIUM || id == CSS_VAL_THICK) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH|NONNEGATIVE);
+ }
+ break;
+ }
+ case CSS_PROP_MARKER_OFFSET: // <length> | auto | inherit
+ {
+ if (cssval && cssval->id == CSS_VAL_AUTO) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH);
+ }
+ break;
+ }
+ case CSS_PROP_LETTER_SPACING: // normal | <length> | inherit
+ case CSS_PROP_WORD_SPACING: // normal | <length> | inherit
+ {
+ if (cssval) {
+ if (cssval->id == CSS_VAL_NORMAL) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ }
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH);
+ }
+ break;
+ }
+ case CSS_PROP_PADDING_TOP: //// <padding-width> | inherit
+ case CSS_PROP_PADDING_RIGHT: // Which is defined as
+ case CSS_PROP_PADDING_BOTTOM: // <length> | <percentage>
+ case CSS_PROP_PADDING_LEFT: ////
+ {
+ parsedValue = parseUnit(curP, endP, LENGTH | PERCENT|NONNEGATIVE);
+ break;
+ }
+ case CSS_PROP_TEXT_INDENT: // <length> | <percentage> | inherit
+ case CSS_PROP_MIN_HEIGHT: // <length> | <percentage> | inherit
+ case CSS_PROP_MIN_WIDTH: // <length> | <percentage> | inherit
+ {
+ parsedValue = parseUnit(curP, endP, LENGTH | PERCENT);
+ break;
+ }
+ case CSS_PROP_FONT_SIZE:
+ // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if (id >= CSS_VAL_XX_SMALL && id <= CSS_VAL_LARGER) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ break;
+ }
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH | PERCENT | NONNEGATIVE);
+ }
+ break;
+ }
+ case CSS_PROP_FONT_STYLE: // normal | italic | oblique | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_NORMAL || id == CSS_VAL_ITALIC || id == CSS_VAL_OBLIQUE) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_FONT_VARIANT: // normal | small-caps | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ( id == CSS_VAL_NORMAL || id == CSS_VAL_SMALL_CAPS) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ }
+ break;
+ }
+ case CSS_PROP_VERTICAL_ALIGN:
+ // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
+ // <percentage> | <length> | inherit
+ {
+ if (cssval) {
+ int id = cssval->id;
+ if ( id >= CSS_VAL_BASELINE && id <= CSS_VAL__KONQ_BASELINE_MIDDLE ) {
+ parsedValue = new CSSPrimitiveValueImpl(id);
+ }
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH | PERCENT );
+ }
+ break;
+ }
+ case CSS_PROP_MAX_HEIGHT: // <length> | <percentage> | none | inherit
+ case CSS_PROP_MAX_WIDTH: // <length> | <percentage> | none | inherit
+ {
+ if (cssval && cssval->id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH | PERCENT );
+ }
+ break;
+ }
+ case CSS_PROP_HEIGHT: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_WIDTH: // <length> | <percentage> | auto | inherit
+ {
+ if (cssval && cssval->id == CSS_VAL_AUTO) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH | PERCENT | NONNEGATIVE );
+ }
+ break;
+ }
+ case CSS_PROP_BOTTOM: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_LEFT: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_RIGHT: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_TOP: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_MARGIN_TOP: //// <margin-width> | inherit
+ case CSS_PROP_MARGIN_RIGHT: // Which is defined as
+ case CSS_PROP_MARGIN_BOTTOM: // <length> | <percentage> | auto | inherit
+ case CSS_PROP_MARGIN_LEFT: ////
+ {
+ if (cssval && cssval->id == CSS_VAL_AUTO) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ parsedValue = parseUnit(curP, endP, LENGTH | PERCENT );
+ }
+ break;
+ }
+ case CSS_PROP_FONT_SIZE_ADJUST: // <number> | none | inherit
+ // ### not supported later on
+ {
+ if (cssval && cssval->id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ parsedValue = parseUnit(curP, endP, NUMBER);
+ }
+ break;
+ }
+ case CSS_PROP_Z_INDEX: // auto | <integer> | inherit
+ {
+ if (cssval && cssval->id == CSS_VAL_AUTO) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ break;
+ }
+ // break explicitly missing, looking for <number>
+ }
+ case CSS_PROP_ORPHANS: // <integer> | inherit
+ case CSS_PROP_WIDOWS: // <integer> | inherit
+ // ### not supported later on
+ {
+ parsedValue = parseUnit(curP, endP, INTEGER);
+ break;
+ }
+ case CSS_PROP_LINE_HEIGHT: // normal | <number> | <length> | <percentage> | inherit
+ {
+ if (cssval && cssval->id == CSS_VAL_NORMAL) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ parsedValue = parseUnit(curP, endP, NUMBER | LENGTH | PERCENT | NONNEGATIVE);
+ }
+ break;
+ }
+ case CSS_PROP_COUNTER_INCREMENT: // [ <identifier> <integer>? ]+ | none | inherit
+ case CSS_PROP_COUNTER_RESET: // [ <identifier> <integer>? ]+ | none | inherit
+ {
+ if (cssval && cssval->id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ CSSValueListImpl *list = new CSSValueListImpl;
+ int pos=0, pos2;
+ while( 1 )
+ {
+ pos2 = value.find(',', pos);
+ QString face = value.mid(pos, pos2-pos);
+ face = face.stripWhiteSpace();
+ if(face.length() == 0) break;
+ // ### single quoted is missing...
+ if(face[0] == '\"') face.remove(0, 1);
+ if(face[face.length()-1] == '\"') face = face.left(face.length()-1);
+ //kdDebug( 6080 ) << "found face '" << face << "'" << endl;
+ list->append(new CSSPrimitiveValueImpl(DOMString(face), CSSPrimitiveValue::CSS_STRING));
+ pos = pos2 + 1;
+ if(pos2 == -1) break;
+ }
+ //kdDebug( 6080 ) << "got " << list->length() << " faces" << endl;
+ if(list->length())
+ parsedValue = list;
+ else
+ delete list;
+ break;
+ }
+ }
+ case CSS_PROP_FONT_FAMILY:
+ // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
+ {
+ CSSValueListImpl *list = new CSSValueListImpl;
+ // css2 compatible parsing...
+ FontParser fp;
+ fp.startTokenizer( value, strictParsing );
+ QStringList families;
+ if ( !fp.matchFontFamily( &families ) )
+ return false;
+ for ( QStringList::Iterator it = families.begin(); it != families.end(); ++it ) {
+ if( *it != QString::null ) {
+ list->append(new CSSPrimitiveValueImpl(DOMString(*it), CSSPrimitiveValue::CSS_STRING));
+ //kdDebug() << "StyleBaseImpl::parsefont: family='" << *it << "'" << endl;
+ }
+ }
+ //kdDebug( 6080 ) << "got " << list->length() << " faces" << endl;
+ if(list->length())
+ parsedValue = list;
+ else
+ delete list;
+ break;
+ }
+ case CSS_PROP_TEXT_DECORATION:
+ // none | [ underline || overline || line-through || blink ] | inherit
+ {
+ if (cssval) {
+ if (cssval->id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ } else {
+ CSSValueListImpl *list = new CSSValueListImpl;
+ value.simplifyWhiteSpace();
+ //kdDebug( 6080 ) << "text-decoration: '" << str << "'" << endl;
+ int pos=0, pos2;
+ while( 1 )
+ {
+ pos2 = value.find(' ', pos);
+ QString decoration = value.mid(pos, pos2-pos);
+ decoration = decoration.stripWhiteSpace();
+ //kdDebug( 6080 ) << "found decoration '" << decoration << "'" << endl;
+ const struct css_value *cssval = findValue(decoration.lower().ascii(),
+ decoration.length());
+ if (cssval) {
+ list->append(new CSSPrimitiveValueImpl(cssval->id));
+ }
+ pos = pos2 + 1;
+ if(pos2 == -1) break;
+ }
+ //kdDebug( 6080 ) << "got " << list->length() << "d decorations" << endl;
+ if(list->length()) {
+ parsedValue = list;
+ } else {
+ delete list;
+ }
+ }
+ }
+ break;
+ }
+ case CSS_PROP__KONQ_FLOW_MODE:
+ {
+ if (cssval->id==CSS_VAL__KONQ_NORMAL || cssval->id==CSS_VAL__KONQ_AROUND_FLOATS)
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ break;
+ }
+ /* shorthand properties */
+
+ case CSS_PROP_BACKGROUND:
+ // ['background-color' || 'background-image' ||'background-repeat' ||
+ // 'background-attachment' || 'background-position'] | inherit
+ {
+#ifdef CSS_DEBUG_BCKGR
+ kdDebug(6080) << "CSS_PROP_BACKGROUND" << endl;
+#endif
+ const int properties[5] = { CSS_PROP_BACKGROUND_COLOR, CSS_PROP_BACKGROUND_IMAGE,
+ CSS_PROP_BACKGROUND_REPEAT, CSS_PROP_BACKGROUND_ATTACHMENT,
+ CSS_PROP_BACKGROUND_POSITION};
+ return parseShortHand(curP, endP, properties, 5);
+
+ //return parseBackground(curP, endP);
+ }
+ case CSS_PROP_BORDER:
+ // [ 'border-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
+ CSS_PROP_BORDER_COLOR };
+ return parseShortHand(curP, endP, properties, 3);
+ }
+ case CSS_PROP_BORDER_TOP:
+ // [ 'border-top-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
+ CSS_PROP_BORDER_TOP_COLOR};
+ return parseShortHand(curP, endP, properties, 3);
+ }
+ case CSS_PROP_BORDER_RIGHT:
+ // [ 'border-right-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
+ CSS_PROP_BORDER_RIGHT_COLOR };
+ return parseShortHand(curP, endP, properties, 3);
+ }
+ case CSS_PROP_BORDER_BOTTOM:
+ // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
+ CSS_PROP_BORDER_BOTTOM_COLOR };
+ return parseShortHand(curP, endP, properties, 3);
+ }
+ case CSS_PROP_BORDER_LEFT:
+ // [ 'border-left-width' || 'border-style' || <color> ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
+ CSS_PROP_BORDER_LEFT_COLOR };
+ return parseShortHand(curP, endP, properties, 3);
+ }
+ case CSS_PROP_OUTLINE:
+ // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
+ {
+ const int properties[3] = { CSS_PROP_OUTLINE_COLOR, CSS_PROP_OUTLINE_STYLE,
+ CSS_PROP_OUTLINE_WIDTH };
+ return parseShortHand(curP, endP, properties, 3);
+ }
+ case CSS_PROP_BORDER_COLOR:
+ // <color>{1,4} | transparent | inherit
+ {
+ const struct css_value *cssval = findValue(val, len);
+ if (cssval && cssval->id == CSS_VAL_TRANSPARENT)
+ {
+ // set border colors to invalid
+ parsedValue = new CSSPrimitiveValueImpl(CSS_VAL_TRANSPARENT);
+ break;
+ }
+ 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 parse4Values(curP, endP, properties);
+ }
+ case CSS_PROP_BORDER_WIDTH:
+ // <border-width>{1,4} | inherit
+ {
+ 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 parse4Values(curP, endP, properties);
+ }
+ case CSS_PROP_BORDER_STYLE:
+ // <border-style>{1,4} | inherit
+ {
+ 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 parse4Values(curP, endP, properties);
+ }
+ case CSS_PROP_MARGIN:
+ // <margin-width>{1,4} | inherit
+ {
+ const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
+ CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
+ return parse4Values(curP, endP, properties);
+ }
+ case CSS_PROP_PADDING:
+ // <padding-width>{1,4} | inherit
+ {
+ const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
+ CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
+ return parse4Values(curP, endP, properties);
+ }
+ case CSS_PROP_FONT:
+ // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
+ // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
+ {
+ return parseFont(curP, endP);
+ }
+ 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 parseShortHand(curP, endP, properties, 3);
+ }
+
+ default:
+ {
+#ifdef CSS_DEBUG
+ kdDebug( 6080 ) << "illegal or CSS2 Aural property: " << val << endl;
+#endif
+ }
+ }
+ }
+ if ( parsedValue ) {
+ setParsedValue(propId, parsedValue);
+ return true;
+ } else {
+#ifndef CSS_AURAL
+ return false;
+#endif
+#ifdef CSS_AURAL
+ return parseAuralValue(curP, endP, propId);
+#endif
+ }
+}
+
+#ifdef CSS_AURAL
+/* parseAuralValue */
+bool StyleBaseImpl::parseAuralValue( const QChar *curP, const QChar *endP, int propId )
+{
+ QString value(curP, endP - curP);
+ value = value.lower();
+ const char *val = value.ascii();
+
+ CSSValueImpl *parsedValue = 0;
+ kdDebug( 6080 ) << "parseAuralValue: " << value << " val: " << val << endl;
+
+ /* AURAL Properies */
+ switch(propId)
+ {
+ case CSS_PROP_AZIMUTH: // <angle> | [[ left-side | far-left | left | center-left | center |
+ // center-right | right | far-right | right-side ] || behind ] |
+ // leftwards | rightwards | inherit
+ case CSS_PROP_PAUSE_AFTER: // <time> | <percentage> | inherit
+ case CSS_PROP_PAUSE_BEFORE: // <time> | <percentage> | inherit
+ case CSS_PROP_PAUSE: // [ [<time> | <percentage>]{1,2} ] | inherit
+ case CSS_PROP_PLAY_DURING: // <uri> mix? repeat? | auto | none | inherit
+ case CSS_PROP_VOICE_FAMILY: // [[<specific-voice> | <generic-voice> ],]*
+ // [<specific-voice> | <generic-voice> ] | inherit
+ {
+ // ### TO BE DONE
+ break;
+ }
+ case CSS_PROP_CUE: // [ 'cue-before' || 'cue-after' ] | inherit
+ {
+ const int properties[2] = {
+ CSS_PROP_CUE_BEFORE,
+ CSS_PROP_CUE_AFTER};
+ return parse2Values(curP, endP, properties);
+ }
+ case CSS_PROP_CUE_AFTER: // <uri> | none | inherit
+ case CSS_PROP_CUE_BEFORE: // <uri> | none | inherit
+ {
+ const struct css_value *cssval = findValue(val, endP - curP);
+ if (cssval) {
+ if (cssval->id == CSS_VAL_NONE) {
+ parsedValue = new CSSPrimitiveValueImpl(cssval->id);
+ }
+ } else {
+ DOM