diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-02-26 15:55:17 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-02-27 09:09:54 +0100 |
commit | 61e4c00eee8c5d07a29cf7ec97bad653e3e8f8ce (patch) | |
tree | 0b1e7a824d52a655315e8bc22eccc8bd76031a75 | |
parent | 78233e47d07d89d656ef75b534272f71ea540572 (diff) |
sw HTML import: allow custom XHTML namespace alias
This helps in case the HTML filter is given an XHTML that has an
explicit namespace alias for <http://www.w3.org/1999/xhtml>.
Change-Id: I437fa85ba19ce907c9c4b10c8d10aaf2217dc0ea
Reviewed-on: https://gerrit.libreoffice.org/50380
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | include/svtools/parhtml.hxx | 5 | ||||
-rw-r--r-- | svtools/source/svhtml/parhtml.cxx | 10 | ||||
-rw-r--r-- | sw/qa/extras/htmlimport/data/reqif-br.xhtml | 1 | ||||
-rw-r--r-- | sw/qa/extras/htmlimport/htmlimport.cxx | 18 | ||||
-rw-r--r-- | sw/qa/extras/inc/swmodeltestbase.hxx | 28 | ||||
-rw-r--r-- | sw/source/filter/html/swhtml.cxx | 21 | ||||
-rw-r--r-- | sw/source/filter/html/swhtml.hxx | 3 |
7 files changed, 86 insertions, 0 deletions
diff --git a/include/svtools/parhtml.hxx b/include/svtools/parhtml.hxx index 762c60e1006e..53c0727fcbf9 100644 --- a/include/svtools/parhtml.hxx +++ b/include/svtools/parhtml.hxx @@ -168,6 +168,9 @@ private: OUString aEndToken; + /// XML namespace, in case of XHTML. + OUString maNamespace; + protected: OUString sSaveToken; // the read tag as string @@ -182,6 +185,8 @@ protected: void FinishHeader() { bIsInHeader = false; } + void SetNamespace(const OUString& rNamespace); + public: HTMLParser( SvStream& rIn, bool bReadNewDoc = true ); diff --git a/svtools/source/svhtml/parhtml.cxx b/svtools/source/svhtml/parhtml.cxx index c32b067ea905..be3167d30053 100644 --- a/svtools/source/svhtml/parhtml.cxx +++ b/svtools/source/svhtml/parhtml.cxx @@ -237,6 +237,12 @@ HTMLParser::~HTMLParser() { } +void HTMLParser::SetNamespace(const OUString& rNamespace) +{ + // Convert namespace alias to a prefix. + maNamespace = rNamespace + ":"; +} + namespace { class RefGuard @@ -1071,6 +1077,10 @@ HtmlTokenId HTMLParser::GetNextToken_() // Search token in table: sSaveToken = aToken; aToken = aToken.toAsciiLowerCase(); + + if (!maNamespace.isEmpty() && aToken.startsWith(maNamespace)) + aToken = aToken.copy(maNamespace.getLength()); + if( HtmlTokenId::NONE == (nRet = GetHTMLToken( aToken )) ) // Unknown control nRet = HtmlTokenId::UNKNOWNCONTROL_ON; diff --git a/sw/qa/extras/htmlimport/data/reqif-br.xhtml b/sw/qa/extras/htmlimport/data/reqif-br.xhtml new file mode 100644 index 000000000000..aeb4ecae6bfb --- /dev/null +++ b/sw/qa/extras/htmlimport/data/reqif-br.xhtml @@ -0,0 +1 @@ +aaa<reqif-xhtml:br/>bbb diff --git a/sw/qa/extras/htmlimport/htmlimport.cxx b/sw/qa/extras/htmlimport/htmlimport.cxx index bfe1f436e03c..2e42b9f841e8 100644 --- a/sw/qa/extras/htmlimport/htmlimport.cxx +++ b/sw/qa/extras/htmlimport/htmlimport.cxx @@ -26,6 +26,18 @@ class HtmlImportTest : public SwModelTestBase { public: HtmlImportTest() : SwModelTestBase("sw/qa/extras/htmlimport/data/", "HTML (StarWriter)") {} + private: + std::unique_ptr<Resetter> preTest(const char* /*filename*/) override + { + if (getTestName().indexOf("ReqIf") != -1) + { + setImportFilterOptions("xhtmlns=reqif-xhtml"); + // Bypass type detection, this is an XHTML fragment only. + setImportFilterName("HTML (StarWriter)"); + } + + return nullptr; + } }; #define DECLARE_HTMLIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, nullptr, HtmlImportTest) @@ -279,6 +291,12 @@ DECLARE_HTMLIMPORT_TEST(testOutlineLevel, "outline-level.html") getProperty<sal_Int32>(getParagraph(1), "OutlineLevel")); } +DECLARE_HTMLIMPORT_TEST(testReqIfBr, "reqif-br.xhtml") +{ + // <reqif-xhtml:br/> was not recognized as a line break from a ReqIf file. + CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("aaa\nbbb")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index 6a0d6a1ff316..07f46710825c 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -136,6 +136,8 @@ class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTes { private: OUString maFilterOptions; + OUString maImportFilterOptions; + OUString maImportFilterName; protected: uno::Reference< lang::XComponent > mxComponent; @@ -184,6 +186,16 @@ public: maFilterOptions = rFilterOptions; } + void setImportFilterOptions(const OUString &rFilterOptions) + { + maImportFilterOptions = rFilterOptions; + } + + void setImportFilterName(const OUString &rFilterName) + { + maImportFilterName = rFilterName; + } + SwModelTestBase(const OUString& pTestDocumentPath = OUString(), const char* pFilter = "") : mpXmlBuffer(nullptr) , mpTestDocumentPath(pTestDocumentPath) @@ -662,6 +674,22 @@ protected: setTestInteractionHandler(pPassword, aFilterOptions); } + if (!maImportFilterOptions.isEmpty()) + { + beans::PropertyValue aValue; + aValue.Name = "FilterOptions"; + aValue.Value <<= maImportFilterOptions; + aFilterOptions.push_back(aValue); + } + + if (!maImportFilterName.isEmpty()) + { + beans::PropertyValue aValue; + aValue.Name = "FilterName"; + aValue.Value <<= maImportFilterName; + aFilterOptions.push_back(aValue); + } + // Output name early, so in the case of a hang, the name of the hanging input file is visible. if (pName) std::cout << pName << ":\n"; diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx index b529f6a97d18..c2009feeaf1b 100644 --- a/sw/source/filter/html/swhtml.cxx +++ b/sw/source/filter/html/swhtml.cxx @@ -417,6 +417,8 @@ SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCursor, SvStream& rIn, } } } + + SetupFilterOptions(); } SwHTMLParser::~SwHTMLParser() @@ -5540,6 +5542,25 @@ void SwHTMLParser::AddMetaUserDefined( OUString const & i_rMetaName ) } } +void SwHTMLParser::SetupFilterOptions() +{ + if (!GetMedium()) + return; + + const SfxItemSet* pItemSet = GetMedium()->GetItemSet(); + if (!pItemSet) + return; + + auto pItem = pItemSet->GetItem<SfxStringItem>(SID_FILE_FILTEROPTIONS); + if (!pItem) + return; + + OUString aFilterOptions = pItem->GetValue(); + const OUString aXhtmlNsKey("xhtmlns="); + if (aFilterOptions.startsWith(aXhtmlNsKey)) + SetNamespace(aFilterOptions.copy(aXhtmlNsKey.getLength())); +} + namespace { class FontCacheGuard diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx index 82fdb4994faf..d4b10d48fe8e 100644 --- a/sw/source/filter/html/swhtml.hxx +++ b/sw/source/filter/html/swhtml.hxx @@ -889,6 +889,9 @@ private: bool PendingObjectsInPaM(SwPaM& rPam) const; + /// Parse FilterOptions passed to the importer. + void SetupFilterOptions(); + class TableDepthGuard { private: |