From 532c01c388c7ab408b0e244fd73849ace8d96f0a Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 27 Feb 2025 19:51:36 +0000 Subject: [PATCH] LibWeb: Implement text-decoration: spelling-error and grammar-error --- Libraries/LibWeb/CSS/ComputedProperties.cpp | 7 ++- Libraries/LibWeb/CSS/Enums.json | 4 +- Libraries/LibWeb/CSS/Keywords.json | 2 + .../LibWeb/CSS/Parser/PropertyParsing.cpp | 12 +++++ Libraries/LibWeb/Painting/PaintableBox.cpp | 44 +++++++++++++++++- .../Screenshot/images/text-decorations.png | Bin 15304 -> 22572 bytes .../Screenshot/input/text-decorations.html | 4 ++ .../parsing/text-decoration-line-computed.txt | 7 ++- .../parsing/text-decoration-line-valid.txt | 7 ++- 9 files changed, 74 insertions(+), 13 deletions(-) diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index 89330897b5..966722f318 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -1008,8 +1008,11 @@ Vector ComputedProperties::text_decoration_line() const return lines; } - if (value.is_keyword() && value.to_keyword() == Keyword::None) - return {}; + if (value.is_keyword()) { + if (value.to_keyword() == Keyword::None) + return {}; + return { keyword_to_text_decoration_line(value.to_keyword()).release_value() }; + } dbgln("FIXME: Unsupported value for text-decoration-line: {}", value.to_string(CSSStyleValue::SerializationMode::Normal)); return {}; diff --git a/Libraries/LibWeb/CSS/Enums.json b/Libraries/LibWeb/CSS/Enums.json index 6b03f3f473..eb328f1d00 100644 --- a/Libraries/LibWeb/CSS/Enums.json +++ b/Libraries/LibWeb/CSS/Enums.json @@ -545,7 +545,9 @@ "underline", "overline", "line-through", - "blink" + "blink", + "spelling-error", + "grammar-error" ], "text-decoration-style": [ "dashed", diff --git a/Libraries/LibWeb/CSS/Keywords.json b/Libraries/LibWeb/CSS/Keywords.json index 5c6267ed0b..82a1d38bd5 100644 --- a/Libraries/LibWeb/CSS/Keywords.json +++ b/Libraries/LibWeb/CSS/Keywords.json @@ -190,6 +190,7 @@ "fullscreen", "grab", "grabbing", + "grammar-error", "graytext", "grid", "groove", @@ -404,6 +405,7 @@ "space-around", "space-between", "space-evenly", + "spelling-error", "square", "square-button", "srgb", diff --git a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp index 03b0b84e6a..896253fe0b 100644 --- a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp @@ -3510,6 +3510,8 @@ RefPtr Parser::parse_text_decoration_line_value(TokenStream Parser::parse_text_decoration_line_value(TokenStream Parser::parse_text_decoration_line_value(TokenStream 1 && includes_spelling_or_grammar_error_value) + return nullptr; + + if (style_values.size() == 1) + return *style_values.first(); + quick_sort(style_values, [](auto& left, auto& right) { return *keyword_to_text_decoration_line(left->to_keyword()) < *keyword_to_text_decoration_line(right->to_keyword()); }); diff --git a/Libraries/LibWeb/Painting/PaintableBox.cpp b/Libraries/LibWeb/Painting/PaintableBox.cpp index 70f6c55050..d7ae415cc3 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -682,6 +682,7 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable auto baseline = fragment.baseline(); auto line_color = paintable.computed_values().text_decoration_color(); + auto line_style = paintable.computed_values().text_decoration_style(); auto const& text_paintable = static_cast(fragment.paintable()); auto device_line_thickness = context.rounded_device_pixels(text_paintable.text_decoration_thickness()); @@ -690,6 +691,24 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable DevicePixelPoint line_start_point {}; DevicePixelPoint line_end_point {}; + if (line == CSS::TextDecorationLine::SpellingError) { + // https://drafts.csswg.org/css-text-decor-4/#valdef-text-decoration-line-spelling-error + // This value indicates the type of text decoration used by the user agent to highlight spelling mistakes. + // Its appearance is UA-defined, and may be platform-dependent. It is often rendered as a red wavy underline. + line_color = Color::Red; + device_line_thickness = context.rounded_device_pixels(1); + line_style = CSS::TextDecorationStyle::Wavy; + line = CSS::TextDecorationLine::Underline; + } else if (line == CSS::TextDecorationLine::GrammarError) { + // https://drafts.csswg.org/css-text-decor-4/#valdef-text-decoration-line-grammar-error + // This value indicates the type of text decoration used by the user agent to highlight grammar mistakes. + // Its appearance is UA defined, and may be platform-dependent. It is often rendered as a green wavy underline. + line_color = Color::DarkGreen; + device_line_thickness = context.rounded_device_pixels(1); + line_style = CSS::TextDecorationStyle::Wavy; + line = CSS::TextDecorationLine::Underline; + } + switch (line) { case CSS::TextDecorationLine::None: return; @@ -710,9 +729,13 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable case CSS::TextDecorationLine::Blink: // Conforming user agents may simply not blink the text return; + case CSS::TextDecorationLine::SpellingError: + case CSS::TextDecorationLine::GrammarError: + // Handled above. + VERIFY_NOT_REACHED(); } - switch (paintable.computed_values().text_decoration_style()) { + switch (line_style) { case CSS::TextDecorationStyle::Solid: painter.draw_line(line_start_point.to_type(), line_end_point.to_type(), line_color, device_line_thickness.value(), Gfx::LineStyle::Solid); break; @@ -742,7 +765,24 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable painter.draw_line(line_start_point.to_type(), line_end_point.to_type(), line_color, device_line_thickness.value(), Gfx::LineStyle::Dotted); break; case CSS::TextDecorationStyle::Wavy: - painter.draw_triangle_wave(line_start_point.to_type(), line_end_point.to_type(), line_color, device_line_thickness.value() + 1, device_line_thickness.value()); + auto amplitude = device_line_thickness.value() * 3; + switch (line) { + case CSS::TextDecorationLine::Underline: + line_start_point.translate_by(0, device_line_thickness + context.rounded_device_pixels(1)); + line_end_point.translate_by(0, device_line_thickness + context.rounded_device_pixels(1)); + break; + case CSS::TextDecorationLine::Overline: + line_start_point.translate_by(0, -device_line_thickness - context.rounded_device_pixels(1)); + line_end_point.translate_by(0, -device_line_thickness - context.rounded_device_pixels(1)); + break; + case CSS::TextDecorationLine::LineThrough: + line_start_point.translate_by(0, -device_line_thickness / 2); + line_end_point.translate_by(0, -device_line_thickness / 2); + break; + default: + VERIFY_NOT_REACHED(); + } + painter.draw_triangle_wave(line_start_point.to_type(), line_end_point.to_type(), line_color, amplitude, device_line_thickness.value()); break; } } diff --git a/Tests/LibWeb/Screenshot/images/text-decorations.png b/Tests/LibWeb/Screenshot/images/text-decorations.png index 74bf0e3938f77443f91f4ebaed464c3f9d63d605..dfb47c2b2b69ddbb799bfdeb01e73f0b4a954226 100644 GIT binary patch literal 22572 zcmb@uby!s4zdfoV1`^UGprn*^mrA!t*C5>>-Hb(dH%NCQUDA!i&?z~9bjJX{7r%Ax zxzD-JxzD}-@UTbOGkfp%U7ycdpS337oq{9=8VTB+J9jXorNrLfxr6fj&YgQ2kM4n2 z@bU2J?%Yv7loorV;yS%O_qYttI1S-3pYVvvJtt*-|73D|;F#aKMwIlM;be8DdZ~I- zb20jKZB=dK&P<{IqooIw&%gUq=KV&?dw#FN{~p?x=Rr&NUOs>1&qVqCWggR)it($| z!#IR|;ZUzb2TF4L<&_v}L`+OfLQF#Lf%*-iHw*G6l3JRpAT{ZABz5m68tF)*R`3G* z2kCzvsu12A-yHKX3}Z$fio{`z7Mm;ZbqX;`M_TB$UL5qdE!=peLz*fcq6ij?!jW*1 zI#U|y_smZ;Mn7Ng?0PG3?Ef}bn#&tkP`&`C9cjkWkfhL!RSD(ID5C9Hrnp{23?Seqz4+q3hQ#JV4tR|8&ZkyT3X0J>4hGg&`DouyypA>T0uSgNN zoX)v4_<;-X#xKizq3bZnbw33KOK|VvPpQZa@{m|~C0ulEC`EhuPr3C>wbP&R2!!+2 zTh_9j+KYMA%EIJbd=C^=JcbIM7W2^=x}g7hYx7RycL6QTtIJ zuQ!%SGjeGz4)W}!bmU3pr?DbU4xHf>m-z&;bMS5)>>0!3#oB}{kYq?kl-g+8UOSe^ zK$-{?dA9F$d9poGs+VZe8HnHHahl3uirFq3_bP?mScXKe#oKGG(F{hJYBS%M5UNMY zZRM}YWjo&pKC9(;QNZsX=J1>?2GzeeLW{60RPaCwXZZKeua#8l#af*`2^^;Ev&Gsq znPI~2{jtnG2R0jcHT;h2Por-C5YiRTW@vy6CgyPE|Im8p?Fb(tx&7lzwe>Ph1-2p~ zlSb=aKTFF1>thxi)d8bl-`_O4PZ`INIZx_uPyf(v`qQ-?!z>#~o$riVl;(Yr-`4oH z&OgGo`JA>ricZnQb#pWy9bVPFXBZ|#5Rv!h>jS~7-(RuT@t~df>Q4h=nYFuQcbhM5 z?la-M4-|tjNf`$%uK(upJp1Si&atMkt|Up;seF%OJ4QZ7st@*D>l4eb@O$w|&Tk70h?CP@TnBGMMP6Y}I3Sxm~Ag z8V31z*3XN1TAfCAF-v9o?L;}otOV0}N>r)jo_jy3Q=h(#a=Ax7;o*tqC!r znDh*Yyi$H5ubqKl)5)}DuaM3i*FVKI?85c!%J9DGDVU?{@t8Wix<{6}fN1K63A(u|a`|vD3x~jd;}~4Q8z>|2VB5 z7M;qQ8v9j>X~Ow|v6X*6F=1Kl_pk;?gl;W=Sn8GzhtyTTbEi3{34Cui51%|IJ48Y4 z760e0c*D>DZzZ3=o#$w;aG2Z!Fb{%rqX^nXebM!6jr(Kw-{&f%xK7vFExTS!Tb7C! z^y|gmZs^9SOOM?qLb3t#hk{4HM3+r=^t_H$6F*(DKZ7FoBNA#ESVLNtLj??|F`VW5 z#qAi~OF5!OjA3z%P6^PB>^P#FDK^OFR3)9_u+ZtO>jk(<3B_}yG1%l|BR4@GuP%;{ zh@szS*I}8mNsIh0JI~J7N*Z=#sOVjkik2kyI>>gi#=!1$r81_w=yZVkjiACRH~pzX z{d3xtG9}1dX6>kRUCn1}?c@_V)9KU%b?fYDf-=)t|FLpTMLbHZ&!A3bKY|r@{)H|m z;L0M=HU3{5-UW;PAIS9gZ~v#mEHAP$?~9FGG6Cn&0Cf%ptf>jIEM6S=4o3)lBs3a@YTo$})1Qfx2X+j&n`|#Q8Xw51!CFd2p zZnEwk08CpyRA;NLXX>5)0PrLFQT1OS3jtPcJz*K9z!q!8=+;yvoQP5(>lMy0M7z`H z3E?$;4OJV(m&#BB4%t`RyV$43A=WaxeO%p zaWrX76?Fv@!%OvAh_1myTN_Rj@kX8j%*~0=C^rz_oo_-6B((31WXtBtB}8@sJQEok z;RZkja9e|*(gJMCKjXy{MVh!jE#W!xQ>$u!A566&-XvCZblC%F?Fl@f^?cO2qF zu-@Jd*8r;yIO-DuR^&lH3&(7cW~G!0TNHqv{Y~RIU5T+`-3I4E_0pl+)jZPtSi>~g z?m_xDg;k%(@p>uNBTmzJ2~h?)InVu0!o#EeZVE*>^y+xR==l=iaz2MRwZ*URcNIm> zexs03l-4exQNk*W`&|RxYyMXV1CN=iB%Trn z9Ig!p)p#QJyMqW>cE$<`+o>dif749gC(b$Lzrl&2m5Xovs8VcDv5vuQHOcC0P8^)g zX))@b`;fwu^=FU(ua5Wms$dGI`TOe%u|f~2Tb!bai)aOotB()I8Z)7;h) ztln6T<|&~sKyR+t><~jKm4gnt^^W>0qxs5}REoTd-wI2c6JsSIluDgFCAtj+&T~GD z4<1WId~wU`r)6!)I@*T`!0^Q2u@W zWdHqWTE!#N;51<`cQlQBNkX30C3>eK*Xdlvw9%r3zi0@SS1lomYMMLE`as8+o6mtI ziXnR3@%~W|OY?`blNsBv8aPW}*P90bW9mnFg47xfL-}Yg#PJ#GznUd#6AT7zxOcq} z^<|yCebD*Jxe9{T09ypTwtq~x$~^iDiX+08rS^FucIv}c^%)qiRKL!9Uv6*dk`kqr z>}t1o3)!wf_SAKqROLji>E}CB$PCc`LSv=w5k%y2t5R0|E9OCCM<1SZ%%Dxv@wjWg z>2RuGcCNZ$_5gv<>R}w{?W$OADosl|mknN*{LT!+F7rNt> z75IE!;+|s2wv)IF?58v*+;p&}if)@w;<8&r?WKJSe*gatu!Zj?LA8#g zk(KGbIf5%5B8Cy!+cP!0t7FCi0?u0>YXIW$6PNWU9`}J}r(``_QTUu1LTNtMBg5Jb zkWu(_)Rv9P_ z@HLSna$9Q=lwM~*{36H#A!GoVU-&((ByVsoQY}t|C*?7z-k~{{0-df!U=)@obsl zBu}B|oA_aRNvJH^Zyw!a(KX+*?=v94Q z+b40wBB^&!Xzzll-u8vs#BFbWos(pvRqwbFqo|`kp&aMH@5h-FZTi6O38^QR&Hs2mo*hwqB6s-S-mBuQFgPxr;`rCQhEf>~))vAoC zb1^p(pGv+SOu=R#)>yN=9xC^m`eG@Fg$Q2fU<%Q#{rI9ibAepPrb9NU_t23_ok>s+vDrbrFkCo9z_?tPh{Fz z`#57=gYT?+N(e84=#Hl#=RJ1in`-@)H`cO26Jq$OTChvx>Ilx3s!8^-^)8#-W+1VI zN+4eup6^2}@@Fh5;8cRyN$P^zljVkJ4oBa27g|ILy?&w+vfBS{{k&rZpm`T%Jdw-t zeFpeJfSr5WX+;0I9x(z9`Ui9;ra+A+1WfDjTt&I|Vq(|hRF9n(FYuk`xHut8(8hEu z0hHO+l>OQECdlJgD8VjcrFv<(j^(ED%{o(`#5pJxJ&x9~73-|Rb19%myA$PK{JlNW zQM7fHG=C|1$9K>uVp0ev2jdt5@Rk%W07MD)Jl^wsHSSxMvZ4@IQuxxzpKs}adFIj& z^DYPXXxl}h?xc3IvIX(uj?wO54s!(<{iqxk7MQC%%8F9RsJP|XZ{5C9d2RZk6XUSh z`7zrx-|n0a<+XM}_^RIv8RH-VW_wfF$Sg04GPIU!sKJ`II_Rph!|+`04z?6t0$%q> z=qRq>C;r)HVX6DcR)UNkvgVfx>}B;FXkK^B0r{sxQQO|%u2~qVNlCI*LSLrUhC#tv z`;U+jdD~O}=kPze#($GJ{>Q`Hg7jZBk-vvk5AUfBrwRe|?*lF5ZJEBUA=5wp0Cs#a zz%kso*Y*V9xEH{%1e3)!pXKhbG*2hC;FXW;)I>E7bn|E98UCUqG+IyXLS}-YtCg z`|A$h-`h9NTr-QaxK`GV=>Z6awA5(H11$2}o;U0npZ)$)r(8Q6FAL(iFHY+L%7B35 z`s)`AT@*ml(5|-9mw^Pb)yz4QJ`OOL1gqqD)?s-6)f$0pBRE0AZ&2fQX6qbkZ0263 z@0WOAU0{%Kt~Z^|2bt%Yh*yITUf^-}k1wf>zm%9(ffWhKwLzjb<5Y!l%;0w06BeU;7Aky}oty)GLUhuRn?|km7n_AtI4RE4=9v;9i9#MH(?2YO za)>!hnXbmofo0r|567?)~I+eU6BGPz3ZLtLIwGsge(?_)NlXWjIFenCC# z$CqypAu=F|B+#8Oj2|I9wT$Po96wm?herd77_8oMwiE@&hBRpa-&T>7GXjsM5nWx0K(?#Y6n=IZYWn)M_a)*v2beTU;Ktki8GkMky~M2 z`!@V>JbNlmXKn92!}YJXLfcmKZCh1D6OqK#!Fe=TV3i1V%*&i9&{_fD`AcaP9uz&m zAQ20D*{2dCUuiSPU!UPndCcjnu!9{?Tkhf92X1$%M)?Rg_-Ps-pgC%tM;e6u+{^xYf@5e z7MicFFLx0lP4rFeZ$o}Ve@pX_#Q^D0!~^iV|9?Q^KM3>RAZ0u5uI1%8v&dE1wV$ne z>E-6(k2DsYCbRLrx?Sd^^YK`D(u0Lshwji6f$Ck;8Os*rJ5Z-sP?;)JN)K=BTcoTUcaC=DmAS`uAr_bEz>`V|p$21kmk8pk z(+K?3^JFJ}f&AlKJOE*WvT?6Et68d=$TWyKbShk6=#SI2h*-&{+s?vq(ue8QG^kR-E@VUruBxOm6Q#)oGLXK!}_cCuBBIv>Moi1~L?DR)3hU{iz4# zHr;(T0zTB#L(8M92|IqT@glOBn&KOG@s#=33rwk`FYLDu6i*lZ z61gf^{_M&4^%ut5AciWsZOV52(`RKo9&_hc1=&;TdfTovjAiby zEd~Tf#o?IT`J%t6_cj_Hb4ESsArI41&Dr{x@W5tfgqNkovN|-Ew2s=`_94@dgeTQ7 z(TNz$6-_HxkKgNFd*PZ_*;!LLk~cK2`ueOrXSX@$MlJCSo}X!EkaXGA8rF>-f2Gxu zP0^^?sR-(X_jK(mlOA=Emd47`=Hr#Q%m$qngP|(dzUY`izeGtb2NK^r3{QUJmCLUb z3Bp_ZoEYM@rw@+L?0?GnwpS7tVthn69$cMcEj+`~T?LW_{HXVcsHo{jm~```J!t~k?+iKaJ=!AGR1{u5 zoJdoF=y)zVfiG&I~UMvodx`oY|}{G4PmgP#*Bm zrum%MVSY-WN=-$|d7PZtFx`7bhZHa4S=gBHi5=XGjjOgznr%R-WU%d+-P5+m7xBnB z+Bg%7g04&`J)4Z#b_~TBcQE?{^|-*giE@p*N-`GS#ayrc*jH$`=kU713ppR1Me;)~MMcs7u7j4y6mquK&_B^Gs7tG9iuQXZ&43GT6?@(GSRIP>^eM%ddEZzcbX| zfrzZlEJY468aD$OC{)4Zg|@&lQQO;RARY9@j>0I3SE;=fbQ?!f+wyt?ZhpB;5#gh| zUCKn{Guvyf0l(YerG!wOqjX-vE;(Mh{mt*%!|p3vH-{lRHCAUPs@E0v3V}_fyxf-r zCPXadK5l*EIj$$j;~T7YA(E>J6)8h6gA2)<ZOU%aCTc@y zieA+maHcdaA8zFbwMU=L*el?w$pt|bCdr+AJl%Iiv3=N*tLZJXvHBI{tTl>;mrm!u zkBUuy@D-!%f}0E)Aul_(YUq90W^cNbr=IXxYAk}MVbW20lvhDh-X>ngm}d4~q=7_=Ym)fWbk?quG-og$zf8>Ix{wS_HnNm+T zt5fJXN}<;+&sL;yuA&ZYDbQU=k|jc?Fwvj3-Gr7`dzX+r+hXu!ZjZAAr*)a77_yn=6X0N;8BTjF`oZ zc&YHA-&8)^jP0x%DsL)0^d7s6_dJ{9nce5OJgaPzUl~~Vy70a}S5qWc+Dj9Kp&mUo z<2)$qRpmtT>lqAu)M_k>bHvg@bi}@XK3f)?Pl*bWE%Q@Z&G%fHgDRrqJ~q!GkKqYi zoZUZE49}KG5&AtDKU7P0ARO+Xxz4v-Y6!Cx8go`Bwngb>AKA;hED5?c=d%;5 z*ZQ0J8V*iTJ-d^Yd@ZjS)Yw0K2a-|8QGuDQlPbYFUA-!KBD>;2&_{ZB^P0D$f;3R% z+Zi76Zdd$g<{O^Xmokn_LS154>h-^j_f*YaA~1dGd#Xb8RDE3|yolEuMd{ zb6*QO9z1}*CZPFNfh!$#!6}PveD)SW&up;KnCf2ti&ELKt>nPIERXZ38JPy8GVIim z5tT_Nc}>qbhxu&CTc={CdnY?jOH0nqbcarh$e9C-bBD>9iF;AQ_6ZceeWN2u8kzb+ z`@%O9M^q)_iAcL$MHcrv0<}Kvh(O^{hlv!T-pJqLoW!%6ThZk9v8oAaxx^gb9dVV0 z0_yCh?wTGsRtG)E?{O5irCgfR9)IMtfkJ&jo zOJ_e^%|&b3`a_V?8gD&SRKgp3CWUhJMVgBDY(oj5o=ZI@*BYodmTj6SrQ*5W1()K3 z`yI)N4Dz*@z)|RyH&2;ftVVN{CLb>>Z6vMIjaFgqVr-Gq<>uACJCKg~R1x4YA0d

c9EV@COJr-Dj~bt)?2#5QpoOT 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 @@ -17,5 +19,7 @@

This underline should match the text color

This should have an underline, overline and line-through, all in glorious magenta.

+

This should look like a spelling error.

+

This should look like a grammar error.

diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-computed.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-computed.txt index 4bf73195b2..7e200ec73e 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-computed.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-computed.txt @@ -2,8 +2,7 @@ Harness status: OK Found 18 tests -16 Pass -2 Fail +18 Pass Pass Property text-decoration-line value 'none' Pass Property text-decoration-line value 'underline' Pass Property text-decoration-line value 'overline' @@ -20,5 +19,5 @@ Pass Property text-decoration-line value 'underline overline blink' Pass Property text-decoration-line value 'underline line-through blink' Pass Property text-decoration-line value 'overline line-through blink' Pass Property text-decoration-line value 'underline overline line-through blink' -Fail Property text-decoration-line value 'spelling-error' -Fail Property text-decoration-line value 'grammar-error' \ No newline at end of file +Pass Property text-decoration-line value 'spelling-error' +Pass Property text-decoration-line value 'grammar-error' \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-valid.txt index 1bbd4f0b60..1ddf11c6b5 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-valid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/parsing/text-decoration-line-valid.txt @@ -2,8 +2,7 @@ Harness status: OK Found 67 tests -65 Pass -2 Fail +67 Pass Pass e.style['text-decoration-line'] = "none" should set the property value Pass e.style['text-decoration-line'] = "underline" should set the property value Pass e.style['text-decoration-line'] = "overline" should set the property value @@ -69,5 +68,5 @@ Pass e.style['text-decoration-line'] = "blink overline underline line-through" s Pass e.style['text-decoration-line'] = "blink overline line-through underline" should set the property value Pass e.style['text-decoration-line'] = "blink line-through underline overline" should set the property value Pass e.style['text-decoration-line'] = "blink line-through overline underline" should set the property value -Fail e.style['text-decoration-line'] = "spelling-error" should set the property value -Fail e.style['text-decoration-line'] = "grammar-error" should set the property value \ No newline at end of file +Pass e.style['text-decoration-line'] = "spelling-error" should set the property value +Pass e.style['text-decoration-line'] = "grammar-error" should set the property value \ No newline at end of file