Changeset 228482 in webkit
- Timestamp:
- Feb 14, 2018 1:07:38 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r228476 r228482 1 2018-02-12 Ryosuke Niwa <rniwa@webkit.org> 2 3 REGRESSION (r223440): Copying & pasting a list from Microsoft Word to TinyMCE fails 4 https://bugs.webkit.org/show_bug.cgi?id=182564 5 6 Reviewed by Wenson Hsieh. 7 8 Unfortunately, r228352 was inadaquate to fix copying & pasting of a list item from Microsoft Word into TinyMCE 9 in older verions of TinyMCE. This patch amends the approach taken by r228352 to make it work across the board 10 as well as unbreak GMail. 11 12 Turns out older versions of TinyMCE can't handle list items when computed styles are added as inline style 13 declarations by WebKit. To make this work, avoid adding any computed styles as inline styles within mso-list 14 conditionals as well as any p elements whose style attribute contains "mso-list" property. We would instead 15 preserve these styles by keeping Microsoft Word's CSS style rules in addition to special @list rules. 16 17 In addition, not keeping the style element of Microsoft Word in a head element as done in r228352 causes some 18 versions of TinyMCE to treat it as regular text, and inserting a bunch of @list rules as user visible text. 19 To work around this problem, we serialize the style rules as a comment (<!-- ~ -->) within a head element. 20 21 Furthermore, when Microsoft Word is in the compatibility mode, it does not generate xmlns:o as the first xmlns 22 declaration. Generalized the code to detect Microsoft Word's HTML declaration by looking for xmlns:o and xmlns:w 23 xmls declarations. 24 25 Finally, it turns out that Gmail has its own handling of list items copy & pasted from Microsoft Word, and also 26 needs this quirks but in the pasted HTML, not the one exposed in getData. As such, this patch also enables the 27 MSO list quirks in the pasted content as well as the one exposed in getData. 28 29 Tests: PasteHTML.PreservesMSOList 30 PasteHTML.PreservesMSOListInCompatibilityMode 31 PasteHTML.StripsMSOListWhenMissingMSOHTMLElement 32 PasteWebArchive.PreservesMSOList 33 PasteWebArchive.PreservesMSOListInCompatibilityMode 34 PasteWebArchive.StripsMSOListWhenMissingMSOHTMLElement 35 36 * editing/HTMLInterchange.h: 37 * editing/ReplaceSelectionCommand.cpp: 38 (WebCore::removeHeadContents): Don't remove the special style element needed for the MSO list quirks since we 39 don't keep the computed style as inline styles in this case. 40 * editing/cocoa/WebContentReaderCocoa.mm: 41 (WebCore::WebContentReader::readWebArchive): Enable the quirks in the pasted content as well as opposed to 42 just in DataTransfer API exposed to the JavaScript. 43 (WebCore::WebContentReader::readHTML): Ditto. 44 * editing/markup.cpp: 45 (WebCore::shouldPreserveMSOLists): Added. Generalized the logic to detect a Microsoft Word document. 46 more xmlns declarations. 47 (WebCore::StyledMarkupAccumulator::shouldPreserveMSOListStyleForElement): Added. 48 (WebCore::StyledMarkupAccumulator::appendElement): Don't generate the second style element here for elements 49 with most-list properties. Instead, avoid overriding inline styles with computed styles altogether. 50 (WebCore::StyledMarkupAccumulator::appendNodeToPreserveMSOList): Include the style rules as well as list rules 51 and wrap the "style" element in a "head" element to make it compatible with older versions of TinyMCE. 52 1 53 2018-02-14 Dean Jackson <dino@apple.com> 2 54 -
trunk/Source/WebCore/editing/HTMLInterchange.h
r208646 r228482 37 37 #define AppleStyleSpanClass "Apple-style-span" 38 38 #define AppleTabSpanClass "Apple-tab-span" 39 #define WebKitMSOListQuirksStyle "WebKit-mso-list-quirks-style" 39 40 40 41 enum EAnnotateForInterchange { DoNotAnnotateForInterchange, AnnotateForInterchange }; -
trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp
r224213 r228482 729 729 auto end = descendantsOfType<Element>(*fragment.fragment()).end(); 730 730 while (it != end) { 731 if (is<HTMLBaseElement>(*it) || is<HTMLLinkElement>(*it) || is<HTMLMetaElement>(*it) || is<HTMLStyleElement>(*it) || is<HTMLTitleElement>(*it)) { 731 if (is<HTMLBaseElement>(*it) || is<HTMLLinkElement>(*it) || is<HTMLMetaElement>(*it) || is<HTMLTitleElement>(*it) 732 || (is<HTMLStyleElement>(*it) && it->getAttribute(classAttr) != WebKitMSOListQuirksStyle)) { 732 733 toRemove.append(&*it); 733 734 it.traverseNextSkippingChildren(); -
trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm
r228352 r228482 458 458 } 459 459 460 String sanitizedMarkup = sanitizeMarkupWithArchive(*frame.document(), *result, MSOListQuirks::Disabled, [&] (const String& type) {460 String sanitizedMarkup = sanitizeMarkupWithArchive(*frame.document(), *result, msoListQuirksForMarkup(), [&] (const String& type) { 461 461 return frame.loader().client().canShowMIMETypeAsHTML(type); 462 462 }); … … 519 519 String markup; 520 520 if (RuntimeEnabledFeatures::sharedFeatures().customPasteboardDataEnabled() && shouldSanitize()) { 521 markup = sanitizeMarkup(stringOmittingMicrosoftPrefix, MSOListQuirks::Disabled, WTF::Function<void (DocumentFragment&)> { [] (DocumentFragment& fragment) {521 markup = sanitizeMarkup(stringOmittingMicrosoftPrefix, msoListQuirksForMarkup(), WTF::Function<void (DocumentFragment&)> { [] (DocumentFragment& fragment) { 522 522 removeSubresourceURLAttributes(fragment, [] (const URL& url) { 523 523 return shouldReplaceSubresourceURL(url); -
trunk/Source/WebCore/editing/markup.cpp
r228352 r228482 237 237 String stringValueForRange(const Node&, const Range*); 238 238 239 bool shouldPreserveMSOListStyleForElement(const Element&); 240 239 241 void appendElement(StringBuilder& out, const Element&, bool addDisplayInline, RangeFullySelectsNode); 240 242 void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*) override; … … 422 424 } 423 425 426 bool StyledMarkupAccumulator::shouldPreserveMSOListStyleForElement(const Element& element) 427 { 428 return m_inMSOList || (m_shouldPreserveMSOList && element.hasTagName(pTag) && element.getAttribute(styleAttr).contains(";mso-list:")); 429 } 430 424 431 void StyledMarkupAccumulator::appendElement(StringBuilder& out, const Element& element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode) 425 432 { … … 430 437 431 438 const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldAnnotate() || addDisplayInline); 432 const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element); 433 bool containsMSOList = false; 439 bool shouldOverrideStyleAttr = (shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element)) && !shouldPreserveMSOListStyleForElement(element); 434 440 if (element.hasAttributes()) { 435 441 for (const Attribute& attribute : element.attributesIterator()) { 436 442 // We'll handle the style attribute separately, below. 437 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) { 438 if (m_shouldPreserveMSOList && attribute.value().contains(";mso-list:")) 439 containsMSOList = true; 443 if (attribute.name() == styleAttr && shouldOverrideStyleAttr) 440 444 continue; 441 }442 445 if (element.isEventHandlerAttribute(attribute) || element.isJavaScriptURLAttribute(attribute)) 443 446 continue; … … 480 483 out.appendLiteral(" style=\""); 481 484 appendAttributeValue(out, newInlineStyle->style()->asText(), documentIsHTML); 482 out.append('\"');483 }484 485 if (containsMSOList) {486 ASSERT(m_shouldPreserveMSOList);487 // Unfortunately, TinyMCE doesn't recognize mso-list inline style if the style attribute contains properties.488 // Generate a separate, second style attribute if newInlineStyle is not empty above.489 // The inline style is preserved because the first attribute always wins but TinyMCE can still recognize the list.490 out.appendLiteral(" style=\"");491 appendAttributeValue(out, element.getAttribute(styleAttr), documentIsHTML);492 485 out.append('\"'); 493 486 } … … 616 609 auto& styleContent = textChild.data(); 617 610 611 const auto msoStyleDefinitionsStart = styleContent.find("/* Style Definitions */"); 618 612 const auto msoListDefinitionsStart = styleContent.find("/* List Definitions */"); 619 613 const auto lastListItem = styleContent.reverseFind("\n@list"); 620 614 if (msoListDefinitionsStart == notFound || lastListItem == notFound) 621 615 return false; 616 const auto start = msoStyleDefinitionsStart != notFound && msoStyleDefinitionsStart < msoListDefinitionsStart ? msoStyleDefinitionsStart : msoListDefinitionsStart; 622 617 623 618 const auto msoListDefinitionsEnd = styleContent.find(";}\n", lastListItem); 624 if (msoListDefinitionsEnd == notFound || msoListDefinitionsStart >= msoListDefinitionsEnd)619 if (msoListDefinitionsEnd == notFound || start >= msoListDefinitionsEnd) 625 620 return false; 626 621 627 appendStartTag(node); 628 appendTextSubstring(textChild, msoListDefinitionsStart, msoListDefinitionsEnd - msoListDefinitionsStart + 1); 629 appendEndTag(node); 622 appendString("<head><style class=\"" WebKitMSOListQuirksStyle "\">\n<!--\n"); 623 appendTextSubstring(textChild, start, msoListDefinitionsEnd - start + 3); 624 appendString("\n-->\n</style></head>"); 625 630 626 return true; 631 627 } … … 840 836 } 841 837 838 static bool shouldPreserveMSOLists(const String& markup) 839 { 840 if (!markup.startsWith("<html xmlns:")) 841 return false; 842 auto tagClose = markup.find('>'); 843 if (tagClose == notFound) 844 return false; 845 auto htmlTag = markup.substring(0, tagClose); 846 return htmlTag.contains("xmlns:o=\"urn:schemas-microsoft-com:office:office\"") 847 && htmlTag.contains("xmlns:w=\"urn:schemas-microsoft-com:office:word\""); 848 } 849 842 850 String sanitizedMarkupForFragmentInDocument(Ref<DocumentFragment>&& fragment, Document& document, MSOListQuirks msoListQuirks, const String& originalMarkup) 843 851 { 844 MSOListMode msoListMode = MSOListMode::DoNotPreserve; 845 if (msoListQuirks == MSOListQuirks::CheckIfNeeded && originalMarkup.startsWith("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"")) 846 msoListMode = MSOListMode::Preserve; 852 MSOListMode msoListMode = msoListQuirks == MSOListQuirks::CheckIfNeeded && shouldPreserveMSOLists(originalMarkup) 853 ? MSOListMode::Preserve : MSOListMode::DoNotPreserve; 847 854 848 855 auto bodyElement = makeRefPtr(document.body()); -
trunk/Tools/ChangeLog
r228480 r228482 1 2018-02-12 Ryosuke Niwa <rniwa@webkit.org> 2 3 REGRESSION (r223440): Copying & pasting a list from Microsoft Word to TinyMCE fails 4 https://bugs.webkit.org/show_bug.cgi?id=182564 5 6 Reviewed by Wenson Hsieh. 7 8 Updated assertions to make sure the trailing "}" of @list rules is includd in the style, the "style" element 9 is wrapped by "head" element (not present in the pasted markup since the fragment parsing algorithm strips away), 10 and the style content is enclosed in "<!--" and "-->". 11 12 Also use execCommand('insertHTML', ~) to insert the HTML obtained via dataTransfer.getData instead of innerHTML 13 to make sure our pasting code preserves the special style element for MSO list quirks. 14 15 Finally, added two more test cases for pasting content from Microsoft Word's compatibility mode. 16 17 * TestWebKitAPI/Tests/WebKitCocoa/PasteHTML.mm: 18 (TEST): 19 * TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm: 20 (TEST): 21 1 22 2018-02-14 Ross Kirsling <ross.kirsling@sony.com> 2 23 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r228430 r228482 581 581 9B270FEE1DDC2C0B002D53F3 /* closed-shadow-tree-test.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B270FED1DDC25FD002D53F3 /* closed-shadow-tree-test.html */; }; 582 582 9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; }; 583 9B59F12A2034086F009E63D5 /* mso-list-compat-mode.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B59F12920340854009E63D5 /* mso-list-compat-mode.html */; }; 583 584 9B62630C1F8C25C8007EE29B /* copy-url.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B62630B1F8C2510007EE29B /* copy-url.html */; }; 584 585 9B7A37C41F8AEBA5004AA228 /* CopyURL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */; }; … … 1023 1024 7A1458FC1AD5C07000E06772 /* mouse-button-listener.html in Copy Resources */, 1024 1025 33E79E06137B5FD900E32D99 /* mouse-move-listener.html in Copy Resources */, 1026 9B59F12A2034086F009E63D5 /* mso-list-compat-mode.html in Copy Resources */, 1025 1027 9BF356CD202D458500F71160 /* mso-list.html in Copy Resources */, 1026 1028 5797FE331EB15AB100B2F4A0 /* navigation-client-default-crypto.html in Copy Resources */, … … 1605 1607 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = "<group>"; }; 1606 1608 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; }; 1609 9B59F12920340854009E63D5 /* mso-list-compat-mode.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "mso-list-compat-mode.html"; sourceTree = "<group>"; }; 1607 1610 9B62630B1F8C2510007EE29B /* copy-url.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "copy-url.html"; sourceTree = "<group>"; }; 1608 1611 9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstResponderScrollingPosition.mm; sourceTree = "<group>"; }; … … 2454 2457 46C519E41D35629600DAA51A /* LocalStorageNullEntries.localstorage-shm */, 2455 2458 7A6A2C711DCCFB0200C0D085 /* LocalStorageQuirkEnabled.html */, 2459 9B59F12920340854009E63D5 /* mso-list-compat-mode.html */, 2456 2460 9BF356CC202D44F200F71160 /* mso-list.html */, 2457 2461 93E2D2751ED7D51700FA76F6 /* offscreen-iframe-of-media-document.html */, -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteHTML.mm
r228352 r228482 171 171 172 172 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 173 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 174 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue); 175 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* List Definitions */')"].boolValue); 176 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('@list l0:level1')"].boolValue); 177 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('}\\n\\n-->\\n</style>')"].boolValue); 178 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[if !supportLists]')"].boolValue); 179 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[endif]')"].boolValue); 180 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 181 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/Users/webkitten/Library/')"].boolValue); 182 183 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 184 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"]; 185 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]); 186 187 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 188 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('<head><style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 189 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue); 190 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* List Definitions */')"].boolValue); 191 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('@list l0:level1')"].boolValue); 192 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('}\\n\\n-->\\n</style></head>')"].boolValue); 193 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[if !supportLists]')"].boolValue); 194 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[endif]')"].boolValue); 195 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 196 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/Users/webkitten/Library/')"].boolValue); 197 198 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''; editor.focus();"]; 199 [webView stringByEvaluatingJavaScript:@"document.execCommand('insertHTML', false, htmlInDataTransfer);"]; 200 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 201 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"]; 202 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]); 203 } 204 205 TEST(PasteHTML, PreservesMSOListInCompatibilityMode) 206 { 207 writeHTMLToPasteboard([NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"mso-list-compat-mode" ofType:@"html" inDirectory:@"TestWebKitAPI.resources"] 208 encoding:NSUTF8StringEncoding error:NULL]); 209 210 auto webView = createWebViewWithCustomPasteboardDataSetting(true); 211 [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"]; 212 [webView paste:nil]; 213 214 EXPECT_WK_STREQ("[\"text/html\"]", [webView stringByEvaluatingJavaScript:@"JSON.stringify(clipboardData.types)"]); 215 [webView stringByEvaluatingJavaScript:@"window.htmlInDataTransfer = clipboardData.values[0]"]; 216 [webView stringByEvaluatingJavaScript:@"window.pastedHTML = editor.innerHTML"]; 217 218 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 219 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 220 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue); 221 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* List Definitions */')"].boolValue); 222 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('@list l0:level1')"].boolValue); 223 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('}\\n\\n-->\\n</style>')"].boolValue); 224 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[if !supportLists]')"].boolValue); 225 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[endif]')"].boolValue); 226 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<p style=\"margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 227 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/Users/webkitten/Library/')"].boolValue); 228 229 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 230 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('<head><style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 231 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue); 232 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* List Definitions */')"].boolValue); 233 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('@list l0:level1')"].boolValue); 234 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('}\\n\\n-->\\n</style></head>')"].boolValue); 235 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[if !supportLists]')"].boolValue); 236 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[endif]')"].boolValue); 237 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<p style=\"margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 238 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/Users/webkitten/Library/')"].boolValue); 239 } 240 241 TEST(PasteHTML, StripsMSOListWhenMissingMSOHTMLElement) 242 { 243 auto *markup = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"mso-list" ofType:@"html" inDirectory:@"TestWebKitAPI.resources"] encoding:NSUTF8StringEncoding error:NULL]; 244 245 writeHTMLToPasteboard([markup substringFromIndex:[markup rangeOfString:@">"].location + 1]); 246 247 auto webView = createWebViewWithCustomPasteboardDataSetting(true); 248 [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"]; 249 [webView paste:nil]; 250 251 EXPECT_WK_STREQ("[\"text/html\"]", [webView stringByEvaluatingJavaScript:@"JSON.stringify(clipboardData.types)"]); 252 [webView stringByEvaluatingJavaScript:@"window.htmlInDataTransfer = clipboardData.values[0]"]; 253 [webView stringByEvaluatingJavaScript:@"window.pastedHTML = editor.innerHTML"]; 254 255 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 256 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 257 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue); 173 258 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* List Definitions */')"].boolValue); 174 259 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('@list l0:level1')"].boolValue); 260 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('}\\n\\n-->\\n</style>')"].boolValue); 175 261 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[if !supportLists]')"].boolValue); 176 262 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[endif]')"].boolValue); 177 263 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 178 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue);179 264 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/Users/webkitten/Library/')"].boolValue); 180 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 181 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"]; 182 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]); 183 184 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 185 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* List Definitions */')"].boolValue); 186 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('@list l0:level1')"].boolValue); 187 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[if !supportLists]')"].boolValue); 188 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[endif]')"].boolValue); 189 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 265 266 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 267 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"]; 268 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]); 269 270 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 271 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('<head><style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 190 272 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue); 191 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/Users/webkitten/Library/')"].boolValue);192 193 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = htmlInDataTransfer"];194 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"];195 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"];196 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]);197 }198 199 TEST(PasteHTML, StripsMSOListWhenMissingMSOHTMLElement)200 {201 auto *markup = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"mso-list" ofType:@"html" inDirectory:@"TestWebKitAPI.resources"] encoding:NSUTF8StringEncoding error:NULL];202 203 writeHTMLToPasteboard([markup substringFromIndex:[markup rangeOfString:@">"].location + 1]);204 205 auto webView = createWebViewWithCustomPasteboardDataSetting(true);206 [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];207 [webView paste:nil];208 209 EXPECT_WK_STREQ("[\"text/html\"]", [webView stringByEvaluatingJavaScript:@"JSON.stringify(clipboardData.types)"]);210 [webView stringByEvaluatingJavaScript:@"window.htmlInDataTransfer = clipboardData.values[0]"];211 [webView stringByEvaluatingJavaScript:@"window.pastedHTML = editor.innerHTML"];212 213 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue);214 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* List Definitions */')"].boolValue);215 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('@list l0:level1')"].boolValue);216 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[if !supportLists]')"].boolValue);217 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[endif]')"].boolValue);218 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue);219 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue);220 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/Users/webkitten/Library/')"].boolValue);221 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"];222 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"];223 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]);224 225 273 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* List Definitions */')"].boolValue); 226 274 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('@list l0:level1')"].boolValue); 275 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('}\\n\\n-->\\n</style></head>')"].boolValue); 227 276 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[if !supportLists]')"].boolValue); 228 277 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[endif]')"].boolValue); 229 278 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 230 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue);231 279 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/Users/webkitten/Library/')"].boolValue); 232 280 233 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = htmlInDataTransfer"]; 281 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''; editor.focus();"]; 282 [webView stringByEvaluatingJavaScript:@"document.execCommand('insertHTML', false, htmlInDataTransfer);"]; 234 283 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 235 284 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"]; -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm
r228352 r228482 121 121 122 122 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 123 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* List Definitions */')"].boolValue); 124 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('@list l0:level1')"].boolValue); 125 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[if !supportLists]')"].boolValue); 126 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[endif]')"].boolValue); 127 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 128 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue); 123 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 124 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue); 125 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* List Definitions */')"].boolValue); 126 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('@list l0:level1')"].boolValue); 127 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('}\\n\\n-->\\n</style>')"].boolValue); 128 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[if !supportLists]')"].boolValue); 129 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[endif]')"].boolValue); 130 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 129 131 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/Users/webkitten/Library/')"].boolValue); 132 130 133 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 131 134 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"]; … … 133 136 134 137 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 138 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('<head><style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 139 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue); 135 140 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* List Definitions */')"].boolValue); 136 141 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('@list l0:level1')"].boolValue); 142 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('}\\n\\n-->\\n</style></head>')"].boolValue); 137 143 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[if !supportLists]')"].boolValue); 138 144 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[endif]')"].boolValue); 139 145 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 140 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue);141 146 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/Users/webkitten/Library/')"].boolValue); 142 147 143 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = htmlInDataTransfer"]; 148 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''; editor.focus();"]; 149 [webView stringByEvaluatingJavaScript:@"document.execCommand('insertHTML', false, htmlInDataTransfer);"]; 144 150 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 145 151 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"]; 146 152 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]); 147 153 } 154 155 TEST(PasteWebArchive, PreservesMSOListInCompatibilityMode) 156 { 157 auto *url = [NSURL URLWithString:@"file:///some-file.html"]; 158 auto *markup = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"mso-list-compat-mode" ofType:@"html" inDirectory:@"TestWebKitAPI.resources"]]; 159 auto mainResource = adoptNS([[WebResource alloc] initWithData:markup URL:url MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]); 160 auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:nil subframeArchives:nil]); 161 162 [[NSPasteboard generalPasteboard] declareTypes:@[WebArchivePboardType] owner:nil]; 163 [[NSPasteboard generalPasteboard] setData:[archive data] forType:WebArchivePboardType]; 164 165 auto webView = createWebViewWithCustomPasteboardDataEnabled(); 166 [webView synchronouslyLoadTestPageNamed:@"paste-rtfd"]; 167 [webView paste:nil]; 168 169 EXPECT_WK_STREQ("[\"text/html\"]", [webView stringByEvaluatingJavaScript:@"JSON.stringify(clipboardData.types)"]); 170 [webView stringByEvaluatingJavaScript:@"window.htmlInDataTransfer = clipboardData.values[0]"]; 171 [webView stringByEvaluatingJavaScript:@"window.pastedHTML = editor.innerHTML"]; 172 173 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 174 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 175 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* Style Definitions */')"].boolValue); 176 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/* List Definitions */')"].boolValue); 177 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('@list l0:level1')"].boolValue); 178 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('}\\n\\n-->\\n</style>')"].boolValue); 179 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[if !supportLists]')"].boolValue); 180 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('[endif]')"].boolValue); 181 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<p style=\"margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 182 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('/Users/webkitten/Library/')"].boolValue); 183 184 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 185 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('<head><style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 186 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue); 187 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* List Definitions */')"].boolValue); 188 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('@list l0:level1')"].boolValue); 189 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('}\\n\\n-->\\n</style></head>')"].boolValue); 190 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[if !supportLists]')"].boolValue); 191 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[endif]')"].boolValue); 192 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"pastedHTML.includes('<p style=\"margin-left:.5in;text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 193 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/Users/webkitten/Library/')"].boolValue); 148 194 } 149 195 … … 178 224 [webView stringByEvaluatingJavaScript:@"window.htmlInDataTransfer = clipboardData.values[0]"]; 179 225 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.startsWith('<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"')"].boolValue); 226 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('<head><style class=\"WebKit-mso-list-quirks-style\">\\n<!--\\n')"].boolValue); 227 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue); 180 228 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* List Definitions */')"].boolValue); 181 229 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('@list l0:level1')"].boolValue); 230 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('}\\n\\n-->\\n</style></head>')"].boolValue); 182 231 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[if !supportLists]')"].boolValue); 183 232 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('[endif]')"].boolValue); 184 233 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes(' style=\"text-indent:-.25in;mso-list:l0 level1 lfo1\">')"].boolValue); 185 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/* Style Definitions */')"].boolValue);186 234 EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"htmlInDataTransfer.includes('/Users/webkitten/Library/')"].boolValue); 187 235 188 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = htmlInDataTransfer"]; 236 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''; editor.focus();"]; 237 [webView stringByEvaluatingJavaScript:@"document.execCommand('insertHTML', false, htmlInDataTransfer);"]; 189 238 [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.querySelector('.MsoListParagraphCxSpLast'));"]; 190 239 [webView stringByEvaluatingJavaScript:@"getSelection().modify('move', 'forward', 'lineboundary');"];
Note: See TracChangeset
for help on using the changeset viewer.