summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/text/qcssparser.cpp24
-rw-r--r--src/gui/text/qcssparser_p.h5
-rw-r--r--src/gui/text/qtexthtmlparser.cpp270
3 files changed, 233 insertions, 66 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index f9e6a7e335..3c98cb568d 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -364,6 +364,29 @@ static quint64 findKnownValue(const QString &name, const QCssKnownValue *start,
return prop->id;
}
+static inline bool isInheritable(Property propertyId)
+{
+ switch (propertyId) {
+ case Font:
+ case FontFamily:
+ case FontSize:
+ case FontStyle:
+ case FontWeight:
+ case TextIndent:
+ case Whitespace:
+ case ListStyleType:
+ case ListStyle:
+ case TextAlignment:
+ case FontVariant:
+ case TextTransform:
+ case LineHeight:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
///////////////////////////////////////////////////////////////////////////////
// Value Extractor
ValueExtractor::ValueExtractor(const QVector<Declaration> &decls, const QPalette &pal)
@@ -2317,6 +2340,7 @@ bool Parser::parseProperty(Declaration *decl)
{
decl->d->property = lexem();
decl->d->propertyId = static_cast<Property>(findKnownValue(decl->d->property, properties, NumProperties));
+ decl->d->inheritable = isInheritable(decl->d->propertyId);
skipSpace();
return true;
}
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index ebd9904762..75802ba36a 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -426,12 +426,13 @@ struct Q_GUI_EXPORT Declaration
{
struct DeclarationData : public QSharedData
{
- inline DeclarationData() : propertyId(UnknownProperty), important(false) {}
+ inline DeclarationData() : propertyId(UnknownProperty), important(false), inheritable(false) {}
QString property;
Property propertyId;
QVector<Value> values;
QVariant parsed;
- bool important;
+ bool important:1;
+ bool inheritable:1;
};
QExplicitlySharedDataPointer<DeclarationData> d;
inline Declaration() : d(new DeclarationData()) {}
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index edace3d13c..866e0046c0 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1050,25 +1050,14 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
// set element specific attributes
switch (id) {
case Html_a:
- charFormat.setAnchor(true);
for (int i = 0; i < attributes.count(); i += 2) {
const QString key = attributes.at(i);
if (key.compare(QLatin1String("href"), Qt::CaseInsensitive) == 0
&& !attributes.at(i + 1).isEmpty()) {
hasHref = true;
- charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- charFormat.setForeground(QGuiApplication::palette().link());
}
}
-
- break;
- case Html_em:
- case Html_i:
- case Html_cite:
- case Html_address:
- case Html_var:
- case Html_dfn:
- charFormat.setFontItalic(true);
+ charFormat.setAnchor(true);
break;
case Html_big:
charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(1));
@@ -1076,36 +1065,27 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
case Html_small:
charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(-1));
break;
- case Html_strong:
- case Html_b:
- charFormat.setFontWeight(QFont::Bold);
- break;
case Html_h1:
- charFormat.setFontWeight(QFont::Bold);
charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(3));
margin[QTextHtmlParser::MarginTop] = 18;
margin[QTextHtmlParser::MarginBottom] = 12;
break;
case Html_h2:
- charFormat.setFontWeight(QFont::Bold);
charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(2));
margin[QTextHtmlParser::MarginTop] = 16;
margin[QTextHtmlParser::MarginBottom] = 12;
break;
case Html_h3:
- charFormat.setFontWeight(QFont::Bold);
charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(1));
margin[QTextHtmlParser::MarginTop] = 14;
margin[QTextHtmlParser::MarginBottom] = 12;
break;
case Html_h4:
- charFormat.setFontWeight(QFont::Bold);
charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(0));
margin[QTextHtmlParser::MarginTop] = 12;
margin[QTextHtmlParser::MarginBottom] = 12;
break;
case Html_h5:
- charFormat.setFontWeight(QFont::Bold);
charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(-1));
margin[QTextHtmlParser::MarginTop] = 12;
margin[QTextHtmlParser::MarginBottom] = 4;
@@ -1114,11 +1094,7 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
margin[QTextHtmlParser::MarginTop] = 12;
margin[QTextHtmlParser::MarginBottom] = 12;
break;
- case Html_center:
- blockFormat.setAlignment(Qt::AlignCenter);
- break;
case Html_ul:
- listStyle = QTextListFormat::ListDisc;
// nested lists don't have margins, except for the toplevel one
if (!isNestedList(parser)) {
margin[QTextHtmlParser::MarginTop] = 12;
@@ -1127,7 +1103,6 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
// no left margin as we use indenting instead
break;
case Html_ol:
- listStyle = QTextListFormat::ListDecimal;
// nested lists don't have margins, except for the toplevel one
if (!isNestedList(parser)) {
margin[QTextHtmlParser::MarginTop] = 12;
@@ -1135,26 +1110,12 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
}
// no left margin as we use indenting instead
break;
- case Html_code:
- case Html_tt:
- case Html_kbd:
- case Html_samp:
- charFormat.setFontFamily(QString::fromLatin1("Courier New,courier"));
- // <tt> uses a fixed font, so set the property
- charFormat.setFontFixedPitch(true);
- break;
case Html_br:
text = QChar(QChar::LineSeparator);
- wsm = QTextHtmlParserNode::WhiteSpacePre;
break;
- // ##### sub / sup
case Html_pre:
- charFormat.setFontFamily(QString::fromLatin1("Courier New,courier"));
- wsm = WhiteSpacePre;
margin[QTextHtmlParser::MarginTop] = 12;
margin[QTextHtmlParser::MarginBottom] = 12;
- // <pre> uses a fixed font
- charFormat.setFontFixedPitch(true);
break;
case Html_blockquote:
margin[QTextHtmlParser::MarginTop] = 12;
@@ -1169,28 +1130,6 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
case Html_dd:
margin[QTextHtmlParser::MarginLeft] = 30;
break;
- case Html_u:
- charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- break;
- case Html_s:
- charFormat.setFontStrikeOut(true);
- break;
- case Html_nobr:
- wsm = WhiteSpaceNoWrap;
- break;
- case Html_th:
- charFormat.setFontWeight(QFont::Bold);
- blockFormat.setAlignment(Qt::AlignCenter);
- break;
- case Html_td:
- blockFormat.setAlignment(Qt::AlignLeft);
- break;
- case Html_sub:
- charFormat.setVerticalAlignment(QTextCharFormat::AlignSubScript);
- break;
- case Html_sup:
- charFormat.setVerticalAlignment(QTextCharFormat::AlignSuperScript);
- break;
default: break;
}
}
@@ -1345,6 +1284,14 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
case QCss::QtListNumberSuffix:
textListNumberSuffix = decl.d->values.first().variant.toString();
break;
+ case QCss::TextAlignment:
+ switch (identifier) {
+ case QCss::Value_Left: blockFormat.setAlignment(Qt::AlignLeft); break;
+ case QCss::Value_Center: blockFormat.setAlignment(Qt::AlignCenter); break;
+ case QCss::Value_Right: blockFormat.setAlignment(Qt::AlignRight); break;
+ default: break;
+ }
+ break;
default: break;
}
}
@@ -1833,6 +1780,189 @@ void QTextHtmlParser::importStyleSheet(const QString &href)
}
}
+QVector<QCss::Declaration> standardDeclarationForNode(const QTextHtmlParserNode &node)
+{
+ QVector<QCss::Declaration> decls;
+ QCss::Declaration decl;
+ QCss::Value val;
+ switch (node.id) {
+ case Html_a:
+ case Html_u: {
+ bool needsUnderline = (node.id == Html_u) ? true : false;
+ if (node.id == Html_a) {
+ for (int i = 0; i < node.attributes.count(); i += 2) {
+ const QString key = node.attributes.at(i);
+ if (key.compare(QLatin1String("href"), Qt::CaseInsensitive) == 0
+ && !node.attributes.at(i + 1).isEmpty()) {
+ needsUnderline = true;
+ decl.d->property = QLatin1String("color");
+ decl.d->propertyId = QCss::Property::Color;
+ val.type = QCss::Value::Color;
+ val.variant = QVariant(QGuiApplication::palette().link());
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ break;
+ }
+ }
+ }
+ if (needsUnderline) {
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("text-decoration");
+ decl.d->propertyId = QCss::Property::TextDecoration;
+ val.type = QCss::Value::KnownIdentifier;
+ val.variant = QVariant(QCss::Value_Underline);
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ }
+ break;
+ }
+ case Html_b:
+ case Html_strong:
+ case Html_h1:
+ case Html_h2:
+ case Html_h3:
+ case Html_h4:
+ case Html_h5:
+ case Html_th:
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("font-weight");
+ decl.d->propertyId = QCss::Property::FontWeight;
+ val.type = QCss::Value::KnownIdentifier;
+ val.variant = QVariant(QCss::Value_Bold);
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ if (node.id == Html_b || node.id == Html_strong)
+ break;
+ // Delibrate fall through
+ case Html_big:
+ case Html_small:
+ if (node.id != Html_th) {
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("font-size");
+ decl.d->propertyId = QCss::Property::FontSize;
+ decl.d->inheritable = false;
+ val.type = QCss::Value::KnownIdentifier;
+ switch (node.id) {
+ case Html_h1: val.variant = QVariant(QCss::Value_XXLarge); break;
+ case Html_h2: val.variant = QVariant(QCss::Value_XLarge); break;
+ case Html_h3: case Html_big: val.variant = QVariant(QCss::Value_Large); break;
+ case Html_h4: val.variant = QVariant(QCss::Value_Medium); break;
+ case Html_h5: case Html_small: val.variant = QVariant(QCss::Value_Small); break;
+ default: break;
+ }
+ decl.d->values = QVector<QCss::Value>() << val;
+ decls << decl;
+ break;
+ }
+ // Delibrate fall through
+ case Html_center:
+ case Html_td:
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("text-align");
+ decl.d->propertyId = QCss::Property::TextAlignment;
+ val.type = QCss::Value::KnownIdentifier;
+ val.variant = (node.id == Html_td) ? QVariant(QCss::Value_Left) : QVariant(QCss::Value_Center);
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ break;
+ case Html_s:
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("text-decoration");
+ decl.d->propertyId = QCss::Property::TextDecoration;
+ val.type = QCss::Value::KnownIdentifier;
+ val.variant = QVariant(QCss::Value_LineThrough);
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ break;
+ case Html_em:
+ case Html_i:
+ case Html_cite:
+ case Html_address:
+ case Html_var:
+ case Html_dfn:
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("font-style");
+ decl.d->propertyId = QCss::Property::FontStyle;
+ val.type = QCss::Value::KnownIdentifier;
+ val.variant = QVariant(QCss::Value_Italic);
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ break;
+ case Html_sub:
+ case Html_sup:
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("vertical-align");
+ decl.d->propertyId = QCss::Property::VerticalAlignment;
+ val.type = QCss::Value::KnownIdentifier;
+ val.variant = (node.id == Html_sub) ? QVariant(QCss::Value_Sub) : QVariant(QCss::Value_Super);
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ break;
+ case Html_ul:
+ case Html_ol:
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("list-style");
+ decl.d->propertyId = QCss::Property::ListStyle;
+ val.type = QCss::Value::KnownIdentifier;
+ val.variant = (node.id == Html_ul) ? QVariant(QCss::Value_Disc) : QVariant(QCss::Value_Decimal);
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ break;
+ case Html_code:
+ case Html_tt:
+ case Html_kbd:
+ case Html_samp:
+ case Html_pre: {
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("font-family");
+ decl.d->propertyId = QCss::Property::FontFamily;
+ QVector<QCss::Value> values;
+ val.type = QCss::Value::String;
+ val.variant = QLatin1String("Courier New");
+ values << val;
+ val.type = QCss::Value::TermOperatorComma;
+ val.variant = QVariant();
+ values << val;
+ val.type = QCss::Value::String;
+ val.variant = QLatin1String("courier");
+ values << val;
+ decl.d->values = values;
+ decl.d->inheritable = true;
+ decls << decl;
+ }
+ if (node.id != Html_pre)
+ break;
+ // Delibrate fall through
+ case Html_br:
+ case Html_nobr:
+ decl = QCss::Declaration();
+ decl.d->property = QLatin1String("whitespace");
+ decl.d->propertyId = QCss::Property::Whitespace;
+ val.type = QCss::Value::KnownIdentifier;
+ switch (node.id) {
+ case Html_br: val.variant = QVariant(QCss::Value_PreWrap); break;
+ case Html_nobr: val.variant = QVariant(QCss::Value_NoWrap); break;
+ case Html_pre: val.variant = QVariant(QCss::Value_Pre); break;
+ default: break;
+ }
+ decl.d->values = QVector<QCss::Value>() << val;
+ decl.d->inheritable = true;
+ decls << decl;
+ break;
+ default:
+ break;
+ }
+ return decls;
+}
+
QVector<QCss::Declaration> QTextHtmlParser::declarationsForNode(int node) const
{
QVector<QCss::Declaration> decls;
@@ -1860,8 +1990,20 @@ QVector<QCss::Declaration> QTextHtmlParser::declarationsForNode(int node) const
const char *extraPseudo = 0;
if (nodes.at(node).id == Html_a && nodes.at(node).hasHref)
extraPseudo = "link";
- decls = selector.declarationsForNode(n, extraPseudo);
-
+ // Ensure that our own style is taken into consideration
+ decls = standardDeclarationForNode(nodes.at(node));
+ decls += selector.declarationsForNode(n, extraPseudo);
+ n = selector.parentNode(n);
+ while (!selector.isNullNode(n)) {
+ QVector<QCss::Declaration> inheritedDecls;
+ inheritedDecls = selector.declarationsForNode(n, extraPseudo);
+ for (int i = 0; i < inheritedDecls.size(); ++i) {
+ const QCss::Declaration &decl = inheritedDecls.at(i);
+ if (decl.d->inheritable)
+ decls.prepend(decl);
+ }
+ n = selector.parentNode(n);
+ }
return decls;
}