RenderBlock {DIV} at (0,0) size 784x356 [border: (2px solid #FF0000)]
RenderBlock (anonymous) at (14,14) size 756x56
RenderInline {SPAN} at (0,0) size 687x56
- RenderInline {SPAN} at (0,0) size 10x28 [color=#008000]
+ RenderInline {FONT} at (0,0) size 10x28 [color=#008000]
RenderText {TEXT} at (0,0) size 10x28
text run at (0,0) width 10: "\""
RenderText {TEXT} at (10,0) size 687x56
RenderInline {SPAN} at (0,0) size 0x0
RenderText {TEXT} at (0,0) size 0x0
selection is RANGE:
-start: position 0 of child 1 {TEXT} of child 1 {SPAN} of child 2 {SPAN} of root {DIV}
+start: position 0 of child 1 {TEXT} of child 1 {FONT} of child 2 {SPAN} of root {DIV}
upstream: position 0 of of root {DIV}
-downstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of child 2 {SPAN} of root {DIV}
-end: position 1 of child 1 {TEXT} of child 1 {SPAN} of child 2 {SPAN} of root {DIV}
-upstream: position 1 of child 1 {TEXT} of child 1 {SPAN} of child 2 {SPAN} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 1 {FONT} of child 2 {SPAN} of root {DIV}
+end: position 1 of child 1 {TEXT} of child 1 {FONT} of child 2 {SPAN} of root {DIV}
+upstream: position 1 of child 1 {TEXT} of child 1 {FONT} of child 2 {SPAN} of root {DIV}
downstream: position 0 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
text run at (0,0) width 39: "there"
RenderBlock {P} at (0,68) size 784x18
RenderInline {B} at (0,0) size 37x18
- RenderInline {SPAN} at (0,0) size 37x18
+ RenderInline {FONT} at (0,0) size 37x18
RenderText {TEXT} at (0,0) size 37x18
text run at (0,0) width 37: "hello"
RenderBlock {P} at (0,102) size 784x18
RenderInline {B} at (0,0) size 39x18
- RenderInline {SPAN} at (0,0) size 39x18
+ RenderInline {FONT} at (0,0) size 39x18
RenderText {TEXT} at (0,0) size 39x18
text run at (0,0) width 39: "there"
selection is CARET:
-start: position 5 of child 1 {TEXT} of child 1 {SPAN} of child 1 {B} of child 5 {P} of root {BODY}
-upstream: position 5 of child 1 {TEXT} of child 1 {SPAN} of child 1 {B} of child 5 {P} of root {BODY}
-downstream: position 5 of child 1 {TEXT} of child 1 {SPAN} of child 1 {B} of child 5 {P} of root {BODY}
+start: position 5 of child 1 {TEXT} of child 1 {FONT} of child 1 {B} of child 5 {P} of root {BODY}
+upstream: position 5 of child 1 {TEXT} of child 1 {FONT} of child 1 {B} of child 5 {P} of root {BODY}
+downstream: position 5 of child 1 {TEXT} of child 1 {FONT} of child 1 {B} of child 5 {P} of root {BODY}
text run at (14,98) width 557: "REGRESSION (Mail): Style not preserved on blank lines"
RenderBlock {DIV} at (0,164) size 784x276
RenderBlock {DIV} at (0,0) size 784x69
- RenderInline {SPAN} at (0,0) size 30x69
- RenderText {TEXT} at (0,0) size 30x69
- text run at (0,0) width 30: "x"
+ RenderInline {FONT} at (0,0) size 30x55
+ RenderInline {SPAN} at (0,0) size 30x69
+ RenderText {TEXT} at (0,0) size 30x69
+ text run at (0,0) width 30: "x"
RenderBlock {DIV} at (0,69) size 784x69
- RenderInline {SPAN} at (0,0) size 0x69
- RenderBR {BR} at (0,0) size 0x69
+ RenderInline {FONT} at (0,0) size 0x55
+ RenderInline {SPAN} at (0,0) size 0x69
+ RenderBR {BR} at (0,0) size 0x69
RenderBlock {DIV} at (0,138) size 784x69
- RenderInline {SPAN} at (0,0) size 0x69
- RenderBR {BR} at (0,0) size 0x69
+ RenderInline {FONT} at (0,0) size 0x55
+ RenderInline {SPAN} at (0,0) size 0x69
+ RenderBR {BR} at (0,0) size 0x69
RenderBlock {DIV} at (0,207) size 784x69
- RenderInline {SPAN} at (0,0) size 30x69
- RenderText {TEXT} at (0,0) size 30x69
- text run at (0,0) width 30: "x"
+ RenderInline {FONT} at (0,0) size 30x55
+ RenderInline {SPAN} at (0,0) size 30x69
+ RenderText {TEXT} at (0,0) size 30x69
+ text run at (0,0) width 30: "x"
selection is CARET:
-start: position 0 of child 1 {BR} of child 1 {SPAN} of child 3 {DIV} of root {DIV}
+start: position 0 of child 1 {BR} of child 1 {SPAN} of child 1 {FONT} of child 3 {DIV} of root {DIV}
upstream: position 0 of child 3 {DIV} of root {DIV}
-downstream: position 0 of child 1 {BR} of child 1 {SPAN} of child 3 {DIV} of root {DIV}
+downstream: position 0 of child 1 {BR} of child 1 {SPAN} of child 1 {FONT} of child 3 {DIV} of root {DIV}
text run at (14,98) width 106: "blank lines"
RenderBlock {DIV} at (0,164) size 784x207
RenderBlock {DIV} at (0,0) size 784x69
- RenderInline {SPAN} at (0,0) size 30x69
- RenderText {TEXT} at (0,0) size 30x69
- text run at (0,0) width 30: "x"
+ RenderInline {FONT} at (0,0) size 30x55
+ RenderInline {SPAN} at (0,0) size 30x69
+ RenderText {TEXT} at (0,0) size 30x69
+ text run at (0,0) width 30: "x"
RenderBlock {DIV} at (0,69) size 784x69
- RenderInline {SPAN} at (0,0) size 0x69
- RenderBR {BR} at (0,0) size 0x69
+ RenderInline {FONT} at (0,0) size 0x55
+ RenderInline {SPAN} at (0,0) size 0x69
+ RenderBR {BR} at (0,0) size 0x69
RenderBlock {DIV} at (0,138) size 784x69
- RenderInline {SPAN} at (0,0) size 0x69
- RenderBR {BR} at (0,0) size 0x69
+ RenderInline {FONT} at (0,0) size 0x55
+ RenderInline {SPAN} at (0,0) size 0x69
+ RenderBR {BR} at (0,0) size 0x69
selection is CARET:
-start: position 0 of child 1 {BR} of child 1 {SPAN} of child 3 {DIV} of root {DIV}
+start: position 0 of child 1 {BR} of child 1 {SPAN} of child 1 {FONT} of child 3 {DIV} of root {DIV}
upstream: position 0 of child 3 {DIV} of root {DIV}
-downstream: position 0 of child 1 {BR} of child 1 {SPAN} of child 3 {DIV} of root {DIV}
+downstream: position 0 of child 1 {BR} of child 1 {SPAN} of child 1 {FONT} of child 3 {DIV} of root {DIV}
text run at (14,98) width 273: "not preserved on blank lines"
RenderBlock {DIV} at (0,164) size 784x276
RenderBlock {DIV} at (0,0) size 784x69
- RenderInline {SPAN} at (0,0) size 30x69
- RenderText {TEXT} at (0,0) size 30x69
- text run at (0,0) width 30: "x"
+ RenderInline {FONT} at (0,0) size 30x55
+ RenderInline {SPAN} at (0,0) size 30x69
+ RenderText {TEXT} at (0,0) size 30x69
+ text run at (0,0) width 30: "x"
RenderBlock {DIV} at (0,69) size 784x69
- RenderInline {SPAN} at (0,0) size 0x69
- RenderBR {BR} at (0,0) size 0x69
+ RenderInline {FONT} at (0,0) size 0x55
+ RenderInline {SPAN} at (0,0) size 0x69
+ RenderBR {BR} at (0,0) size 0x69
RenderBlock {DIV} at (0,138) size 784x69
- RenderInline {SPAN} at (0,0) size 0x69
- RenderBR {BR} at (0,0) size 0x69
+ RenderInline {FONT} at (0,0) size 0x55
+ RenderInline {SPAN} at (0,0) size 0x69
+ RenderBR {BR} at (0,0) size 0x69
RenderBlock {DIV} at (0,207) size 784x69
- RenderInline {SPAN} at (0,0) size 30x69
- RenderText {TEXT} at (0,0) size 30x69
- text run at (0,0) width 30: "x"
+ RenderInline {FONT} at (0,0) size 30x55
+ RenderInline {SPAN} at (0,0) size 30x69
+ RenderText {TEXT} at (0,0) size 30x69
+ text run at (0,0) width 30: "x"
selection is CARET:
-start: position 0 of child 1 {TEXT} of child 1 {SPAN} of child 4 {DIV} of root {DIV}
+start: position 0 of child 1 {TEXT} of child 1 {SPAN} of child 1 {FONT} of child 4 {DIV} of root {DIV}
upstream: position 0 of child 4 {DIV} of root {DIV}
-downstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of child 4 {DIV} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of child 1 {FONT} of child 4 {DIV} of root {DIV}
RenderInline {SPAN} at (0,0) size 77x28 [color=#FF0000]
RenderText {TEXT} at (2,2) size 23x28
text run at (2,2) width 23: "ab"
- RenderInline {SPAN} at (0,0) size 34x28 [color=#000000]
+ RenderInline {FONT} at (0,0) size 34x28 [color=#000000]
RenderText {TEXT} at (25,2) size 34x28
text run at (25,2) width 34: "cde"
RenderText {TEXT} at (59,2) size 20x28
text run at (59,2) width 20: "fg"
selection is CARET:
-start: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
-upstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
+start: position 3 of child 1 {TEXT} of child 2 {FONT} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
+upstream: position 3 of child 1 {TEXT} of child 2 {FONT} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
downstream: position 0 of child 3 {TEXT} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
RenderInline {SPAN} at (0,0) size 99x28 [color=#FF0000]
RenderText {TEXT} at (2,8) size 29x28
text run at (2,8) width 29: "ab"
- RenderInline {SPAN} at (0,0) size 46x37 [color=#000000]
- RenderInline {B} at (0,0) size 46x37
- RenderText {TEXT} at (31,2) size 46x37
- text run at (31,2) width 46: "cde"
+ RenderInline {FONT} at (0,0) size 46x37 [color=#000000]
+ RenderInline {SPAN} at (0,0) size 46x37
+ RenderInline {B} at (0,0) size 46x37
+ RenderText {TEXT} at (31,2) size 46x37
+ text run at (31,2) width 46: "cde"
RenderText {TEXT} at (77,8) size 24x28
text run at (77,8) width 24: "fg"
RenderText {TEXT} at (0,0) size 0x0
RenderBlock {H1} at (0,62) size 784x0
selection is CARET:
-start: position 3 of child 1 {TEXT} of child 1 {B} of child 2 {SPAN} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
-upstream: position 3 of child 1 {TEXT} of child 1 {B} of child 2 {SPAN} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
+start: position 3 of child 1 {TEXT} of child 1 {B} of child 1 {SPAN} of child 2 {FONT} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
+upstream: position 3 of child 1 {TEXT} of child 1 {B} of child 1 {SPAN} of child 2 {FONT} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
downstream: position 0 of child 3 {TEXT} of child 2 {SPAN} of child 1 {DIV} of root {DIV}
+2005-02-22 Ken Kocienda <kocienda@apple.com>
+
+ Reviewed by Hyatt
+
+ Fix for this bug:
+
+ <rdar://problem/4003463> Mail.app HTML uses inline styling markup not understood by Entourage and Eudora
+
+ * khtml/editing/htmlediting.cpp:
+ (khtml::isEmptyFontTag): Helper for removing <font> tags.
+ (khtml::StyleChange::styleModeForParseMode): Helper to map a document parse mode to a use/don't use
+ legacy-html-styles value.
+ (khtml::StyleChange::checkForLegacyHTMLStyleChange): Add support for colors, font faces, and font sizes.
+ (khtml::ApplyStyleCommand::isHTMLStyleNode):
+ (khtml::ApplyStyleCommand::removeHTMLFontStyle):
+ (khtml::ApplyStyleCommand::applyTextDecorationStyle): Now call styleModeForParseMode to determine
+ whether to use legacy html styles or not.
+ (khtml::ApplyStyleCommand::removeInlineStyle): Now properly removes <font> styles.
+ (khtml::ApplyStyleCommand::addBlockStyleIfNeeded): Ditto.
+ (khtml::ApplyStyleCommand::addInlineStyleIfNeeded): Ditto.
+ (khtml::createFontElement): Helper for applying <font> elements.
+ * khtml/editing/htmlediting.h: All the following support the new bits of data we need to store.
+ (khtml::StyleChange::applyFontColor)
+ (khtml::StyleChange::applyFontFace)
+ (khtml::StyleChange::applyFontSize)
+ (khtml::StyleChange::fontColor)
+ (khtml::StyleChange::fontFace)
+ (khtml::StyleChange::fontSize)
+
+ Test results updated now that we will write out <font> tags for quirks mode documents.
+
+ * layout-tests/editing/execCommand/modifyForeColorByCharacter-expected.txt
+ * layout-tests/editing/style/block-style-004-expected.txt
+ * layout-tests/editing/editing/pasteboard/paste-text-011-expected.txt
+ * layout-tests/editing/style/block-style-005-expected.txt
+ * layout-tests/editing/style/block-style-006-expected.txt
+ * layout-tests/editing/style/smoosh-styles-001-expected.txt
+ * layout-tests/editing/style/smoosh-styles-002-expected.txt
+
2005-02-22 Maciej Stachowiak <mjs@apple.com>
Reviewed by Kevin.
#include "khtml_part.h"
#include "khtml_part.h"
#include "khtmlview.h"
+#include "qcolor.h"
#include "qptrlist.h"
#include "render_object.h"
#include "render_style.h"
return elem->id() == ID_SPAN && elem->getAttribute(ATTR_CLASS) == styleSpanClassString();
}
+static bool isEmptyFontTag(const NodeImpl *node)
+{
+ if (!node || node->id() != ID_FONT)
+ return false;
+
+ const ElementImpl *elem = static_cast<const ElementImpl *>(node);
+ NamedAttrMapImpl *map = elem->attributes(true); // true for read-only
+ return (!map || map->length() == 1) && elem->getAttribute(ATTR_CLASS) == styleSpanClassString();
+}
+
static DOMString &blockPlaceholderClassString()
{
static DOMString blockPlaceholderClassString = "khtml-block-placeholder";
m_cssStyle = styleText.stripWhiteSpace();
}
-bool StyleChange::checkForLegacyHTMLStyleChange(const DOM::CSSProperty *property)
+StyleChange::ELegacyHTMLStyles StyleChange::styleModeForParseMode(bool isQuirksMode)
+{
+ return isQuirksMode ? UseLegacyHTMLStyles : DoNotUseLegacyHTMLStyles;
+}
+
+bool StyleChange::checkForLegacyHTMLStyleChange(const CSSProperty *property)
{
DOMString valueText(property->value()->cssText());
switch (property->id()) {
return true;
}
break;
+ case CSS_PROP_COLOR: {
+ QColor color(CSSParser::parseColor(valueText));
+ m_applyFontColor = color.name();
+ return true;
+ }
+ case CSS_PROP_FONT_FAMILY:
+ m_applyFontFace = valueText;
+ return true;
+ case CSS_PROP_FONT_SIZE:
+ if (property->value()->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) {
+ CSSPrimitiveValueImpl *value = static_cast<CSSPrimitiveValueImpl *>(property->value());
+ float number = value->getFloatValue(CSSPrimitiveValue::CSS_PX);
+ if (number <= 9)
+ m_applyFontSize = "1";
+ else if (number <= 10)
+ m_applyFontSize = "2";
+ else if (number <= 13)
+ m_applyFontSize = "3";
+ else if (number <= 16)
+ m_applyFontSize = "4";
+ else if (number <= 18)
+ m_applyFontSize = "5";
+ else if (number <= 24)
+ m_applyFontSize = "6";
+ else
+ m_applyFontSize = "7";
+ // Huge quirk in Microsft Entourage is that they understand CSS font-size, but also write
+ // out legacy 1-7 values in font tags (I guess for mailers that are not CSS-savvy at all,
+ // like Eudora). Yes, they write out *both*. We need to write out both as well. Return false.
+ return false;
+ }
+ else {
+ // Can't make sense of the number. Put no font size.
+ return true;
+ }
}
return false;
}
case CSS_PROP_FONT_STYLE:
if (elem->id() == ID_I)
return true;
- break;
}
}
removeNodePreservingChildren(elem);
}
+void ApplyStyleCommand::removeHTMLFontStyle(CSSMutableStyleDeclarationImpl *style, HTMLElementImpl *elem)
+{
+ ASSERT(style);
+ ASSERT(elem);
+
+ if (elem->id() != ID_FONT)
+ return;
+
+ int exceptionCode = 0;
+ QValueListConstIterator<CSSProperty> end;
+ for (QValueListConstIterator<CSSProperty> it = style->valuesIterator(); it != end; ++it) {
+ switch ((*it).id()) {
+ case CSS_PROP_COLOR:
+ elem->removeAttribute(ATTR_COLOR, exceptionCode);
+ ASSERT(exceptionCode == 0);
+ break;
+ case CSS_PROP_FONT_FAMILY:
+ elem->removeAttribute(ATTR_FACE, exceptionCode);
+ ASSERT(exceptionCode == 0);
+ break;
+ case CSS_PROP_FONT_SIZE:
+ elem->removeAttribute(ATTR_SIZE, exceptionCode);
+ ASSERT(exceptionCode == 0);
+ break;
+ }
+ }
+
+ if (isEmptyFontTag(elem))
+ removeNodePreservingChildren(elem);
+}
+
void ApplyStyleCommand::removeCSSStyle(CSSMutableStyleDeclarationImpl *style, HTMLElementImpl *elem)
{
ASSERT(style);
HTMLElementImpl *element = static_cast<HTMLElementImpl *>(node);
- StyleChange styleChange(style, Position(element, 0), StyleChange::DoNotUseLegacyHTMLStyles);
+ StyleChange styleChange(style, Position(element, 0), StyleChange::styleModeForParseMode(document()->inCompatMode()));
if (styleChange.cssStyle().length() > 0) {
DOMString cssText = styleChange.cssStyle();
CSSMutableStyleDeclarationImpl *decl = element->inlineStyleDecl();
NodeImpl *next = node->traverseNextNode();
if (node->isHTMLElement() && nodeFullySelected(node, start, end)) {
HTMLElementImpl *elem = static_cast<HTMLElementImpl *>(node);
- if (isHTMLStyleNode(style, elem))
+ if (isHTMLStyleNode(style, elem)) {
removeHTMLStyleNode(elem);
- else
+ }
+ else {
+ removeHTMLFontStyle(style, elem);
removeCSSStyle(style, elem);
+ }
}
if (node == end.node())
break;
if (!block)
return;
- StyleChange styleChange(style, Position(block, 0), StyleChange::DoNotUseLegacyHTMLStyles);
+ StyleChange styleChange(style, Position(block, 0), StyleChange::styleModeForParseMode(document()->inCompatMode()));
if (styleChange.cssStyle().length() > 0) {
moveParagraphContentsToNewBlockIfNecessary(Position(node, 0));
block = static_cast<HTMLElementImpl *>(node->enclosingBlockFlowElement());
void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclarationImpl *style, NodeImpl *startNode, NodeImpl *endNode)
{
- StyleChange styleChange(style, Position(startNode, 0));
+ StyleChange styleChange(style, Position(startNode, 0), StyleChange::styleModeForParseMode(document()->inCompatMode()));
int exceptionCode = 0;
+ //
+ // Font tags need to go outside of CSS so that CSS font sizes override leagcy font sizes.
+ //
+ if (styleChange.applyFontColor() || styleChange.applyFontFace() || styleChange.applyFontSize()) {
+ ElementImpl *fontElement = createFontElement(document());
+ ASSERT(exceptionCode == 0);
+ insertNodeBefore(fontElement, startNode);
+ if (styleChange.applyFontColor())
+ fontElement->setAttribute(ATTR_COLOR, styleChange.fontColor());
+ if (styleChange.applyFontFace())
+ fontElement->setAttribute(ATTR_FACE, styleChange.fontFace());
+ if (styleChange.applyFontSize())
+ fontElement->setAttribute(ATTR_SIZE, styleChange.fontSize());
+ surroundNodeRangeWithElement(startNode, endNode, fontElement);
+ }
+
if (styleChange.cssStyle().length() > 0) {
ElementImpl *styleElement = createStyleSpanElement(document());
styleElement->setAttribute(ATTR_STYLE, styleChange.cssStyle());
return breakNode;
}
+ElementImpl *createFontElement(DocumentImpl *document)
+{
+ int exceptionCode = 0;
+ ElementImpl *fontNode = document->createHTMLElement("font", exceptionCode);
+ ASSERT(exceptionCode == 0);
+ fontNode->setAttribute(ATTR_CLASS, styleSpanClassString());
+ return fontNode;
+}
+
ElementImpl *createStyleSpanElement(DocumentImpl *document)
{
int exceptionCode = 0;
explicit StyleChange(DOM::CSSStyleDeclarationImpl *, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
StyleChange(DOM::CSSStyleDeclarationImpl *, const DOM::Position &, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
+ static ELegacyHTMLStyles styleModeForParseMode(bool);
+
DOM::DOMString cssStyle() const { return m_cssStyle; }
bool applyBold() const { return m_applyBold; }
bool applyItalic() const { return m_applyItalic; }
+ bool applyFontColor() const { return m_applyFontColor.length() > 0; }
+ bool applyFontFace() const { return m_applyFontFace.length() > 0; }
+ bool applyFontSize() const { return m_applyFontSize.length() > 0; }
+
+ DOM::DOMString fontColor() { return m_applyFontColor; }
+ DOM::DOMString fontFace() { return m_applyFontFace; }
+ DOM::DOMString fontSize() { return m_applyFontSize; }
+
bool usesLegacyStyles() const { return m_usesLegacyStyles; }
private:
DOM::DOMString m_cssStyle;
bool m_applyBold;
bool m_applyItalic;
+ DOM::DOMString m_applyFontColor;
+ DOM::DOMString m_applyFontFace;
+ DOM::DOMString m_applyFontSize;
bool m_usesLegacyStyles;
};
// style-removal helpers
bool isHTMLStyleNode(DOM::CSSMutableStyleDeclarationImpl *, DOM::HTMLElementImpl *);
void removeHTMLStyleNode(DOM::HTMLElementImpl *);
+ void removeHTMLFontStyle(DOM::CSSMutableStyleDeclarationImpl *, DOM::HTMLElementImpl *);
void removeCSSStyle(DOM::CSSMutableStyleDeclarationImpl *, DOM::HTMLElementImpl *);
void removeBlockStyle(DOM::CSSMutableStyleDeclarationImpl *, const DOM::Position &start, const DOM::Position &end);
void removeInlineStyle(DOM::CSSMutableStyleDeclarationImpl *, const DOM::Position &start, const DOM::Position &end);
DOM::ElementImpl *createDefaultParagraphElement(DOM::DocumentImpl *document);
DOM::ElementImpl *createBlockPlaceholderElement(DOM::DocumentImpl *document);
DOM::ElementImpl *createBreakElement(DOM::DocumentImpl *document);
+DOM::ElementImpl *createFontElement(DOM::DocumentImpl *document);
DOM::ElementImpl *createStyleSpanElement(DOM::DocumentImpl *document);
bool isNodeRendered(const DOM::NodeImpl *);