android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / qa / extras / htmlimport / htmlimport.cxx
blob34900529ada9d85cb6425ff8168028eaf10b6bcd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/graphic/XGraphic.hpp>
13 #include <com/sun/star/graphic/GraphicType.hpp>
14 #include <com/sun/star/drawing/FillStyle.hpp>
15 #include <com/sun/star/drawing/BitmapMode.hpp>
16 #include <com/sun/star/document/XEmbeddedObjectSupplier2.hpp>
17 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
18 #include <com/sun/star/embed/XInplaceObject.hpp>
19 #include <com/sun/star/text/XTextTable.hpp>
21 #include <tools/datetime.hxx>
22 #include <sfx2/linkmgr.hxx>
23 #include <comphelper/propertyvalue.hxx>
25 #include <docsh.hxx>
26 #include <editsh.hxx>
27 #include <ndgrf.hxx>
28 #include <ndtxt.hxx>
29 #include <txatbase.hxx>
30 #include <fmtflcnt.hxx>
31 #include <fmtfsize.hxx>
32 #include <frameformats.hxx>
33 #include <unotxdoc.hxx>
35 class HtmlImportTest : public SwModelTestBase
37 public:
38 HtmlImportTest() : SwModelTestBase("sw/qa/extras/htmlimport/data/", "HTML (StarWriter)") {}
41 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testPictureImport)
43 createSwWebDoc("picture.html");
44 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
45 CPPUNIT_ASSERT(pTextDoc);
46 // The document contains two pictures stored as a link.
47 sfx2::LinkManager& rLinkManager = pTextDoc->GetDocShell()->GetDoc()->GetEditShell()->GetLinkManager();
48 CPPUNIT_ASSERT_EQUAL(size_t(2), rLinkManager.GetLinks().size());
49 rLinkManager.Remove(0,2);
50 CPPUNIT_ASSERT_EQUAL(size_t(0), rLinkManager.GetLinks().size());
52 // TODO: Get the data into clipboard in html format and paste
54 // But when pasting we don't want images to be linked.
55 CPPUNIT_ASSERT_EQUAL(size_t(0), rLinkManager.GetLinks().size());
58 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testInlinedImage)
60 createSwWebDoc("inlined_image.html");
61 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
62 CPPUNIT_ASSERT(pTextDoc);
63 // The document contains only one embedded picture inlined in img's src attribute.
65 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
66 SwEditShell* pEditShell = pDoc->GetEditShell();
67 CPPUNIT_ASSERT(pEditShell);
69 // This was 1 before 3914a711060341345f15b83656457f90095f32d6
70 const sfx2::LinkManager& rLinkManager = pEditShell->GetLinkManager();
71 CPPUNIT_ASSERT_EQUAL(size_t(0), rLinkManager.GetLinks().size());
73 uno::Reference<drawing::XShape> xShape = getShape(1);
74 uno::Reference<container::XNamed> const xNamed(xShape, uno::UNO_QUERY_THROW);
75 CPPUNIT_ASSERT_EQUAL(OUString("Image1"), xNamed->getName());
77 uno::Reference<graphic::XGraphic> xGraphic = getProperty< uno::Reference<graphic::XGraphic> >(xShape, "Graphic");
78 CPPUNIT_ASSERT(xGraphic.is());
79 CPPUNIT_ASSERT(xGraphic->getType() != graphic::GraphicType::EMPTY);
81 for (SwNodeOffset n(0); ; n++)
83 SwNode* pNode = pDoc->GetNodes()[ n ];
84 if (SwGrfNode *pGrfNode = pNode->GetGrfNode())
86 // FIXME? For some reason without the fix in 72703173066a2db5c977d422ace
87 // I was getting GraphicType::NONE from SwEditShell::GetGraphicType() when
88 // running LibreOffice but cannot reproduce that in a unit test here. :-(
89 // So, this does not really test anything.
90 CPPUNIT_ASSERT(pGrfNode->GetGrfObj().GetType() != GraphicType::NONE);
91 break;
96 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testInlinedImagesPageAndParagraph)
98 createSwWebDoc("PageAndParagraphFilled.html");
99 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
100 CPPUNIT_ASSERT(pTextDoc);
102 // The document contains embedded pictures inlined for PageBackground and
103 // ParagraphBackground, check for their existence after import
104 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
105 SwEditShell* pEditShell = pDoc->GetEditShell();
106 CPPUNIT_ASSERT(pEditShell);
108 // images are not linked, check for zero links
109 const sfx2::LinkManager& rLinkManager = pEditShell->GetLinkManager();
110 CPPUNIT_ASSERT_EQUAL(size_t(0), rLinkManager.GetLinks().size());
112 // get the pageStyle where the PageBackgroundFill is defined. Caution: for
113 // HTML mode this is *not* called 'Default Style', but 'HTML'. Name is empty
114 // due to being loaded embedded. BitmapMode is repeat.
115 uno::Reference<beans::XPropertySet> xPageProperties1(getStyles("PageStyles")->getByName("HTML"), uno::UNO_QUERY);
116 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xPageProperties1, "FillStyle"));
117 CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPageProperties1, "FillBitmapName"));
118 CPPUNIT_ASSERT_EQUAL(drawing::BitmapMode_REPEAT, getProperty<drawing::BitmapMode>(xPageProperties1, "FillBitmapMode"));
120 // we should have one paragraph
121 const int nParagraphs = getParagraphs();
122 CPPUNIT_ASSERT_EQUAL(1, nParagraphs);
124 if(nParagraphs)
126 // get the paragraph
127 uno::Reference<text::XTextRange> xPara = getParagraph(1);
128 uno::Reference< beans::XPropertySet > xParagraphProperties( xPara, uno::UNO_QUERY);
130 // check for Bitmap FillStyle, name empty, repeat
131 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xParagraphProperties, "FillStyle"));
132 CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xParagraphProperties, "FillBitmapName"));
133 CPPUNIT_ASSERT_EQUAL(drawing::BitmapMode_REPEAT, getProperty<drawing::BitmapMode>(xParagraphProperties, "FillBitmapMode"));
137 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testListStyleType)
139 createSwWebDoc("list-style.html");
140 // check unnumbered list style - should be type circle here
141 uno::Reference< beans::XPropertySet > xParagraphProperties(getParagraph(4),
142 uno::UNO_QUERY);
143 uno::Reference<container::XIndexAccess> xLevels(
144 xParagraphProperties->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
145 uno::Sequence<beans::PropertyValue> aProps;
146 xLevels->getByIndex(0) >>= aProps; // 1st level
148 bool bBulletFound=false;
149 for (beans::PropertyValue const & rProp : std::as_const(aProps))
151 if (rProp.Name == "BulletChar")
153 // should be 'o'.
154 CPPUNIT_ASSERT_EQUAL(OUString(u"\uE009"), rProp.Value.get<OUString>());
155 bBulletFound = true;
156 break;
159 CPPUNIT_ASSERT_MESSAGE("no BulletChar property found for para 4", bBulletFound);
161 // check numbered list style - should be type lower-alpha here
162 xParagraphProperties.set(getParagraph(14),
163 uno::UNO_QUERY);
164 xLevels.set(xParagraphProperties->getPropertyValue("NumberingRules"),
165 uno::UNO_QUERY);
166 xLevels->getByIndex(0) >>= aProps; // 1st level
168 for (beans::PropertyValue const & rProp : std::as_const(aProps))
170 if (rProp.Name == "NumberingType")
172 printf("style is %d\n", rProp.Value.get<sal_Int16>());
173 // is lower-alpha in input, translates into chars_lower_letter here
174 CPPUNIT_ASSERT_EQUAL(style::NumberingType::CHARS_LOWER_LETTER,
175 rProp.Value.get<sal_Int16>());
176 return;
179 CPPUNIT_FAIL("no NumberingType property found for para 14");
182 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testMetaIsoDates)
184 createSwWebDoc("meta-ISO8601-dates.html");
185 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
186 CPPUNIT_ASSERT(pTextDoc);
187 SwDocShell* pDocShell(pTextDoc->GetDocShell());
188 uno::Reference<document::XDocumentProperties> xDocProps;
190 CPPUNIT_ASSERT(pDocShell);
191 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(pDocShell->GetModel(), uno::UNO_QUERY);
192 xDocProps.set(xDPS->getDocumentProperties());
194 // get the document properties
195 CPPUNIT_ASSERT(xDocProps.is());
196 DateTime aCreated(xDocProps->getCreationDate()); // in the new format
197 DateTime aModified(xDocProps->getModificationDate()); // in the legacy format (what LibreOffice used to write)
199 CPPUNIT_ASSERT_EQUAL(DateTime(Date(7, 5, 2017), tools::Time(12, 34, 3, 921000000)), aCreated);
200 CPPUNIT_ASSERT_EQUAL(DateTime(Date(8, 5, 2017), tools::Time(12, 47, 0, 386000000)), aModified);
203 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testImageWidthAuto)
205 createSwWebDoc("image-width-auto.html");
206 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
207 CPPUNIT_ASSERT(pTextDoc);
208 SwTextAttr const*const pAttr(pTextDoc->GetDocShell()->GetDoc()->GetEditShell()->
209 GetCursor()->GetPointNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
210 CPPUNIT_ASSERT(pAttr);
211 SwFrameFormat const*const pFmt(pAttr->GetFlyCnt().GetFrameFormat());
212 SwFormatFrameSize const& rSize(pFmt->GetFormatAttr(RES_FRM_SIZE));
213 CPPUNIT_ASSERT_EQUAL(Size(1835, 560), rSize.GetSize());
216 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testImageLazyRead)
218 createSwWebDoc("image-lazy-read.html");
219 auto xGraphic = getProperty<uno::Reference<graphic::XGraphic>>(getShape(1), "Graphic");
220 Graphic aGraphic(xGraphic);
221 // This failed, import loaded the graphic, it wasn't lazy-read.
222 CPPUNIT_ASSERT(!aGraphic.isAvailable());
225 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testChangedby)
227 createSwWebDoc("meta-changedby.html");
228 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
229 CPPUNIT_ASSERT(pTextDoc);
230 SwDocShell* pDocShell(pTextDoc->GetDocShell());
231 uno::Reference<document::XDocumentProperties> xDocProps;
233 CPPUNIT_ASSERT(pDocShell);
234 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(pDocShell->GetModel(), uno::UNO_QUERY);
235 xDocProps.set(xDPS->getDocumentProperties());
237 // get the document properties
238 CPPUNIT_ASSERT(xDocProps.is());
240 // the doc's property ModifiedBy is set correctly, ...
241 CPPUNIT_ASSERT_EQUAL(OUString("Blah"), xDocProps->getModifiedBy());
243 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
244 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
245 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
247 // ...but there is no comment 'HTML: <meta name="changedby" content="Blah">'
248 CPPUNIT_ASSERT(!xFields->hasMoreElements());
251 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTableBorder1px)
253 createSwWebDoc("table_border_1px.html");
254 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
255 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
256 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
257 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
259 table::BorderLine2 aBorder;
261 uno::Reference<text::XTextRange> xCellA1(xTable->getCellByName("A1"), uno::UNO_QUERY);
262 aBorder = getProperty<table::BorderLine2>(xCellA1, "TopBorder");
263 CPPUNIT_ASSERT_MESSAGE("Missing cell top border", aBorder.InnerLineWidth > 0);
264 aBorder = getProperty<table::BorderLine2>(xCellA1, "BottomBorder");
265 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell bottom border", sal_Int16(0), aBorder.InnerLineWidth);
266 aBorder = getProperty<table::BorderLine2>(xCellA1, "LeftBorder");
267 CPPUNIT_ASSERT_MESSAGE("Missing cell left border", aBorder.InnerLineWidth > 0);
268 aBorder = getProperty<table::BorderLine2>(xCellA1, "RightBorder");
269 CPPUNIT_ASSERT_MESSAGE("Missing cell right border", aBorder.InnerLineWidth > 0);
271 uno::Reference<text::XTextRange> xCellB1(xTable->getCellByName("B1"), uno::UNO_QUERY);
272 aBorder = getProperty<table::BorderLine2>(xCellB1, "TopBorder");
273 CPPUNIT_ASSERT_MESSAGE("Missing cell top border", aBorder.InnerLineWidth > 0);
274 aBorder = getProperty<table::BorderLine2>(xCellB1, "BottomBorder");
275 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell bottom border", sal_Int16(0), aBorder.InnerLineWidth);
276 aBorder = getProperty<table::BorderLine2>(xCellB1, "LeftBorder");
277 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell left border", sal_Int16(0), aBorder.InnerLineWidth);
278 aBorder = getProperty<table::BorderLine2>(xCellB1, "RightBorder");
279 CPPUNIT_ASSERT_MESSAGE("Missing cell right border", aBorder.InnerLineWidth > 0);
281 uno::Reference<text::XTextRange> xCellA2(xTable->getCellByName("A2"), uno::UNO_QUERY);
282 aBorder = getProperty<table::BorderLine2>(xCellA2, "TopBorder");
283 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell top border", sal_Int16(0), aBorder.InnerLineWidth);
284 aBorder = getProperty<table::BorderLine2>(xCellA2, "BottomBorder");
285 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell bottom border", sal_Int16(0), aBorder.InnerLineWidth);
286 aBorder = getProperty<table::BorderLine2>(xCellA2, "LeftBorder");
287 CPPUNIT_ASSERT_MESSAGE("Missing cell left border", aBorder.InnerLineWidth > 0);
288 aBorder = getProperty<table::BorderLine2>(xCellA2,"RightBorder");
289 CPPUNIT_ASSERT_MESSAGE("Missing cell right border", aBorder.InnerLineWidth > 0);
291 uno::Reference<text::XTextRange> xCellB2(xTable->getCellByName("B2"), uno::UNO_QUERY);
292 aBorder = getProperty<table::BorderLine2>(xCellB2, "TopBorder");
293 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell top border", sal_Int16(0), aBorder.InnerLineWidth);
294 aBorder = getProperty<table::BorderLine2>(xCellB2, "BottomBorder");
295 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell bottom border", sal_Int16(0), aBorder.InnerLineWidth);
296 aBorder = getProperty<table::BorderLine2>(xCellB2, "LeftBorder");
297 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected cell left border", sal_Int16(0), aBorder.InnerLineWidth);
298 aBorder = getProperty<table::BorderLine2>(xCellB2, "RightBorder");
299 CPPUNIT_ASSERT_MESSAGE("Missing cell right border", aBorder.InnerLineWidth > 0);
302 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testOutlineLevel)
304 createSwWebDoc("outline-level.html");
305 // This was 0, HTML imported into Writer lost the outline numbering for
306 // Heading 1 styles.
307 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
308 getProperty<sal_Int32>(getParagraph(1), "OutlineLevel"));
311 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testReqIfBr)
313 setImportFilterOptions("xhtmlns=reqif-xhtml");
314 setImportFilterName("HTML (StarWriter)");
315 createSwDoc("reqif-br.xhtml");
316 // <reqif-xhtml:br/> was not recognized as a line break from a ReqIf file.
317 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("aaa\nbbb"));
320 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTdf80194_subscript)
322 createSwWebDoc("tdf80194_subscript.html");
323 uno::Reference<text::XTextRange> xPara = getParagraph(1);
324 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1), "CharEscapement"), 0);
325 // Most recently, the default subscript was 33%, which is much too large for a subscript.
326 // The original 8% (derived from a mathematical calculation) is much better in general,
327 // and for HTML was a better match when testing with firefox.
328 // DFLT_ESC_AUTO_SUB was tested, but HTML specs are pretty loose, and generally
329 // it exceeds the font ascent - so the formula-based-escapement is not appropriate.
330 CPPUNIT_ASSERT_DOUBLES_EQUAL( -8.f, getProperty<float>(getRun(xPara, 2, "p"), "CharEscapement"), 1);
332 xPara.set(getParagraph(2));
333 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1), "CharEscapement"), 0);
334 uno::Reference<text::XTextRange> xRun (getRun(xPara, 2, "L"));
335 CPPUNIT_ASSERT_DOUBLES_EQUAL( 33.f, getProperty<float>(xRun, "CharEscapement"), 1);
336 // HTML (although unspecified) tends to use a fairly large font. Definitely more than DFLT_ESC_PROP.
337 CPPUNIT_ASSERT( 70 < getProperty<sal_Int8>(xRun, "CharEscapementHeight"));
340 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testReqIfTable)
342 setImportFilterOptions("xhtmlns=reqif-xhtml");
343 setImportFilterName("HTML (StarWriter)");
344 createSwDoc("reqif-table.xhtml");
345 // to see this: soffice --infilter="HTML (StarWriter):xhtmlns=reqif-xhtml" sw/qa/extras/htmlimport/data/reqif-table.xhtml
346 // Load a table with xhtmlns=reqif-xhtml filter param.
347 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
348 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
349 uno::UNO_QUERY);
350 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xTables->getCount());
351 uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
352 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
353 auto aBorder = getProperty<table::BorderLine2>(xCell, "TopBorder");
354 // This was 0, tables had no borders, even if the default autoformat has
355 // borders and the markup allows no custom borders.
356 CPPUNIT_ASSERT_EQUAL_MESSAGE("Top Border", static_cast<sal_uInt32>(18), aBorder.LineWidth);
357 aBorder = getProperty<table::BorderLine2>(xCell, "BottomBorder");
358 CPPUNIT_ASSERT_EQUAL_MESSAGE("Bottom Border", static_cast<sal_uInt32>(18), aBorder.LineWidth);
359 aBorder = getProperty<table::BorderLine2>(xCell, "LeftBorder");
360 CPPUNIT_ASSERT_EQUAL_MESSAGE("Left Border", static_cast<sal_uInt32>(18), aBorder.LineWidth);
361 aBorder = getProperty<table::BorderLine2>(xCell, "RightBorder");
362 // This was 0. Single column tables had no right border. tdf#115576
363 CPPUNIT_ASSERT_EQUAL_MESSAGE("Right Border", static_cast<sal_uInt32>(18), aBorder.LineWidth);
366 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testImageSize)
368 createSwWebDoc("image-size.html");
369 awt::Size aSize = getShape(1)->getSize();
370 OutputDevice* pDevice = Application::GetDefaultDevice();
371 Size aPixelSize(200, 400);
372 Size aExpected = pDevice->PixelToLogic(aPixelSize, MapMode(MapUnit::Map100thMM));
374 // This was 1997, i.e. a hardcoded default, we did not look at the image
375 // header when the HTML markup declared no size.
376 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(aExpected.getWidth()), aSize.Width);
377 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(aExpected.getHeight()), aSize.Height);
380 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTdf142781)
382 createSwWebDoc("tdf142781.html");
383 OutputDevice* pDevice = Application::GetDefaultDevice();
384 Size aPixelSize(672, 480);
385 Size aExpected = pDevice->PixelToLogic(aPixelSize, MapMode(MapUnit::Map100thMM));
386 awt::Size aSize = getShape(1)->getSize();
387 // Without the fix in place, this test would have failed with
388 // - Expected: 12700
389 // - Actual: 25400
390 // CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(aExpected.getHeight()), aSize.Height);
391 aSize = getShape(2)->getSize();
392 // Without the fix in place, this test would have failed with
393 // - Expected: 17780
394 // - Actual: 35560
395 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(aExpected.getWidth()), aSize.Width);
399 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTdf122789)
401 createSwWebDoc("tdf122789.html");
402 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
403 CPPUNIT_ASSERT(pTextDoc);
404 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
405 const auto& rFormats = *pDoc->GetSpzFrameFormats();
406 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rFormats.size());
407 // This failed, the image had an absolute size, not a relative one.
408 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt8>(70), rFormats[0]->GetAttrSet().GetFrameSize().GetWidthPercent());
411 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTdf118579)
413 createSwWebDoc("tdf118579.html");
414 //Without the fix in place, the file fails to load
415 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
416 CPPUNIT_ASSERT(pTextDoc);
419 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testReqIfPageStyle)
421 setImportFilterOptions("xhtmlns=reqif-xhtml");
422 setImportFilterName("HTML (StarWriter)");
423 createSwDoc("reqif-page-style.xhtml");
424 // Without the accompanying fix in place, this test would have failed with
425 // 'Expected: Standard, Actual : HTML'.
426 CPPUNIT_ASSERT_EQUAL(OUString("Standard"),
427 getProperty<OUString>(getParagraph(1), "PageStyleName"));
430 /// HTML import to the sw doc model tests.
431 class SwHtmlOptionsImportTest : public SwModelTestBase
433 public:
434 SwHtmlOptionsImportTest() : SwModelTestBase("/sw/qa/extras/htmlimport/data/", "HTML (StarWriter)") {}
437 CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testAllowedRTFOLEMimeTypes)
439 uno::Sequence<OUString> aTypes = { OUString("test/rtf") };
440 uno::Sequence<beans::PropertyValue> aLoadProperties = {
441 comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")),
442 comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")),
443 comphelper::makePropertyValue("AllowedRTFOLEMimeTypes", aTypes),
445 OUString aURL = createFileURL(u"allowed-rtf-ole-mime-types.xhtml");
446 mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", aLoadProperties);
447 uno::Reference<text::XTextEmbeddedObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
448 uno::Reference<container::XIndexAccess> xObjects(xSupplier->getEmbeddedObjects(),
449 uno::UNO_QUERY);
450 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xObjects->getCount());
451 uno::Reference<document::XEmbeddedObjectSupplier2> xObject(xObjects->getByIndex(0),
452 uno::UNO_QUERY);
453 CPPUNIT_ASSERT(xObject.is());
454 uno::Reference<embed::XInplaceObject> xEmbeddedObject(
455 xObject->getExtendedControlOverEmbeddedObject(), uno::UNO_QUERY);
456 // Without the accompanying fix in place, this test would have failed, because the returned
457 // embedded object was a dummy one, which does not support in-place editing.
458 CPPUNIT_ASSERT(xEmbeddedObject.is());
461 CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testHiddenTextframe)
463 // Load HTML content into Writer, similar to HTML paste.
464 createSwWebDoc("hidden-textframe.html");
466 // Check the content of the draw page.
467 uno::Reference<drawing::XDrawPageSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
468 uno::Reference<drawing::XDrawPage> xDrawPage = xSupplier->getDrawPage();
470 // Without the accompanying fix in place, this test would have failed with:
471 // - Expected: 0
472 // - Actual : 1
473 // i.e. an unexpected text frame was created, covering the actual content.
474 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount());
477 CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testOleImg)
479 // Given an XHTML with an <object> (containing GIF) and an inner <object> (containing PNG, to be
480 // ignored):
481 setImportFilterOptions("xhtmlns=reqif-xhtml");
482 setImportFilterName("HTML (StarWriter)");
483 createSwDoc("ole-img.xhtml");
485 // Then make sure the result is a single Writer image:
486 uno::Reference<text::XTextGraphicObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
487 uno::Reference<container::XIndexAccess> xObjects(xSupplier->getGraphicObjects(),
488 uno::UNO_QUERY);
489 // Without the accompanying fix in place, this test would have failed with:
490 // - Expected: 0
491 // - Actual : 1
492 // i.e. the image was not imported as a Writer image (but as an OLE object).
493 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xObjects->getCount());
496 CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testOleImgSvg)
498 // Given an XHTML with an <object> (containing SVG) and an inner <object> (containing PNG, to be
499 // ignored):
500 setImportFilterOptions("xhtmlns=reqif-xhtml");
501 setImportFilterName("HTML (StarWriter)");
502 createSwDoc("ole-img-svg.xhtml");
504 // Then make sure the result is a single Writer image:
505 uno::Reference<text::XTextGraphicObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
506 uno::Reference<container::XIndexAccess> xObjects(xSupplier->getGraphicObjects(),
507 uno::UNO_QUERY);
508 // Without the accompanying fix in place, this test would have failed with:
509 // - Expected: 0
510 // - Actual : 1
511 // i.e. the image was not imported as a Writer image (but as an OLE object).
512 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xObjects->getCount());
515 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testUTF16_nonBMP)
517 createSwWebDoc("emojis16BE.html");
518 // tdf#146173: non-BMP characters' surrogates didn't combine correctly
519 CPPUNIT_ASSERT_EQUAL(OUString(u"a text with emojis: 🌾 β˜€πŸ‘¨πŸΌβ€πŸŒΎπŸƒπŸΌβ€β™‚οΈπŸ€™πŸ½πŸ”"),
520 getParagraph(1)->getString());
523 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTdf154273)
525 createSwWebDoc("tdf154273.html");
527 // Without the fix in place, this test would have failed with
528 // - Expected: 'test'
529 // - Actual : &apos;test&apos;
530 CPPUNIT_ASSERT_EQUAL(OUString("'test' "), getParagraph(1)->getString());
533 CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testOleData)
535 // Given an XHTML with an <object> (containing non-image, non-OLE2 data) and an inner <object>
536 // (containing PNG):
537 setImportFilterOptions("xhtmlns=reqif-xhtml");
538 setImportFilterName("HTML (StarWriter)");
539 createSwDoc("ole-data.xhtml");
541 // Then make sure the result is a single clickable Writer image:
542 uno::Reference<text::XTextGraphicObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
543 uno::Reference<container::XIndexAccess> xObjects(xSupplier->getGraphicObjects(),
544 uno::UNO_QUERY);
545 // Without the accompanying fix in place, this test would have failed with:
546 // - Expected: 0
547 // - Actual : 1
548 // i.e. the image was not imported as a Writer image (but as an OLE object).
549 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xObjects->getCount());
550 uno::Reference<css::drawing::XShape> xShape = getShape(1);
551 // And then the image was not clickable: this was empty.
552 CPPUNIT_ASSERT(getProperty<OUString>(xShape, "HyperLinkURL").endsWith("/data.ole"));
555 CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testOleData2)
557 // Given an XHTML with 2 objects: the first has a link, the second does not have:
558 setImportFilterOptions("xhtmlns=reqif-xhtml");
559 setImportFilterName("HTML (StarWriter)");
560 createSwDoc("ole-data2.xhtml");
562 // Then make sure that the second image doesn't have a link set:
563 uno::Reference<text::XTextGraphicObjectsSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
564 uno::Reference<container::XIndexAccess> xObjects(xSupplier->getGraphicObjects(),
565 uno::UNO_QUERY);
566 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xObjects->getCount());
567 uno::Reference<css::drawing::XShape> xShape = getShape(1);
568 CPPUNIT_ASSERT(getProperty<OUString>(xShape, "HyperLinkURL").endsWith("/data.ole"));
569 xShape = getShape(2);
570 // Without the accompanying fix in place, this test would have failed, the link from the 1st
571 // image leaked to the 2nd image.
572 CPPUNIT_ASSERT(getProperty<OUString>(xShape, "HyperLinkURL").isEmpty());
575 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testRGBAColor)
577 createSwWebDoc("green-highlight.html");
578 const uno::Reference<text::XTextRange> xPara = getParagraph(1);
579 const uno::Reference<beans::XPropertySet> xRun(getRun(xPara,1), uno::UNO_QUERY);
580 const Color nBackColor(0xaed89a);
582 // Without the accompanying fix in place, this test would have failed, the background
583 // color was not imported at all, when it was in hex RGBA format in HTML.
584 CPPUNIT_ASSERT_EQUAL(nBackColor, getProperty<Color>(xRun, "CharBackColor"));
587 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTdf153341)
589 createSwWebDoc("tdf153341.html");
591 const uno::Reference<text::XTextRange> xPara1 = getParagraph(1);
592 const uno::Reference<beans::XPropertySet> xRun1(getRun(xPara1,1), uno::UNO_QUERY);
593 CPPUNIT_ASSERT_EQUAL(Color(ColorTransparency, 0x00, 0xFF, 0x00, 0x00), getProperty<Color>(xRun1, "CharColor"));
595 const uno::Reference<text::XTextRange> xPara2 = getParagraph(2);
596 const uno::Reference<beans::XPropertySet> xRun2(getRun(xPara2,1), uno::UNO_QUERY);
598 // Without the fix in place, this test would have failed with
599 // - Expected: rgba[ff00007f]
600 // - Actual : rgba[ff0000ff]
601 CPPUNIT_ASSERT_EQUAL(Color(ColorTransparency, 0x80, 0xFF, 0x00, 0x00), getProperty<Color>(xRun2, "CharColor"));
603 const uno::Reference<text::XTextRange> xPara3 = getParagraph(3);
604 const uno::Reference<beans::XPropertySet> xRun3(getRun(xPara3,1), uno::UNO_QUERY);
605 CPPUNIT_ASSERT_EQUAL(Color(ColorTransparency, 0xB3, 0xFF, 0x00, 0x00), getProperty<Color>(xRun3, "CharColor"));
608 CPPUNIT_TEST_FIXTURE(HtmlImportTest, testTdf155011)
610 createSwWebDoc("tdf155011.html");
611 // Must not crash / fail asserts
614 CPPUNIT_PLUGIN_IMPLEMENT();
616 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */