summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2024-07-26 23:04:34 +0500
committerMike Kaganski <mike.kaganski@collabora.com>2024-07-27 02:03:15 +0200
commit4be345abd678babcbb989db1e7a16021ad1da562 (patch)
tree3a8068019187343952b09fd3a5bb61f217ce5cb3
parent0b683547bbb22cab46e92dfd65c129630bd9ca94 (diff)
HTML/ReqIF export: introduce RelativeOwnObjectURL filter optionHEADmaster
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.mk4
-rw-r--r--sw/qa/extras/htmlexport/data/URLs.odtbin0 -> 18377 bytes
-rw-r--r--sw/qa/extras/htmlexport/data/external.pngbin0 -> 173 bytes
-rw-r--r--sw/qa/extras/htmlexport/htmlexport.cxx221
-rw-r--r--sw/source/filter/html/css1atr.cxx6
-rw-r--r--sw/source/filter/html/htmlflywriter.cxx25
-rw-r--r--sw/source/filter/html/htmlforw.cxx6
-rw-r--r--sw/source/filter/html/htmlplug.cxx10
-rw-r--r--sw/source/filter/html/wrthtml.cxx35
-rw-r--r--sw/source/filter/html/wrthtml.hxx7
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
new file mode 100644
index 000000000000..fd3593113f31
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/URLs.odt
Binary files differ
diff --git a/sw/qa/extras/htmlexport/data/external.png b/sw/qa/extras/htmlexport/data/external.png
new file mode 100644
index 000000000000..6ed2b8afc0af
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/external.png
Binary files differ
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,