Kaydet (Commit) 61e4c00e authored tarafından Miklos Vajna's avatar Miklos Vajna

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/50380Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst 78233e47
...@@ -168,6 +168,9 @@ private: ...@@ -168,6 +168,9 @@ private:
OUString aEndToken; OUString aEndToken;
/// XML namespace, in case of XHTML.
OUString maNamespace;
protected: protected:
OUString sSaveToken; // the read tag as string OUString sSaveToken; // the read tag as string
...@@ -182,6 +185,8 @@ protected: ...@@ -182,6 +185,8 @@ protected:
void FinishHeader() { bIsInHeader = false; } void FinishHeader() { bIsInHeader = false; }
void SetNamespace(const OUString& rNamespace);
public: public:
HTMLParser( SvStream& rIn, bool bReadNewDoc = true ); HTMLParser( SvStream& rIn, bool bReadNewDoc = true );
......
...@@ -237,6 +237,12 @@ HTMLParser::~HTMLParser() ...@@ -237,6 +237,12 @@ HTMLParser::~HTMLParser()
{ {
} }
void HTMLParser::SetNamespace(const OUString& rNamespace)
{
// Convert namespace alias to a prefix.
maNamespace = rNamespace + ":";
}
namespace namespace
{ {
class RefGuard class RefGuard
...@@ -1071,6 +1077,10 @@ HtmlTokenId HTMLParser::GetNextToken_() ...@@ -1071,6 +1077,10 @@ HtmlTokenId HTMLParser::GetNextToken_()
// Search token in table: // Search token in table:
sSaveToken = aToken; sSaveToken = aToken;
aToken = aToken.toAsciiLowerCase(); aToken = aToken.toAsciiLowerCase();
if (!maNamespace.isEmpty() && aToken.startsWith(maNamespace))
aToken = aToken.copy(maNamespace.getLength());
if( HtmlTokenId::NONE == (nRet = GetHTMLToken( aToken )) ) if( HtmlTokenId::NONE == (nRet = GetHTMLToken( aToken )) )
// Unknown control // Unknown control
nRet = HtmlTokenId::UNKNOWNCONTROL_ON; nRet = HtmlTokenId::UNKNOWNCONTROL_ON;
......
...@@ -26,6 +26,18 @@ class HtmlImportTest : public SwModelTestBase ...@@ -26,6 +26,18 @@ class HtmlImportTest : public SwModelTestBase
{ {
public: public:
HtmlImportTest() : SwModelTestBase("sw/qa/extras/htmlimport/data/", "HTML (StarWriter)") {} 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) #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") ...@@ -279,6 +291,12 @@ DECLARE_HTMLIMPORT_TEST(testOutlineLevel, "outline-level.html")
getProperty<sal_Int32>(getParagraph(1), "OutlineLevel")); 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(); CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -136,6 +136,8 @@ class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTes ...@@ -136,6 +136,8 @@ class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTes
{ {
private: private:
OUString maFilterOptions; OUString maFilterOptions;
OUString maImportFilterOptions;
OUString maImportFilterName;
protected: protected:
uno::Reference< lang::XComponent > mxComponent; uno::Reference< lang::XComponent > mxComponent;
...@@ -184,6 +186,16 @@ public: ...@@ -184,6 +186,16 @@ public:
maFilterOptions = rFilterOptions; maFilterOptions = rFilterOptions;
} }
void setImportFilterOptions(const OUString &rFilterOptions)
{
maImportFilterOptions = rFilterOptions;
}
void setImportFilterName(const OUString &rFilterName)
{
maImportFilterName = rFilterName;
}
SwModelTestBase(const OUString& pTestDocumentPath = OUString(), const char* pFilter = "") SwModelTestBase(const OUString& pTestDocumentPath = OUString(), const char* pFilter = "")
: mpXmlBuffer(nullptr) : mpXmlBuffer(nullptr)
, mpTestDocumentPath(pTestDocumentPath) , mpTestDocumentPath(pTestDocumentPath)
...@@ -662,6 +674,22 @@ protected: ...@@ -662,6 +674,22 @@ protected:
setTestInteractionHandler(pPassword, aFilterOptions); 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. // Output name early, so in the case of a hang, the name of the hanging input file is visible.
if (pName) if (pName)
std::cout << pName << ":\n"; std::cout << pName << ":\n";
......
...@@ -417,6 +417,8 @@ SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCursor, SvStream& rIn, ...@@ -417,6 +417,8 @@ SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCursor, SvStream& rIn,
} }
} }
} }
SetupFilterOptions();
} }
SwHTMLParser::~SwHTMLParser() SwHTMLParser::~SwHTMLParser()
...@@ -5540,6 +5542,25 @@ void SwHTMLParser::AddMetaUserDefined( OUString const & i_rMetaName ) ...@@ -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 namespace
{ {
class FontCacheGuard class FontCacheGuard
......
...@@ -889,6 +889,9 @@ private: ...@@ -889,6 +889,9 @@ private:
bool PendingObjectsInPaM(SwPaM& rPam) const; bool PendingObjectsInPaM(SwPaM& rPam) const;
/// Parse FilterOptions passed to the importer.
void SetupFilterOptions();
class TableDepthGuard class TableDepthGuard
{ {
private: private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment