diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-03-31 18:47:56 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-01 09:10:26 +0200 |
commit | 0e6ee136c91432d4ceeeda64e5a5fa88231398d4 (patch) | |
tree | 6060e002af2900007895f6efa757989dd4c190c9 /src/gui/text/qtexthtmlparser.cpp | |
parent | 418869d9158ea5cd998ba30778b0b7173b48161b (diff) | |
parent | 17294c5e4d15d5776f6e414b03671a4a9ed4993d (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
src/testlib/qtestblacklist.cpp
src/widgets/accessible/qaccessiblewidgets.cpp
Change-Id: If032adb9296428f62384ed835dbf41ee7a0b886c
Diffstat (limited to 'src/gui/text/qtexthtmlparser.cpp')
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 270 |
1 files changed, 206 insertions, 64 deletions
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index edace3d13c..f8f41bb53d 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::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::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::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::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::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::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::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::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::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::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::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; } |