diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2024-07-26 23:04:34 +0500 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2024-07-27 02:03:15 +0200 |
commit | 4be345abd678babcbb989db1e7a16021ad1da562 (patch) | |
tree | 3a8068019187343952b09fd3a5bb61f217ce5cb3 | |
parent | 0b683547bbb22cab46e92dfd65c129630bd9ca94 (diff) |
When the use cases require use of absolute URLs at export (Options->
Load/Save->General, Save URLs relative to file system and Save URLs
relative to internet), the fles generated from the document itself
(e.g., images that aren't embedded into HTML/ReqIF itself) may still
need to be referenced relatively.
This introduces the export filter option, named RelativeOwnObjectURL,
that overrides the general export settings specifically for these
self-generated objects.
Change-Id: I09aeb931db5712271a40c683370316783507775a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171083
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | sw/CppunitTest_sw_htmlexport.mk | 4 | ||||
-rw-r--r-- | sw/qa/extras/htmlexport/data/URLs.odt | bin | 0 -> 18377 bytes | |||
-rw-r--r-- | sw/qa/extras/htmlexport/data/external.png | bin | 0 -> 173 bytes | |||
-rw-r--r-- | sw/qa/extras/htmlexport/htmlexport.cxx | 221 | ||||
-rw-r--r-- | sw/source/filter/html/css1atr.cxx | 6 | ||||
-rw-r--r-- | sw/source/filter/html/htmlflywriter.cxx | 25 | ||||
-rw-r--r-- | sw/source/filter/html/htmlforw.cxx | 6 | ||||
-rw-r--r-- | sw/source/filter/html/htmlplug.cxx | 10 | ||||
-rw-r--r-- | sw/source/filter/html/wrthtml.cxx | 35 | ||||
-rw-r--r-- | sw/source/filter/html/wrthtml.hxx | 7 |
10 files changed, 286 insertions, 28 deletions
diff --git a/sw/CppunitTest_sw_htmlexport.mk b/sw/CppunitTest_sw_htmlexport.mk index e456673def7f..43a5ca56d041 100644 --- a/sw/CppunitTest_sw_htmlexport.mk +++ b/sw/CppunitTest_sw_htmlexport.mk @@ -61,6 +61,10 @@ $(eval $(call gb_CppunitTest_use_api,sw_htmlexport,\ $(eval $(call gb_CppunitTest_use_ure,sw_htmlexport)) $(eval $(call gb_CppunitTest_use_vcl,sw_htmlexport)) +$(eval $(call gb_CppunitTest_use_custom_headers,sw_htmlexport,\ + officecfg/registry \ +)) + $(eval $(call gb_CppunitTest_use_rdb,sw_htmlexport,services)) $(eval $(call gb_CppunitTest_use_configuration,sw_htmlexport)) diff --git a/sw/qa/extras/htmlexport/data/URLs.odt b/sw/qa/extras/htmlexport/data/URLs.odt Binary files differnew file mode 100644 index 000000000000..fd3593113f31 --- /dev/null +++ b/sw/qa/extras/htmlexport/data/URLs.odt diff --git a/sw/qa/extras/htmlexport/data/external.png b/sw/qa/extras/htmlexport/data/external.png Binary files differnew file mode 100644 index 000000000000..6ed2b8afc0af --- /dev/null +++ b/sw/qa/extras/htmlexport/data/external.png diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx index a7878823f63b..b0976c5a764f 100644 --- a/sw/qa/extras/htmlexport/htmlexport.cxx +++ b/sw/qa/extras/htmlexport/htmlexport.cxx @@ -27,11 +27,14 @@ #include <com/sun/star/packages/zip/ZipFileAccess.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> +#include <officecfg/Office/Common.hxx> + #include <test/htmltesttools.hxx> #include <tools/urlobj.hxx> #include <svtools/rtfkeywd.hxx> #include <comphelper/propertyvalue.hxx> #include <comphelper/propertysequence.hxx> +#include <comphelper/scopeguard.hxx> #include <svtools/parrtf.hxx> #include <rtl/strbuf.hxx> #include <svtools/rtftoken.h> @@ -3168,6 +3171,224 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testHTML_161979) CPPUNIT_ASSERT(numNonTransparent < size.Height() * size.Width()); } +CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqIF_exportAbsoluteURLs_ownRelative) +{ + auto pBatch(comphelper::ConfigurationChanges::create()); + Resetter resetter([ + bInternetPreviousValue = officecfg::Office::Common::Save::URL::Internet::get(), + bFileSystemPreviousValue = officecfg::Office::Common::Save::URL::FileSystem::get(), pBatch + ]() { + officecfg::Office::Common::Save::URL::Internet::set(bInternetPreviousValue, pBatch); + officecfg::Office::Common::Save::URL::FileSystem::set(bFileSystemPreviousValue, pBatch); + return pBatch->commit(); + }); + // Set saving absolute URLs + officecfg::Office::Common::Save::URL::Internet::set(false, pBatch); + officecfg::Office::Common::Save::URL::FileSystem::set(false, pBatch); + pBatch->commit(); + + createSwDoc("URLs.odt"); + // Export to ReqIF, using absolute URLs + saveWithParams({ + comphelper::makePropertyValue(u"FilterName"_ustr, u"HTML (StarWriter)"_ustr), + comphelper::makePropertyValue(u"FilterOptions"_ustr, u"xhtmlns=reqif-xhtml"_ustr), + comphelper::makePropertyValue(u"ExportImagesAsOLE"_ustr, true), + comphelper::makePropertyValue(u"RelativeOwnObjectURL"_ustr, true), + }); + xmlDocUniquePtr pXmlDoc = WrapReqifFromTempFile(); + + // HTTP URL: must be absolute + assertXPath(pXmlDoc, "//reqif-xhtml:p[1]/reqif-xhtml:a"_ostr, "href"_ostr, + u"http://www.example.org/"_ustr); + // file URL: must be absolute + assertXPath(pXmlDoc, "//reqif-xhtml:p[2]/reqif-xhtml:a"_ostr, "href"_ostr, + createFileURL(u"NonExistingPath/NonExistingFile.html")); + // form URL: must be absolute + assertXPath(pXmlDoc, "//reqif-xhtml:form"_ostr, "action"_ostr, + u"https://www.example.org/submit"_ustr); + // linked image exported as object: generated, must be relative + OUString url = getXPath(pXmlDoc, "//reqif-xhtml:p[3]/reqif-xhtml:object"_ostr, "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".ole")); + // its original image URL: must be absolute + assertXPath(pXmlDoc, "//reqif-xhtml:p[3]/reqif-xhtml:object/reqif-xhtml:object"_ostr, + "data"_ostr, createFileURL(u"external.png")); + // embedded image exported as object: generated, must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[4]/reqif-xhtml:object"_ostr, "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".ole")); + // its image URL: generated, must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[4]/reqif-xhtml:object/reqif-xhtml:object"_ostr, + "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".png")); + // unordered list with image bullet - it gets embedded as base64 data + OUString style = getXPath(pXmlDoc, "//reqif-xhtml:ul"_ostr, "style"_ostr); + CPPUNIT_ASSERT(style.indexOf("list-style-image: url(data:image/png;base64,") != -1); + // an as-char frame, exported as a whole to an object, must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[5]/reqif-xhtml:object"_ostr, "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".ole")); + // its file hyperlink must be absolute + assertXPath(pXmlDoc, "//reqif-xhtml:p[5]/reqif-xhtml:object/reqif-xhtml:a"_ostr, "href"_ostr, + createFileURL(u"foo/bar")); + // its image URL: generated, must be relative + url = getXPath(pXmlDoc, + "//reqif-xhtml:p[5]/reqif-xhtml:object/reqif-xhtml:a/reqif-xhtml:object"_ostr, + "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".png")); +} + +CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqIF_exportRelativeURLs) +{ + CPPUNIT_ASSERT(officecfg::Office::Common::Save::URL::Internet::get()); + CPPUNIT_ASSERT(officecfg::Office::Common::Save::URL::FileSystem::get()); + + createSwDoc("URLs.odt"); + // Export to ReqIF, using relative URLs (the default) + saveWithParams({ + comphelper::makePropertyValue(u"FilterName"_ustr, u"HTML (StarWriter)"_ustr), + comphelper::makePropertyValue(u"FilterOptions"_ustr, u"xhtmlns=reqif-xhtml"_ustr), + comphelper::makePropertyValue(u"ExportImagesAsOLE"_ustr, true), + }); + xmlDocUniquePtr pXmlDoc = WrapReqifFromTempFile(); + + // HTTP URL: must be absolute + assertXPath(pXmlDoc, "//reqif-xhtml:p[1]/reqif-xhtml:a"_ostr, "href"_ostr, + u"http://www.example.org/"_ustr); + // file URL: must be relative + OUString url = getXPath(pXmlDoc, "//reqif-xhtml:p[2]/reqif-xhtml:a"_ostr, "href"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith("NonExistingPath/NonExistingFile.html")); + // form URL: must be absolute + assertXPath(pXmlDoc, "//reqif-xhtml:form"_ostr, "action"_ostr, + u"https://www.example.org/submit"_ustr); + // linked image exported as object: generated, must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[3]/reqif-xhtml:object"_ostr, "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".ole")); + // its original image URL: must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[3]/reqif-xhtml:object/reqif-xhtml:object"_ostr, + "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith("external.png")); + // embedded image exported as object: generated, must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[4]/reqif-xhtml:object"_ostr, "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".ole")); + // its image URL: generated, must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[4]/reqif-xhtml:object/reqif-xhtml:object"_ostr, + "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".png")); + // unordered list with image bullet - it gets embedded as base64 data + OUString style = getXPath(pXmlDoc, "//reqif-xhtml:ul"_ostr, "style"_ostr); + CPPUNIT_ASSERT(style.indexOf("list-style-image: url(data:image/png;base64,") != -1); + // an as-char frame, exported as a whole to an object, must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[5]/reqif-xhtml:object"_ostr, "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".ole")); + // its file hyperlink must be relative + url = getXPath(pXmlDoc, "//reqif-xhtml:p[5]/reqif-xhtml:object/reqif-xhtml:a"_ostr, + "href"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith("foo/bar")); + // its image URL: generated, must be relative + url = getXPath(pXmlDoc, + "//reqif-xhtml:p[5]/reqif-xhtml:object/reqif-xhtml:a/reqif-xhtml:object"_ostr, + "data"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".png")); +} + +CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testHTML_exportAbsoluteURLs_ownRelative) +{ + auto pBatch(comphelper::ConfigurationChanges::create()); + Resetter resetter([ + bInternetPreviousValue = officecfg::Office::Common::Save::URL::Internet::get(), + bFileSystemPreviousValue = officecfg::Office::Common::Save::URL::FileSystem::get(), pBatch + ]() { + officecfg::Office::Common::Save::URL::Internet::set(bInternetPreviousValue, pBatch); + officecfg::Office::Common::Save::URL::FileSystem::set(bFileSystemPreviousValue, pBatch); + return pBatch->commit(); + }); + // Set saving absolute URLs + officecfg::Office::Common::Save::URL::Internet::set(false, pBatch); + officecfg::Office::Common::Save::URL::FileSystem::set(false, pBatch); + pBatch->commit(); + + createSwDoc("URLs.odt"); + // Export to HTML, using absolute URLs + saveWithParams({ + comphelper::makePropertyValue(u"FilterName"_ustr, u"HTML (StarWriter)"_ustr), + comphelper::makePropertyValue(u"RelativeOwnObjectURL"_ustr, true), + }); + htmlDocUniquePtr pHtmlDoc = parseHtml(maTempFile); + + // HTTP URL: must be absolute + assertXPath(pHtmlDoc, "//p[1]/a"_ostr, "href"_ostr, u"http://www.example.org/"_ustr); + // file URL: must be absolute + assertXPath(pHtmlDoc, "//p[2]/a"_ostr, "href"_ostr, + createFileURL(u"NonExistingPath/NonExistingFile.html")); + // form URL: must be absolute + assertXPath(pHtmlDoc, "//form"_ostr, "action"_ostr, u"https://www.example.org/submit"_ustr); + // linked image: must be absolute + assertXPath(pHtmlDoc, "//p[3]/img"_ostr, "src"_ostr, createFileURL(u"external.png")); + // embedded image: generated, must be relative + OUString url = getXPath(pHtmlDoc, "//p[4]/img"_ostr, "src"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".png")); + // unordered list with image bullet - it gets embedded as base64 data + OUString style = getXPath(pHtmlDoc, "//ul"_ostr, "style"_ostr); + CPPUNIT_ASSERT(style.indexOf("list-style-image: url(data:image/png;base64,") != -1); + // image-in-frame file hyperlink must be absolute; FIXME: HTMLOutFuncs::Out_ImageMap + // assertXPath(pHtmlDoc, "//p[5]/map/area"_ostr, "href"_ostr, createFileURL(u"foo/bar")); + // its image URL: generated, must be relative + url = getXPath(pHtmlDoc, "//p[5]/img"_ostr, "src"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".gif")); +} + +CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testHTML_exportRelativeURLs) +{ + CPPUNIT_ASSERT(officecfg::Office::Common::Save::URL::Internet::get()); + CPPUNIT_ASSERT(officecfg::Office::Common::Save::URL::FileSystem::get()); + + createSwDoc("URLs.odt"); + // Export to HTML, using relative URLs (the default) + ExportToHTML(); + htmlDocUniquePtr pHtmlDoc = parseHtml(maTempFile); + + // HTTP URL: must be absolute + assertXPath(pHtmlDoc, "//p[1]/a"_ostr, "href"_ostr, u"http://www.example.org/"_ustr); + // file URL: must be relative + OUString url = getXPath(pHtmlDoc, "//p[2]/a"_ostr, "href"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith("NonExistingPath/NonExistingFile.html")); + // form URL: must be absolute + assertXPath(pHtmlDoc, "//form"_ostr, "action"_ostr, u"https://www.example.org/submit"_ustr); + // linked image: must be relative + url = getXPath(pHtmlDoc, "//p[3]/img"_ostr, "src"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith("external.png")); + // embedded image: generated, must be relative + url = getXPath(pHtmlDoc, "//p[4]/img"_ostr, "src"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".png")); + // unordered list with image bullet - it gets embedded as base64 data + OUString style = getXPath(pHtmlDoc, "//ul"_ostr, "style"_ostr); + CPPUNIT_ASSERT(style.indexOf("list-style-image: url(data:image/png;base64,") != -1); + // image-in-frame file hyperlink must be relative + url = getXPath(pHtmlDoc, "//p[5]/map/area"_ostr, "href"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith("foo/bar")); + // its image URL: generated, must be relative + url = getXPath(pHtmlDoc, "//p[5]/img"_ostr, "src"_ostr); + CPPUNIT_ASSERT(!url.startsWith("file:")); + CPPUNIT_ASSERT(url.endsWith(".gif")); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx index cfd4e9e50fb9..20706f93d690 100644 --- a/sw/source/filter/html/css1atr.cxx +++ b/sw/source/filter/html/css1atr.cxx @@ -3050,6 +3050,7 @@ static SwHTMLWriter& OutCSS1_SvxBrush( SwHTMLWriter& rWrt, const SfxPoolItem& rH const Color & rColor = static_cast<const SvxBrushItem &>(rHt).GetColor(); OUString aLink = pGraphicName ? *pGraphicName : static_cast<const SvxBrushItem &>(rHt).GetGraphicLink(); + bool bOwn = false; SvxGraphicPosition ePos = static_cast<const SvxBrushItem &>(rHt).GetGraphicPos(); if( sw::Css1Background::Page == nMode && !rWrt.mbEmbedImages ) { @@ -3089,7 +3090,7 @@ static SwHTMLWriter& OutCSS1_SvxBrush( SwHTMLWriter& rWrt, const SfxPoolItem& rH else if( !pGraphicName && rWrt.m_bCfgCpyLinkedGrfs ) { OUString aGraphicAsLink = aLink; - rWrt.CopyLocalFileToINet( aGraphicAsLink ); + bOwn = rWrt.CopyLocalFileToINet( aGraphicAsLink ); aLink = aGraphicAsLink; } // In tables we only export something if there is a Graphic @@ -3188,8 +3189,7 @@ static SwHTMLWriter& OutCSS1_SvxBrush( SwHTMLWriter& rWrt, const SfxPoolItem& rH else { sOut += OStringToOUString(sCSS1_url, RTL_TEXTENCODING_ASCII_US)+ - "(" + URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), - aLink) + ")"; + "(" + rWrt.normalizeURL(aLink, bOwn) + ")"; } if( !pRepeat.empty() ) diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx index ddab7d00cf2f..a98aab4d429f 100644 --- a/sw/source/filter/html/htmlflywriter.cxx +++ b/sw/source/filter/html/htmlflywriter.cxx @@ -1234,7 +1234,8 @@ SwHTMLWriter& OutHTML_ImageStart( HtmlWriter& rHtml, SwHTMLWriter& rWrt, const S const Size &rRealSize, HtmlFrmOpts nFrameOpts, const char *pMarkType, const ImageMap *pAltImgMap, - const OUString& rMimeType ) + const OUString& rMimeType, + bool bOwn) { // <object data="..."> instead of <img src="..."> bool bReplacement = (nFrameOpts & HtmlFrmOpts::Replacement) || rWrt.mbReqIF; @@ -1250,8 +1251,8 @@ SwHTMLWriter& OutHTML_ImageStart( HtmlWriter& rHtml, SwHTMLWriter& rWrt, const S } OUString aGraphicURL( rGraphicURL ); - if( !rWrt.mbEmbedImages && !HTMLOutFuncs::PrivateURLToInternalImg(aGraphicURL) && !rWrt.mpTempBaseURL ) - aGraphicURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), aGraphicURL); + if (!rWrt.mbEmbedImages) + aGraphicURL = rWrt.normalizeURL(aGraphicURL, bOwn); const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet(); @@ -1496,6 +1497,7 @@ SwHTMLWriter& OutHTML_BulletImage( SwHTMLWriter& rWrt, { OUString aGraphicInBase64; OUString aLink; + bool bOwn = false; if( pBrush ) { aLink = pBrush->GetGraphicLink(); @@ -1510,11 +1512,11 @@ SwHTMLWriter& OutHTML_BulletImage( SwHTMLWriter& rWrt, } } } - else if(!aLink.isEmpty()) + else { if( rWrt.m_bCfgCpyLinkedGrfs ) { - rWrt.CopyLocalFileToINet( aLink ); + bOwn = rWrt.CopyLocalFileToINet(aLink); } } @@ -1525,8 +1527,7 @@ SwHTMLWriter& OutHTML_BulletImage( SwHTMLWriter& rWrt, } if(!aLink.isEmpty()) { - if( !HTMLOutFuncs::PrivateURLToInternalImg(aLink) ) - aLink = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), aLink); + aLink = rWrt.normalizeURL(aLink, bOwn); } OStringBuffer sOut; @@ -1787,7 +1788,7 @@ static void OutHTML_ImageOLEStart(SwHTMLWriter& rWrt, const Graphic& rGraphic, SAL_WARN("sw.html", "SwReqIfReader::WrapGraphicInRtf() failed"); // Refer to this data. - aFileName = URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aFileName); + aFileName = rWrt.normalizeURL(aFileName, true); rWrt.Strm().WriteOString( Concat2View("<" + rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object)); rWrt.Strm().WriteOString(Concat2View(" data=\"" + aFileName.toUtf8() + "\"")); @@ -1884,7 +1885,7 @@ static SwHTMLWriter & OutHTML_FrameFormatAsImage( SwHTMLWriter& rWrt, const SwFr HtmlWriter aHtml(rWrt.Strm(), rWrt.maNamespace); OutHTML_ImageStart( aHtml, rWrt, rFrameFormat, GraphicURL, aGraphic, rFrameFormat.GetName(), aSz, HtmlFrmOpts::GenImgMask, "frame", - aIMap.GetIMapObjectCount() ? &aIMap : nullptr, aMimeType ); + aIMap.GetIMapObjectCount() ? &aIMap : nullptr, aMimeType, true); GfxLink aLink = aGraphic.GetGfxLink(); if (bWritePNGFallback && aLink.GetType() != GfxLinkType::NativePng) @@ -1928,6 +1929,7 @@ static SwHTMLWriter& OutHTML_FrameFormatGrfNode( SwHTMLWriter& rWrt, const SwFra OUString aGraphicURL; OUString aMimeType; + bool bOwn = false; if(!rWrt.mbEmbedImages) { const SwMirrorGrf& rMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf(); @@ -2012,12 +2014,13 @@ static SwHTMLWriter& OutHTML_FrameFormatGrfNode( SwHTMLWriter& rWrt, const SwFra aGraphicURL = URIHelper::SmartRel2Abs( INetURLObject(rWrt.GetBaseURL()), aGraphicURL, URIHelper::GetMaybeFileHdl() ); + bOwn = true; } else { pGrfNd->GetFileFilterNms( &aGraphicURL, nullptr ); if( rWrt.m_bCfgCpyLinkedGrfs ) - rWrt.CopyLocalFileToINet( aGraphicURL ); + bOwn = rWrt.CopyLocalFileToINet(aGraphicURL); } } @@ -2029,7 +2032,7 @@ static SwHTMLWriter& OutHTML_FrameFormatGrfNode( SwHTMLWriter& rWrt, const SwFra HtmlWriter aHtml(rWrt.Strm(), rWrt.maNamespace); OutHTML_ImageStart( aHtml, rWrt, rFrameFormat, aGraphicURL, aGraphic, pGrfNd->GetTitle(), - pGrfNd->GetTwipSize(), nFrameFlags, "graphic", nullptr, aMimeType ); + pGrfNd->GetTwipSize(), nFrameFlags, "graphic", nullptr, aMimeType, bOwn ); GfxLink aLink = aGraphic.GetGfxLink(); if (bWritePNGFallback && aLink.GetType() != GfxLinkType::NativePng) diff --git a/sw/source/filter/html/htmlforw.cxx b/sw/source/filter/html/htmlforw.cxx index c020d1632612..2d7aa7200b0f 100644 --- a/sw/source/filter/html/htmlforw.cxx +++ b/sw/source/filter/html/htmlforw.cxx @@ -467,8 +467,7 @@ void SwHTMLWriter::OutForm( bool bOn, { sOut += " " OOO_STRING_SVTOOLS_HTML_O_action "=\""; Strm().WriteOString( sOut ); - OUString aURL - = URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), *s); + OUString aURL = normalizeURL(*s, false); HTMLOutFuncs::Out_String( Strm(), aURL ); sOut = "\""_ostr; } @@ -967,8 +966,7 @@ SwHTMLWriter& OutHTML_DrawFrameFormatAsControl( SwHTMLWriter& rWrt, sOut += " " OOO_STRING_SVTOOLS_HTML_O_src "=\""; rWrt.Strm().WriteOString( sOut ); - HTMLOutFuncs::Out_String( rWrt.Strm(), - URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), *s) ); + HTMLOutFuncs::Out_String(rWrt.Strm(), rWrt.normalizeURL(*s, false)); sOut = "\""_ostr; } } diff --git a/sw/source/filter/html/htmlplug.cxx b/sw/source/filter/html/htmlplug.cxx index 720a9a929647..3e594bbf8b43 100644 --- a/sw/source/filter/html/htmlplug.cxx +++ b/sw/source/filter/html/htmlplug.cxx @@ -1259,8 +1259,7 @@ SwHTMLWriter& OutHTML_FrameFormatOLENode( SwHTMLWriter& rWrt, const SwFrameForma aAny = xSet->getPropertyValue(u"PluginURL"_ustr); if( (aAny >>= aStr) && !aStr.isEmpty() ) { - aURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), - aStr); + aURL = rWrt.normalizeURL(aStr, false); } if( !aURL.isEmpty() ) @@ -1308,7 +1307,7 @@ SwHTMLWriter& OutHTML_FrameFormatOLENode( SwHTMLWriter& rWrt, const SwFrameForma aAny = xSet->getPropertyValue(u"AppletCodeBase"_ustr); if( (aAny >>= aCd) && !aCd.isEmpty() ) { - OUString sCodeBase( URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aCd) ); + OUString sCodeBase(rWrt.normalizeURL(aCd, false)); if( !sCodeBase.isEmpty() ) { sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_codebase "=\""); @@ -1524,13 +1523,14 @@ static void OutHTMLGraphic(SwHTMLWriter& rWrt, const SwFrameFormat& rFrameFormat nFlags |= HtmlFrmOpts::Replacement; HtmlWriter aHtml(rWrt.Strm(), rWrt.maNamespace); OutHTML_ImageStart(aHtml, rWrt, rFrameFormat, aGraphicURL, rGraphic, pOLENd->GetTitle(), - pOLENd->GetTwipSize(), nFlags, "ole", nullptr, aMimeType); + pOLENd->GetTwipSize(), nFlags, "ole", nullptr, aMimeType, true); OutHTML_ImageEnd(aHtml, rWrt); } static void OutHTMLStartObject(SwHTMLWriter& rWrt, const OUString& rFileName, const OUString& rFileType) { - OUString aFileName = URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), rFileName); + // OutHTMLStartObject is only for own objects + OUString aFileName = rWrt.normalizeURL(rFileName, true); if (rWrt.IsLFPossible()) rWrt.OutNewLine(); diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx index 58360ff40527..f77b5154cdee 100644 --- a/sw/source/filter/html/wrthtml.cxx +++ b/sw/source/filter/html/wrthtml.cxx @@ -362,6 +362,17 @@ void SwHTMLWriter::SetupFilterFromPropertyValues( it->second >>= bVal; m_bPreserveSpacesOnWrite = bVal; } + + it = aStoreMap.find(u"RelativeOwnObjectURL"_ustr); + if (it != aStoreMap.end()) + { + // URLs for images / objects created by export (from the document information) will be + // relative, regardless of org.openoffice.Office.Common/Save/URL/Internet and + // org.openoffice.Office.Common/Save/URL/FileSystem settings + bool bVal = false; + it->second >>= bVal; + m_bRelativeURLsForOwnObjects = bVal; + } } ErrCode SwHTMLWriter::WriteStream() @@ -770,7 +781,7 @@ static void lcl_html_OutSectionStartTag( SwHTMLWriter& rHTMLWrt, OUString aFilter( aFName.getToken(0, sfx2::cTokenSeparator, nIdx) ); OUString aSection( aFName.getToken(0, sfx2::cTokenSeparator, nIdx) ); - OUString aEncURL( URIHelper::simpleNormalizedMakeRelative(rHTMLWrt.GetBaseURL(), aURL ) ); + OUString aEncURL(rHTMLWrt.normalizeURL(aURL, false)); sal_Unicode cDelim = 255U; bool bURLContainsDelim = (-1 != aEncURL.indexOf( cDelim ) ); @@ -1384,7 +1395,7 @@ OUString SwHTMLWriter::convertHyperlinkHRefValue(const OUString& rURL) if (!aURL.HasError()) sURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE); } - return URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), sURL ); + return normalizeURL(sURL, false); } void SwHTMLWriter::OutHyperlinkHRefValue( const OUString& rURL ) @@ -1425,11 +1436,12 @@ void SwHTMLWriter::OutBackground( const SvxBrushItem *pBrushItem, bool bGraphic } else { + bool bOwn = false; if( m_bCfgCpyLinkedGrfs ) { - CopyLocalFileToINet( GraphicURL ); + bOwn = CopyLocalFileToINet(GraphicURL); } - OUString s( URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), GraphicURL)); + OUString s(normalizeURL(GraphicURL, bOwn)); Strm().WriteOString(" " OOO_STRING_SVTOOLS_HTML_O_background "=\"" ); HTMLOutFuncs::Out_String( Strm(), s ); Strm().WriteOString("\""); @@ -1608,6 +1620,21 @@ OString SwHTMLWriter::GetNamespace() const return maNamespace + ":"; } +OUString SwHTMLWriter::normalizeURL(const OUString& url, bool own) const +{ + OUString ret(url); + if (HTMLOutFuncs::PrivateURLToInternalImg(ret)) + return ret; + OUString base; + if (!mpTempBaseURL) + base = GetBaseURL(); + else if (own && m_bRelativeURLsForOwnObjects && GetOrigFileName()) + base = *GetOrigFileName(); + if (!base.isEmpty()) + ret = URIHelper::simpleNormalizedMakeRelative(base, ret); + return ret; +} + // Structure caches the current data of the writer to output a // other part of the document, like e.g. header/footer HTMLSaveData::HTMLSaveData(SwHTMLWriter& rWriter, SwNodeOffset nStt, diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx index aac06fbf8868..0b518a29c448 100644 --- a/sw/source/filter/html/wrthtml.hxx +++ b/sw/source/filter/html/wrthtml.hxx @@ -282,6 +282,8 @@ class SwHTMLWriter : public Writer bool m_bLFPossible = false; // a line break can be inserted bool m_bSpacePreserve = false; // Using xml::space="preserve", or "white-space: pre-wrap" style bool m_bPreserveSpacesOnWrite = false; // If export should use m_bSpacePreserve + // If "Save URLs relative to *" is ignored for self-generated images / objects + bool m_bRelativeURLsForOwnObjects = false; sal_uInt16 OutHeaderAttrs(); const SwPageDesc *MakeHeader( sal_uInt16& rHeaderAtrs ); @@ -629,6 +631,8 @@ public: bool IsSpacePreserve() const { return m_bSpacePreserve; } void SetSpacePreserve(bool val) { m_bSpacePreserve = val; } bool IsPreserveSpacesOnWritePrefSet() const { return m_bPreserveSpacesOnWrite; } + + OUString normalizeURL(const OUString& url, bool own) const; }; inline bool SwHTMLWriter::IsCSS1Source( sal_uInt16 n ) const @@ -706,7 +710,8 @@ SwHTMLWriter& OutHTML_ImageStart( HtmlWriter& rHtml, SwHTMLWriter&, const SwFram const Size& rRealSize, HtmlFrmOpts nFrameOpts, const char *pMarkType, const ImageMap *pGenImgMap, - const OUString& rMimeType = {} ); + const OUString& rMimeType, + bool bOwn = false ); SwHTMLWriter& OutHTML_ImageEnd( HtmlWriter& rHtml, SwHTMLWriter& ); SwHTMLWriter& OutHTML_BulletImage( SwHTMLWriter& rWrt, const char *pTag, |