From 867a30cdaa0e3004a7186782dc701874e1f68a94 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Braun" Date: Wed, 26 Feb 2020 19:39:02 -0800 Subject: [PATCH 1/8] support href (not just xlink:href) in tags in svg open (#620) --- src/attributes.cpp | 1 + src/attributes.h | 1 + src/object/sp-use.cpp | 3 ++- src/ui/dialog/symbols.cpp | 7 ++++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/attributes.cpp b/src/attributes.cpp index 2588cf8c90..b0f7e91edf 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -54,6 +54,7 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, "inkscape:highlight-color"}, {SP_ATTR_INKSCAPE_SPRAY_ORIGIN, "inkscape:spray-origin"}, /* SPAnchor */ + {SP_ATTR_HREF, "href"}, {SP_ATTR_XLINK_HREF, "xlink:href"}, {SP_ATTR_XLINK_TYPE, "xlink:type"}, {SP_ATTR_XLINK_ROLE, "xlink:role"}, diff --git a/src/attributes.h b/src/attributes.h index 198d76187e..a6115847c8 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -52,6 +52,7 @@ enum SPAttributeEnum : unsigned { SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, SP_ATTR_INKSCAPE_SPRAY_ORIGIN, /* SPAnchor */ + SP_ATTR_HREF, SP_ATTR_XLINK_HREF, SP_ATTR_XLINK_TYPE, SP_ATTR_XLINK_ROLE, diff --git a/src/object/sp-use.cpp b/src/object/sp-use.cpp index f1cf6d0470..f28d40bc85 100644 --- a/src/object/sp-use.cpp +++ b/src/object/sp-use.cpp @@ -83,6 +83,7 @@ void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "width" ); this->readAttr( "height" ); this->readAttr( "xlink:href" ); + this->readAttr( "href" ); // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, @@ -129,7 +130,7 @@ void SPUse::set(SPAttributeEnum key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_XLINK_HREF: { + case SP_ATTR_XLINK_HREF: case SP_ATTR_HREF: { if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { /* No change, do nothing. */ } else { diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 9dc867bb4c..213127d23d 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -992,7 +992,12 @@ gchar const* SymbolsDialog::styleFromUse( gchar const* id, SPDocument* document) std::vector l = useInDoc( document ); for( auto use:l ) { if ( use ) { - gchar const *href = use->getRepr()->attribute("xlink:href"); + // Support SVG2 style href + const gchar *href = use->getRepr()->attribute("href"); + if (! href ) { + //Deprecated xlink:href reference: + href = use->getRepr()->attribute("xlink:href"); + } if( href ) { Glib::ustring href2(href); Glib::ustring id2(id); -- GitLab From 63e69f12267a94ec112e437bf1acfbf3d56de407 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 23 Apr 2020 16:32:01 -0400 Subject: [PATCH 2/8] Add reading for href in place of xlink:href --- src/extension/internal/bitmap/imagemagick.cpp | 5 ++++- src/extension/internal/odf.cpp | 10 ++++++++-- src/file.cpp | 7 ++++++- src/id-clash.cpp | 5 +++-- src/io/resource-manager.cpp | 10 ++++++++-- src/object/color-profile.cpp | 2 ++ src/object/filters/image.cpp | 2 ++ src/object/sp-anchor.cpp | 4 +++- src/object/sp-filter.cpp | 2 ++ src/object/sp-gradient.cpp | 2 ++ src/object/sp-hatch.cpp | 2 ++ src/object/sp-image.cpp | 16 +++++++++++---- src/object/sp-offset.cpp | 5 ++++- src/object/sp-pattern.cpp | 2 ++ src/object/sp-script.cpp | 2 ++ src/object/sp-tag-use.cpp | 2 ++ src/object/sp-tref.cpp | 3 ++- src/object/sp-tspan.cpp | 2 ++ src/object/sp-use.cpp | 5 +++-- src/ui/contextmenu.cpp | 20 ++++++++++++------- src/ui/dialog/clonetiler.cpp | 12 +++++++---- src/ui/dialog/object-attributes.cpp | 9 +++++++-- src/ui/dialog/symbols.cpp | 9 ++++----- src/xml/rebase-hrefs.cpp | 10 +++++++--- 24 files changed, 110 insertions(+), 38 deletions(-) diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index 915d3b08f2..a287dd8397 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -80,7 +80,10 @@ ImageMagickDocCache::ImageMagickDocCache(Inkscape::UI::View::View * view) : if (!strcmp(node->name(), "image") || !strcmp(node->name(), "svg:image")) { _nodes[_imageCount] = node; - char const *xlink = node->attribute("xlink:href"); + char const *xlink = node->attribute("href"); + if(!xlink) { + xlink = node->attribute("xlink:href"); + } char const *id = node->attribute("id"); _originals[_imageCount] = xlink; _caches[_imageCount] = (char*)""; diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index bd520455d7..b8bc6791b0 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -1021,7 +1021,10 @@ void OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node) } if (nodeName == "image" || nodeName == "svg:image") { - Glib::ustring href = getAttribute(node, "xlink:href"); + Glib::ustring href = getAttribute(node, "href"); + if (href.size() == 0) { + href = getAttribute(node, "xlink:href"); + } if (href.size() > 0 && imageTable.count(href) == 0) { try { auto uri = Inkscape::URI(href.c_str(), docBaseUri.c_str()); @@ -1677,7 +1680,10 @@ bool OdfOutput::writeTree(Writer &couts, Writer &souts, Glib::ustring itemTransformString = formatTransform(itemTransform); - Glib::ustring href = getAttribute(node, "xlink:href"); + Glib::ustring href = getAttribute(node, "href"); + if (href.size() == 0) { + href = getAttribute(node, "xlink:href"); + } std::map::iterator iter = imageTable.find(href); if (iter == imageTable.end()) { diff --git a/src/file.cpp b/src/file.cpp index 07f2db33f8..714ca18f78 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -966,7 +966,12 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) // if we are pasting a clone to an already existing object, its // transform is wrong (see ui/clipboard.cpp) - if(obj_copy->attribute("transform-with-parent") && target_document->getObjectById(obj->attribute("xlink:href")+1) ){ + gchar const *href = obj->attribute("href"); + if(!href) { + href = obj->attribute("xlink:href"); + } + + if(obj_copy->attribute("transform-with-parent") && target_document->getObjectById(href+1) ){ obj_copy->setAttribute("transform",obj_copy->attribute("transform-with-parent")); } if(obj_copy->attribute("transform-with-parent")) diff --git a/src/id-clash.cpp b/src/id-clash.cpp index a7ab3263ef..c62d3a9bc5 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -43,13 +43,14 @@ typedef std::pair id_changeitem_type; typedef std::list id_changelist_type; const char *href_like_attributes[] = { + "href", + "xlink:href", + "inkscape:href", "inkscape:connection-end", "inkscape:connection-start", - "inkscape:href", "inkscape:path-effect", "inkscape:perspectiveID", "inkscape:tiled-clone-of", - "xlink:href", }; #define NUM_HREF_LIKE_ATTRIBUTES (sizeof(href_like_attributes) / sizeof(*href_like_attributes)) diff --git a/src/io/resource-manager.cpp b/src/io/resource-manager.cpp index e0a3ac95eb..9a07e58b2a 100644 --- a/src/io/resource-manager.cpp +++ b/src/io/resource-manager.cpp @@ -221,7 +221,10 @@ std::vector ResourceManagerImpl::findBrokenLinks( SPDocument *doc for (auto image : images) { Inkscape::XML::Node *ir = image->getRepr(); - gchar const *href = ir->attribute("xlink:href"); + gchar const *href = ir->attribute("href"); + if(!href) { + href = ir->attribute("xlink:href"); + } if ( href && ( uniques.find(href) == uniques.end() ) ) { std::string filename; if (extractFilepath(href, filename)) { @@ -356,7 +359,10 @@ bool ResourceManagerImpl::fixupBrokenLinks(SPDocument *doc) for (auto image : images) { Inkscape::XML::Node *ir = image->getRepr(); - gchar const *href = ir->attribute("xlink:href"); + gchar const *href = ir->attribute("href"); + if(!href) { + href = ir->attribute("xlink:href"); + } if ( href ) { // TODO debug g_message(" consider [%s]", href); diff --git a/src/object/color-profile.cpp b/src/object/color-profile.cpp index a4776861c3..907de90fe0 100644 --- a/src/object/color-profile.cpp +++ b/src/object/color-profile.cpp @@ -303,6 +303,7 @@ void ColorProfile::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); + this->readAttr( "href" ); this->readAttr( "xlink:href" ); this->readAttr( "id" ); this->readAttr( "local" ); @@ -321,6 +322,7 @@ void ColorProfile::build(SPDocument *document, Inkscape::XML::Node *repr) { */ void ColorProfile::set(SPAttributeEnum key, gchar const *value) { switch (key) { + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: if ( this->href ) { g_free( this->href ); diff --git a/src/object/filters/image.cpp b/src/object/filters/image.cpp index ea88d81c8d..b34ba3758c 100644 --- a/src/object/filters/image.cpp +++ b/src/object/filters/image.cpp @@ -58,6 +58,7 @@ void SPFeImage::build(SPDocument *document, Inkscape::XML::Node *repr) /*LOAD ATTRIBUTES FROM REPR HERE*/ this->readAttr( "preserveAspectRatio" ); + this->readAttr( "href" ); this->readAttr( "xlink:href" ); } @@ -100,6 +101,7 @@ static void sp_feImage_href_modified(SPObject* /*old_elem*/, SPObject* new_elem, void SPFeImage::set(SPAttributeEnum key, gchar const *value) { switch(key) { /*DEAL WITH SETTING ATTRIBUTES HERE*/ + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: if (this->href) { g_free(this->href); diff --git a/src/object/sp-anchor.cpp b/src/object/sp-anchor.cpp index 544e2d3e95..53994c6d30 100644 --- a/src/object/sp-anchor.cpp +++ b/src/object/sp-anchor.cpp @@ -35,13 +35,14 @@ SPAnchor::~SPAnchor() = default; void SPAnchor::build(SPDocument *document, Inkscape::XML::Node *repr) { SPGroup::build(document, repr); + this->readAttr( "href" ); + this->readAttr( "xlink:href" ); this->readAttr( "xlink:type" ); this->readAttr( "xlink:role" ); this->readAttr( "xlink:arcrole" ); this->readAttr( "xlink:title" ); this->readAttr( "xlink:show" ); this->readAttr( "xlink:actuate" ); - this->readAttr( "xlink:href" ); this->readAttr( "target" ); } @@ -68,6 +69,7 @@ void SPAnchor::release() { void SPAnchor::set(SPAttributeEnum key, const gchar* value) { switch (key) { + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: g_free(this->href); this->href = g_strdup(value); diff --git a/src/object/sp-filter.cpp b/src/object/sp-filter.cpp index 4c434b9daf..7555f565a7 100644 --- a/src/object/sp-filter.cpp +++ b/src/object/sp-filter.cpp @@ -71,6 +71,7 @@ void SPFilter::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "width" ); this->readAttr( "height" ); this->readAttr( "filterRes" ); + this->readAttr( "href" ); this->readAttr( "xlink:href" ); this->_refcount = 0; @@ -165,6 +166,7 @@ void SPFilter::set(SPAttributeEnum key, gchar const *value) { this->filterRes.set(value); this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: if (value) { try { diff --git a/src/object/sp-gradient.cpp b/src/object/sp-gradient.cpp index 031aa22569..f61e06ebd6 100644 --- a/src/object/sp-gradient.cpp +++ b/src/object/sp-gradient.cpp @@ -293,6 +293,7 @@ void SPGradient::build(SPDocument *document, Inkscape::XML::Node *repr) this->readAttr( "gradientUnits" ); this->readAttr( "gradientTransform" ); this->readAttr( "spreadMethod" ); + this->readAttr( "href" ); this->readAttr( "xlink:href" ); this->readAttr( "osb:paint" ); @@ -387,6 +388,7 @@ void SPGradient::set(SPAttributeEnum key, gchar const *value) this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: if (value) { try { diff --git a/src/object/sp-hatch.cpp b/src/object/sp-hatch.cpp index ef9bae6ca0..9e44300592 100644 --- a/src/object/sp-hatch.cpp +++ b/src/object/sp-hatch.cpp @@ -77,6 +77,7 @@ void SPHatch::build(SPDocument* doc, Inkscape::XML::Node* repr) readAttr("y"); readAttr("pitch"); readAttr("rotate"); + readAttr("href"); readAttr("xlink:href"); readAttr( "style" ); @@ -199,6 +200,7 @@ void SPHatch::set(SPAttributeEnum key, const gchar* value) requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: if (value && href == value) { // Href unchanged, do nothing. diff --git a/src/object/sp-image.cpp b/src/object/sp-image.cpp index cec0c1299e..419fd29d76 100644 --- a/src/object/sp-image.cpp +++ b/src/object/sp-image.cpp @@ -131,6 +131,7 @@ SPImage::~SPImage() = default; void SPImage::build(SPDocument *document, Inkscape::XML::Node *repr) { SPItem::build(document, repr); + this->readAttr( "href" ); this->readAttr( "xlink:href" ); this->readAttr( "x" ); this->readAttr( "y" ); @@ -174,6 +175,7 @@ void SPImage::release() { void SPImage::set(SPAttributeEnum key, const gchar* value) { switch (key) { + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: g_free (this->href); this->href = (value) ? g_strdup (value) : nullptr; @@ -339,8 +341,11 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) { svgdpi = atof(this->getRepr()->attribute("inkscape:svg-dpi")); } this->dpi = svgdpi; - pixbuf = sp_image_repr_read_image(this->getRepr()->attribute("xlink:href"), - this->getRepr()->attribute("sodipodi:absref"), doc->getDocumentBase(), svgdpi); + gchar const *href = this->getAttribute("href"); + if(!href) { + href = this->getAttribute("xlink:href"); + } + pixbuf = sp_image_repr_read_image(href, this->getAttribute("sodipodi:absref"), doc->getDocumentBase(), svgdpi); if (pixbuf) { #if defined(HAVE_LIBLCMS2) @@ -551,8 +556,11 @@ gchar* SPImage::description() const { if (this->getRepr()->attribute("inkscape:svg-dpi")) { svgdpi = atof(this->getRepr()->attribute("inkscape:svg-dpi")); } - pb = sp_image_repr_read_image(this->getRepr()->attribute("xlink:href"), - this->getRepr()->attribute("sodipodi:absref"), this->document->getDocumentBase(), svgdpi); + gchar const *href = this->getAttribute("href"); + if(!href) { + href = this->getAttribute("xlink:href"); + } + pb = sp_image_repr_read_image(href, this->getAttribute("sodipodi:absref"), this->document->getDocumentBase(), svgdpi); if (pb) { ret = g_strdup_printf(_("%d × %d: %s"), diff --git a/src/object/sp-offset.cpp b/src/object/sp-offset.cpp index bcb24e8deb..5ddcde2a9a 100644 --- a/src/object/sp-offset.cpp +++ b/src/object/sp-offset.cpp @@ -134,7 +134,9 @@ void SPOffset::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "inkscape:original" ); } - if (this->getRepr()->attribute("xlink:href")) { + if (this->getRepr()->attribute("href")) { + this->readAttr( "href" ); + } else if(this->getAttribute("xlink:href")) { this->readAttr( "xlink:href" ); } else { gchar const *oldA = this->getRepr()->attribute("inkscape:href"); @@ -267,6 +269,7 @@ void SPOffset::set(SPAttributeEnum key, const gchar* value) { } break; + case SP_ATTR_HREF: case SP_ATTR_INKSCAPE_HREF: case SP_ATTR_XLINK_HREF: if ( value == nullptr ) { diff --git a/src/object/sp-pattern.cpp b/src/object/sp-pattern.cpp index 5017ca434f..ac929e00a3 100644 --- a/src/object/sp-pattern.cpp +++ b/src/object/sp-pattern.cpp @@ -75,6 +75,7 @@ void SPPattern::build(SPDocument *doc, Inkscape::XML::Node *repr) this->readAttr("height"); this->readAttr("viewBox"); this->readAttr("preserveAspectRatio"); + this->readAttr("href"); this->readAttr("xlink:href"); this->readAttr("style"); @@ -183,6 +184,7 @@ void SPPattern::set(SPAttributeEnum key, const gchar *value) this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); break; + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: if (value && this->href == value) { /* Href unchanged, do nothing. */ diff --git a/src/object/sp-script.cpp b/src/object/sp-script.cpp index d965421cbb..805e2be028 100644 --- a/src/object/sp-script.cpp +++ b/src/object/sp-script.cpp @@ -25,6 +25,7 @@ void SPScript::build(SPDocument* doc, Inkscape::XML::Node* repr) { SPObject::build(doc, repr); //Read values of key attributes from XML nodes into object. + this->readAttr( "href" ); this->readAttr( "xlink:href" ); doc->addResource("script", this); @@ -55,6 +56,7 @@ void SPScript::modified(unsigned int /*flags*/) { void SPScript::set(SPAttributeEnum key, const gchar* value) { switch (key) { + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: if (this->xlinkhref) { g_free(this->xlinkhref); diff --git a/src/object/sp-tag-use.cpp b/src/object/sp-tag-use.cpp index 40c5599e70..9108aa480b 100644 --- a/src/object/sp-tag-use.cpp +++ b/src/object/sp-tag-use.cpp @@ -58,6 +58,7 @@ void SPTagUse::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); + readAttr( "href" ); readAttr( "xlink:href" ); // We don't need to create child here: @@ -89,6 +90,7 @@ SPTagUse::set(SPAttributeEnum key, gchar const *value) { switch (key) { + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: { if ( value && href && ( strcmp(value, href) == 0 ) ) { /* No change, do nothing. */ diff --git a/src/object/sp-tref.cpp b/src/object/sp-tref.cpp index a99f8686f9..524c66ed6e 100644 --- a/src/object/sp-tref.cpp +++ b/src/object/sp-tref.cpp @@ -64,6 +64,7 @@ SPTRef::~SPTRef() { void SPTRef::build(SPDocument *document, Inkscape::XML::Node *repr) { SPItem::build(document, repr); + this->readAttr( "href" ); this->readAttr( "xlink:href" ); this->readAttr( "x" ); this->readAttr( "y" ); @@ -92,7 +93,7 @@ void SPTRef::set(SPAttributeEnum key, const gchar* value) { if (this->attributes.readSingleAttribute(key, value, style, &viewport)) { // x, y, dx, dy, rotate this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } else if (key == SP_ATTR_XLINK_HREF) { // xlink:href + } else if (key == SP_ATTR_XLINK_HREF || key == SP_ATTR_HREF) { // xlink:href or href if ( !value ) { // No value g_free(this->href); diff --git a/src/object/sp-tspan.cpp b/src/object/sp-tspan.cpp index bfa52c57b6..daf4625a60 100644 --- a/src/object/sp-tspan.cpp +++ b/src/object/sp-tspan.cpp @@ -264,6 +264,7 @@ void SPTextPath::build(SPDocument *doc, Inkscape::XML::Node *repr) { this->readAttr( "rotate" ); this->readAttr( "startOffset" ); this->readAttr( "side" ); + this->readAttr( "href" ); this->readAttr( "xlink:href" ); this->readAttr( "style"); @@ -289,6 +290,7 @@ void SPTextPath::set(SPAttributeEnum key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { switch (key) { + case SP_ATTR_HREF: case SP_ATTR_XLINK_HREF: this->sourcePath->link((char*)value); break; diff --git a/src/object/sp-use.cpp b/src/object/sp-use.cpp index f28d40bc85..8a86098d34 100644 --- a/src/object/sp-use.cpp +++ b/src/object/sp-use.cpp @@ -82,8 +82,8 @@ void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "y" ); this->readAttr( "width" ); this->readAttr( "height" ); - this->readAttr( "xlink:href" ); this->readAttr( "href" ); + this->readAttr( "xlink:href" ); // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, @@ -130,7 +130,8 @@ void SPUse::set(SPAttributeEnum key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_XLINK_HREF: case SP_ATTR_HREF: { + case SP_ATTR_XLINK_HREF: + case SP_ATTR_HREF: { if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { /* No change, do nothing. */ } else { diff --git a/src/ui/contextmenu.cpp b/src/ui/contextmenu.cpp index 85965743f4..e6184fd8f0 100644 --- a/src/ui/contextmenu.cpp +++ b/src/ui/contextmenu.cpp @@ -685,8 +685,12 @@ void ContextMenu::AnchorLinkRemove() void ContextMenu::MakeImageMenu () { Gtk::MenuItem* mi; - Inkscape::XML::Node *ir = _object->getRepr(); - const gchar *href = ir->attribute("xlink:href"); + const gchar *href = _object->getAttribute("href"); + if(!href) { + href = _object->getAttribute("xlink:href"); + } + + bool not_href = !href || strncmp(href, "data:", 5) == 0; /* Image properties */ mi = Gtk::manage(new Gtk::MenuItem(_("Image _Properties..."), true)); @@ -699,7 +703,7 @@ void ContextMenu::MakeImageMenu () mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEdit)); mi->show(); insert(*mi,positionOfLastDialog++); - if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + if ( not_href ) { mi->set_sensitive( FALSE ); } @@ -718,7 +722,7 @@ void ContextMenu::MakeImageMenu () mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEmbed)); mi->show(); insert(*mi,positionOfLastDialog++); - if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + if ( not_href ) { mi->set_sensitive( FALSE ); } } @@ -729,7 +733,7 @@ void ContextMenu::MakeImageMenu () mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageExtract)); mi->show(); insert(*mi,positionOfLastDialog++); - if ( (!href) || ((strncmp(href, "data:", 5) != 0)) ) { + if ( not_href ) { mi->set_sensitive( FALSE ); } } @@ -798,8 +802,10 @@ void ContextMenu::ImageEdit() auto itemlist= _desktop->selection->items(); for(auto i=itemlist.begin();i!=itemlist.end();++i){ - Inkscape::XML::Node *ir = (*i)->getRepr(); - const gchar *href = ir->attribute("xlink:href"); + const gchar *href = (*i)->getAttribute("href"); + if(!href) { + href = (*i)->getAttribute("xlink:href"); + } if (strncmp (href,"file:",5) == 0) { // URI to filename conversion diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 74d75439c3..8a1f851784 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1854,12 +1854,16 @@ bool CloneTiler::is_a_clone_of(SPObject *tile, SPObject *obj) Inkscape::XML::Node *obj_repr = obj->getRepr(); id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); } + + const gchar *href = tile->getAttribute("href"); + if(!href) { + href = tile->getAttribute("xlink:href"); + } if (dynamic_cast(tile) && - tile->getRepr()->attribute("xlink:href") && - (!id_href || !strcmp(id_href, tile->getRepr()->attribute("xlink:href"))) && - tile->getRepr()->attribute("inkscape:tiled-clone-of") && - (!id_href || !strcmp(id_href, tile->getRepr()->attribute("inkscape:tiled-clone-of")))) + href && (!id_href || !strcmp(id_href, href)) && + tile->getAttribute("inkscape:tiled-clone-of") && + (!id_href || !strcmp(id_href, tile->getAttribute("inkscape:tiled-clone-of")))) { result = true; } else { diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index 44bcf7f138..5ec8dbbe61 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -35,6 +35,7 @@ struct SPAttrDesc { }; static const SPAttrDesc anchor_desc[] = { + { N_("Href:"), "href"}, { N_("Href:"), "xlink:href"}, { N_("Target:"), "target"}, { N_("Type:"), "xlink:type"}, @@ -53,6 +54,7 @@ static const SPAttrDesc anchor_desc[] = { }; static const SPAttrDesc image_desc[] = { + { N_("URL:"), "href"}, { N_("URL:"), "xlink:href"}, { N_("X:"), "x"}, { N_("Y:"), "y"}, @@ -121,8 +123,11 @@ void ObjectAttributes::widget_setup () // else if (type == SP_TYPE_IMAGE) else if (SP_IS_IMAGE(item)) { - Inkscape::XML::Node *ir = obj->getRepr(); - const gchar *href = ir->attribute("xlink:href"); + + const gchar *href = obj->getAttribute("href"); + if(!href) { + href = obj->getAttribute("xlink:href"); + } if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { desc = image_nohref_desc; diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 213127d23d..f36403ea8e 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -992,11 +992,10 @@ gchar const* SymbolsDialog::styleFromUse( gchar const* id, SPDocument* document) std::vector l = useInDoc( document ); for( auto use:l ) { if ( use ) { - // Support SVG2 style href - const gchar *href = use->getRepr()->attribute("href"); - if (! href ) { - //Deprecated xlink:href reference: - href = use->getRepr()->attribute("xlink:href"); + // Support SVG2 style href but continue xlink support + const gchar *href = use->getAttribute("href"); + if (!href) { + href = use->getAttribute("xlink:href"); } if( href ) { Glib::ustring href2(href); diff --git a/src/xml/rebase-hrefs.cpp b/src/xml/rebase-hrefs.cpp index b6f7e5505e..39d7451f67 100644 --- a/src/xml/rebase-hrefs.cpp +++ b/src/xml/rebase-hrefs.cpp @@ -70,7 +70,8 @@ Inkscape::XML::rebase_href_attrs(gchar const *const old_abs_base, return attributes; } - GQuark const href_key = g_quark_from_static_string("xlink:href"); + GQuark const href_key = g_quark_from_static_string("href"); + GQuark const xlink_href_key = g_quark_from_static_string("xlink:href"); GQuark const absref_key = g_quark_from_static_string("sodipodi:absref"); /* First search attributes for xlink:href and sodipodi:absref, putting the rest in ret. @@ -82,7 +83,7 @@ Inkscape::XML::rebase_href_attrs(gchar const *const old_abs_base, List ret; { for (List ai(attributes); ai; ++ai) { - if (ai->key == href_key) { + if (ai->key == href_key || ai->key == xlink_href_key) { old_href = ai->value; if (!href_needs_rebasing(static_cast(old_href))) { return attributes; @@ -167,7 +168,10 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b for (auto image : images) { Inkscape::XML::Node *ir = image->getRepr(); - auto href_cstr = ir->attribute("xlink:href"); + auto href_cstr = ir->attribute("href"); + if (!href_cstr) { + href_cstr = ir->attribute("xlink:href"); + } if (!href_cstr) { continue; } -- GitLab From 89bcc8da9ae94b328f0439935abc4f9c297abaa6 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 23 Apr 2020 16:32:35 -0400 Subject: [PATCH 3/8] Remove alternative href attribute when writing href --- src/gradient-chemistry.cpp | 2 ++ src/io/resource-manager.cpp | 2 ++ src/object/color-profile.cpp | 2 ++ src/object/sp-anchor.cpp | 2 ++ src/object/sp-filter.cpp | 2 ++ src/object/sp-gradient.cpp | 2 ++ src/object/sp-hatch.cpp | 2 ++ src/object/sp-image.cpp | 6 ++++++ src/object/sp-pattern.cpp | 2 ++ src/object/sp-tag-use.cpp | 2 ++ src/object/sp-tref.cpp | 2 ++ src/object/sp-tspan.cpp | 2 ++ src/object/sp-use.cpp | 2 ++ src/selection-chemistry.cpp | 14 ++++++++++++-- src/ui/clipboard.cpp | 2 ++ src/xml/rebase-hrefs.cpp | 2 ++ 16 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index a7e111a668..e257a931cf 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -1507,6 +1507,8 @@ static void sp_gradient_repr_set_link(Inkscape::XML::Node *repr, SPGradient *lin } else { repr->removeAttribute("xlink:href"); } + // Always remove alternative href attribute + repr->removeAttribute("href"); } diff --git a/src/io/resource-manager.cpp b/src/io/resource-manager.cpp index 9a07e58b2a..d09d6f3e2c 100644 --- a/src/io/resource-manager.cpp +++ b/src/io/resource-manager.cpp @@ -370,6 +370,8 @@ bool ResourceManagerImpl::fixupBrokenLinks(SPDocument *doc) // TODO debug g_message(" Found a replacement"); ir->setAttributeOrRemoveIfEmpty( "xlink:href", mapping[href] ); + // Remove alternative href attribute + ir->removeAttribute("href"); if ( ir->attribute( "sodipodi:absref" ) ) { ir->removeAttribute("sodipodi:absref"); // Remove this attribute } diff --git a/src/object/color-profile.cpp b/src/object/color-profile.cpp index 907de90fe0..8209c6eb9b 100644 --- a/src/object/color-profile.cpp +++ b/src/object/color-profile.cpp @@ -435,6 +435,8 @@ Inkscape::XML::Node* ColorProfile::write(Inkscape::XML::Document *xml_doc, Inksc if ( (flags & SP_OBJECT_WRITE_ALL) || this->href ) { repr->setAttribute( "xlink:href", this->href ); + // Remove alternative href attribute + repr->removeAttribute("href"); } if ( (flags & SP_OBJECT_WRITE_ALL) || this->local ) { diff --git a/src/object/sp-anchor.cpp b/src/object/sp-anchor.cpp index 53994c6d30..87349c6fca 100644 --- a/src/object/sp-anchor.cpp +++ b/src/object/sp-anchor.cpp @@ -121,6 +121,8 @@ Inkscape::XML::Node* SPAnchor::write(Inkscape::XML::Document *xml_doc, Inkscape: } repr->setAttribute("xlink:href", this->href); + // Remove alternative href attribute + repr->removeAttribute("href"); if (this->type) repr->setAttribute("xlink:type", this->type); if (this->title) repr->setAttribute("xlink:title", this->title); diff --git a/src/object/sp-filter.cpp b/src/object/sp-filter.cpp index 7555f565a7..1a420ad0c1 100644 --- a/src/object/sp-filter.cpp +++ b/src/object/sp-filter.cpp @@ -319,6 +319,8 @@ Inkscape::XML::Node* SPFilter::write(Inkscape::XML::Document *doc, Inkscape::XML if (this->href->getURI()) { auto uri_string = this->href->getURI()->str(); repr->setAttributeOrRemoveIfEmpty("xlink:href", uri_string); + // Remove alternative href attribute + repr->removeAttribute("href"); } SPObject::write(doc, repr, flags); diff --git a/src/object/sp-gradient.cpp b/src/object/sp-gradient.cpp index f61e06ebd6..bc1b9f35b0 100644 --- a/src/object/sp-gradient.cpp +++ b/src/object/sp-gradient.cpp @@ -634,6 +634,8 @@ Inkscape::XML::Node *SPGradient::write(Inkscape::XML::Document *xml_doc, Inkscap if (this->ref->getURI()) { auto uri_string = this->ref->getURI()->str(); repr->setAttributeOrRemoveIfEmpty("xlink:href", uri_string); + // Make sure alternative attribute is not already set. + repr->removeAttribute("href"); } if ((flags & SP_OBJECT_WRITE_ALL) || this->units_set) { diff --git a/src/object/sp-hatch.cpp b/src/object/sp-hatch.cpp index 9e44300592..a5f8ede138 100644 --- a/src/object/sp-hatch.cpp +++ b/src/object/sp-hatch.cpp @@ -517,6 +517,8 @@ SPHatch *SPHatch::clone_if_necessary(SPItem *item, const gchar *property) repr->setAttribute("inkscape:collect", "always"); Glib::ustring parent_ref = Glib::ustring::compose("#%1", getRepr()->attribute("id")); repr->setAttribute("xlink:href", parent_ref); + // Make sure alternative href attribute is removed + repr->removeAttribute("href"); defsrepr->addChild(repr, nullptr); const gchar *child_id = repr->attribute("id"); diff --git a/src/object/sp-image.cpp b/src/object/sp-image.cpp index 419fd29d76..39e751a915 100644 --- a/src/object/sp-image.cpp +++ b/src/object/sp-image.cpp @@ -461,6 +461,8 @@ Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape:: } repr->setAttribute("xlink:href", this->href); + // Remove alternative href attribute + repr->removeAttribute("href"); /* fixme: Reset attribute if needed (Lauris) */ if (this->x._set) { @@ -822,6 +824,8 @@ void sp_embed_image(Inkscape::XML::Node *image_node, Inkscape::Pixbuf *pb) // It would be better to only keep the binary data around, // and base64 encode on the fly when saving the XML. image_node->setAttribute("xlink:href", buffer); + // Remove alternative href attribute + image_node->removeAttribute("href"); g_free(buffer); if (free_data) g_free(data); @@ -875,6 +879,8 @@ void sp_embed_svg(Inkscape::XML::Node *image_node, std::string const &fn) // It would be better to only keep the binary data around, // and base64 encode on the fly when saving the XML. image_node->setAttribute("xlink:href", buffer); + // Remove alternative href attribute + image_node->removeAttribute("href"); g_free(buffer); g_free(data); diff --git a/src/object/sp-pattern.cpp b/src/object/sp-pattern.cpp index ac929e00a3..66e0d04ced 100644 --- a/src/object/sp-pattern.cpp +++ b/src/object/sp-pattern.cpp @@ -331,6 +331,8 @@ SPPattern *SPPattern::_chain() const repr->setAttribute("inkscape:collect", "always"); Glib::ustring parent_ref = Glib::ustring::compose("#%1", getRepr()->attribute("id")); repr->setAttribute("xlink:href", parent_ref); + // Remove alternative href attribute + repr->removeAttribute("href"); defsrepr->addChild(repr, nullptr); SPObject *child = document->getObjectByRepr(repr); diff --git a/src/object/sp-tag-use.cpp b/src/object/sp-tag-use.cpp index 9108aa480b..f3ae1dad2c 100644 --- a/src/object/sp-tag-use.cpp +++ b/src/object/sp-tag-use.cpp @@ -133,6 +133,8 @@ SPTagUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, gui if (ref->getURI()) { auto uri_string = ref->getURI()->str(); repr->setAttributeOrRemoveIfEmpty("xlink:href", uri_string); + // Remove alternative href attribute + repr->removeAttribute("href"); } return repr; diff --git a/src/object/sp-tref.cpp b/src/object/sp-tref.cpp index 524c66ed6e..cdf5a011b0 100644 --- a/src/object/sp-tref.cpp +++ b/src/object/sp-tref.cpp @@ -179,6 +179,8 @@ Inkscape::XML::Node* SPTRef::write(Inkscape::XML::Document *xml_doc, Inkscape::X auto uri_string = uri.c_str(); debug("uri_string=%s", uri_string); repr->setAttribute("xlink:href", uri_string); + // Make sure alternative attribute is removed + repr->removeAttribute("href"); } SPItem::write(xml_doc, repr, flags); diff --git a/src/object/sp-tspan.cpp b/src/object/sp-tspan.cpp index daf4625a60..9d5f51a1fe 100644 --- a/src/object/sp-tspan.cpp +++ b/src/object/sp-tspan.cpp @@ -429,6 +429,8 @@ Inkscape::XML::Node* SPTextPath::write(Inkscape::XML::Document *xml_doc, Inkscap if ( this->sourcePath->sourceHref ) { repr->setAttribute("xlink:href", this->sourcePath->sourceHref); + // Remove alternative href attribute + repr->removeAttribute("href"); } if ( flags & SP_OBJECT_WRITE_BUILD ) { diff --git a/src/object/sp-use.cpp b/src/object/sp-use.cpp index 8a86098d34..708dc7b7ab 100644 --- a/src/object/sp-use.cpp +++ b/src/object/sp-use.cpp @@ -177,6 +177,8 @@ Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XM if (this->ref->getURI()) { auto uri_string = this->ref->getURI()->str(); repr->setAttributeOrRemoveIfEmpty("xlink:href", uri_string); + // Remove alternative href attribute + repr->removeAttribute("href"); } SPShape *shape = dynamic_cast(child); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 85e29eda8e..c83fa0c76f 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -548,6 +548,8 @@ void ObjectSet::duplicate(bool suppressDone, bool duplicateLayer) // std::cout << id << " old, its ori: " << orig->getId() << "; will relink:" << new_ids[i] << " to " << new_ids[j] << "\n"; SPObject *new_clone = doc->getObjectById(new_ids[i]); new_clone->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); + // Remove alternative href attribute + new_clone->removeAttribute("href"); new_clone->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } @@ -555,7 +557,10 @@ void ObjectSet::duplicate(bool suppressDone, bool duplicateLayer) gchar *source_href = offset->sourceHref; for (guint j = 0; j < old_ids.size(); j++) { if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { - doc->getObjectById(new_ids[i])->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); + auto obj = doc->getObjectById(new_ids[i]); + obj->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); + // Remove alternative href attribute + obj->removeAttribute("href"); } } } else if (text) { @@ -564,7 +569,10 @@ void ObjectSet::duplicate(bool suppressDone, bool duplicateLayer) const gchar *source_href = sp_textpath_get_path_item(textpath)->getId(); for (guint j = 0; j < old_ids.size(); j++) { if (!strcmp(source_href, old_ids[j])) { - doc->getObjectById(new_ids[i])->firstChild()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); + auto obj = doc->getObjectById(new_ids[i])->firstChild(); + obj->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); + // Remove alternative href attribute + obj->removeAttribute("href"); } } } else if (path) { @@ -2682,6 +2690,8 @@ void ObjectSet::relink() if (dynamic_cast(item)) { item->setAttribute("xlink:href", newref); + // Remove alternative href attribute + item->removeAttribute("href"); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); relinked = true; } diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 54a16886fa..d05cc2fe81 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -342,6 +342,8 @@ void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* Inkscape::XML::Node *use = _doc->createElement("svg:use"); use->setAttribute("xlink:href", id ); + // Remove alternative href attribute + use->removeAttribute("href"); // Set a default style in rather than so it can be changed. use->setAttribute("style", style ); if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { diff --git a/src/xml/rebase-hrefs.cpp b/src/xml/rebase-hrefs.cpp index 39d7451f67..1cc14cf23d 100644 --- a/src/xml/rebase-hrefs.cpp +++ b/src/xml/rebase-hrefs.cpp @@ -212,6 +212,8 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b href_str = Inkscape::uri_to_iri(href_str.c_str()); ir->setAttribute("xlink:href", href_str); + // Remove alternative href attribute + ir->removeAttribute("href"); } doc->setDocumentBase(new_base); -- GitLab From 06f8b9ac32aea74c9c3c808753a6ba240762a2a9 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 23 Apr 2020 18:59:06 -0400 Subject: [PATCH 4/8] Fix size checking in ustring --- src/extension/internal/odf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index b8bc6791b0..b663fbe675 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -1022,10 +1022,10 @@ void OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node) if (nodeName == "image" || nodeName == "svg:image") { Glib::ustring href = getAttribute(node, "href"); - if (href.size() == 0) { + if (href.empty()) { href = getAttribute(node, "xlink:href"); } - if (href.size() > 0 && imageTable.count(href) == 0) { + if (!href.empty() && imageTable.count(href) == 0) { try { auto uri = Inkscape::URI(href.c_str(), docBaseUri.c_str()); auto mimetype = uri.getMimeType(); -- GitLab From c2cb91ed10858de6a25ed729fc7826287247e6a9 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 23 Apr 2020 21:28:31 -0400 Subject: [PATCH 5/8] Fix attribute test, add href into ids --- testfiles/src/attributes-test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testfiles/src/attributes-test.cpp b/testfiles/src/attributes-test.cpp index 01462e1593..cdbf7151b3 100644 --- a/testfiles/src/attributes-test.cpp +++ b/testfiles/src/attributes-test.cpp @@ -359,10 +359,11 @@ std::vector getKnownAttrs() AttributeInfo("x-height", true), AttributeInfo("x1", true), AttributeInfo("x2", true), + AttributeInfo("href", true), + AttributeInfo("xlink:href", true), AttributeInfo("xChannelSelector", true), AttributeInfo("xlink:actuate", true), AttributeInfo("xlink:arcrole", true), - AttributeInfo("xlink:href", true), AttributeInfo("xlink:role", true), AttributeInfo("xlink:show", true), AttributeInfo("xlink:title", true), -- GitLab From 62c973cf9136fdbbf1c01d85eaf468f3a8ac4085 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 30 Apr 2020 15:14:10 -0400 Subject: [PATCH 6/8] Add Thomas' readAttr fallback alternative. --- src/object/color-profile.cpp | 3 +-- src/object/filters/image.cpp | 5 ++--- src/object/sp-anchor.cpp | 3 +-- src/object/sp-filter.cpp | 3 +-- src/object/sp-gradient.cpp | 3 +-- src/object/sp-hatch.cpp | 5 ++--- src/object/sp-image.cpp | 3 +-- src/object/sp-object.cpp | 23 ++++++++++++++--------- src/object/sp-object.h | 4 +++- src/object/sp-offset.cpp | 10 +++------- src/object/sp-pattern.cpp | 3 +-- src/object/sp-script.cpp | 3 +-- src/object/sp-tag-use.cpp | 3 +-- src/object/sp-tref.cpp | 3 +-- src/object/sp-tspan.cpp | 3 +-- src/object/sp-use.cpp | 3 +-- 16 files changed, 35 insertions(+), 45 deletions(-) diff --git a/src/object/color-profile.cpp b/src/object/color-profile.cpp index 8209c6eb9b..bbaf46a73d 100644 --- a/src/object/color-profile.cpp +++ b/src/object/color-profile.cpp @@ -303,8 +303,7 @@ void ColorProfile::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); this->readAttr( "id" ); this->readAttr( "local" ); this->readAttr( "name" ); diff --git a/src/object/filters/image.cpp b/src/object/filters/image.cpp index b34ba3758c..a878623f7e 100644 --- a/src/object/filters/image.cpp +++ b/src/object/filters/image.cpp @@ -57,9 +57,8 @@ void SPFeImage::build(SPDocument *document, Inkscape::XML::Node *repr) /*LOAD ATTRIBUTES FROM REPR HERE*/ - this->readAttr( "preserveAspectRatio" ); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("preserveAspectRatio"); + this->readAttr("href", "xlink:href"); } /** diff --git a/src/object/sp-anchor.cpp b/src/object/sp-anchor.cpp index 87349c6fca..0a2d714614 100644 --- a/src/object/sp-anchor.cpp +++ b/src/object/sp-anchor.cpp @@ -35,8 +35,7 @@ SPAnchor::~SPAnchor() = default; void SPAnchor::build(SPDocument *document, Inkscape::XML::Node *repr) { SPGroup::build(document, repr); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); this->readAttr( "xlink:type" ); this->readAttr( "xlink:role" ); this->readAttr( "xlink:arcrole" ); diff --git a/src/object/sp-filter.cpp b/src/object/sp-filter.cpp index 1a420ad0c1..0cf81b81f2 100644 --- a/src/object/sp-filter.cpp +++ b/src/object/sp-filter.cpp @@ -71,8 +71,7 @@ void SPFilter::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "width" ); this->readAttr( "height" ); this->readAttr( "filterRes" ); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); this->_refcount = 0; SPObject::build(document, repr); diff --git a/src/object/sp-gradient.cpp b/src/object/sp-gradient.cpp index bc1b9f35b0..2feef6c95a 100644 --- a/src/object/sp-gradient.cpp +++ b/src/object/sp-gradient.cpp @@ -293,8 +293,7 @@ void SPGradient::build(SPDocument *document, Inkscape::XML::Node *repr) this->readAttr( "gradientUnits" ); this->readAttr( "gradientTransform" ); this->readAttr( "spreadMethod" ); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); this->readAttr( "osb:paint" ); // Register ourselves diff --git a/src/object/sp-hatch.cpp b/src/object/sp-hatch.cpp index a5f8ede138..2e8ecf394d 100644 --- a/src/object/sp-hatch.cpp +++ b/src/object/sp-hatch.cpp @@ -77,9 +77,8 @@ void SPHatch::build(SPDocument* doc, Inkscape::XML::Node* repr) readAttr("y"); readAttr("pitch"); readAttr("rotate"); - readAttr("href"); - readAttr("xlink:href"); - readAttr( "style" ); + readAttr("href", "xlink:href"); + readAttr("style"); // Register ourselves doc->addResource("hatch", this); diff --git a/src/object/sp-image.cpp b/src/object/sp-image.cpp index 39e751a915..c4eba785a2 100644 --- a/src/object/sp-image.cpp +++ b/src/object/sp-image.cpp @@ -131,8 +131,7 @@ SPImage::~SPImage() = default; void SPImage::build(SPDocument *document, Inkscape::XML::Node *repr) { SPItem::build(document, repr); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); this->readAttr( "x" ); this->readAttr( "y" ); this->readAttr( "width" ); diff --git a/src/object/sp-object.cpp b/src/object/sp-object.cpp index e1e9c80599..3fe4db3e9d 100644 --- a/src/object/sp-object.cpp +++ b/src/object/sp-object.cpp @@ -1008,19 +1008,24 @@ void SPObject::setKeyValue(SPAttributeEnum key, gchar const *value) this->set(key, value); } -void SPObject::readAttr(gchar const *key) +void SPObject::readAttr(gchar const *key, char const *fallback) { - //g_assert(object != NULL); - //g_assert(SP_IS_OBJECT(object)); g_assert(key != nullptr); - - //XML Tree being used here. - g_assert(this->getRepr() != nullptr); - auto keyid = sp_attribute_lookup(key); + if (keyid != SP_ATTR_INVALID) { - /* Retrieve the 'key' attribute from the object's XML representation */ - gchar const *value = getRepr()->attribute(key); + + //XML Tree being used here. + auto repr = this->getRepr(); + g_assert(repr != nullptr); + + // Retrieve the 'key' attribute from the object's XML representation + gchar const *value = repr->attribute(key); + + // Use a fallback key, but apply it to the same attribute name + if(!value && fallback) { + value = repr->attribute(fallback); + } setKeyValue(keyid, value); } diff --git a/src/object/sp-object.h b/src/object/sp-object.h index 100583ba22..4ca2dfd8f2 100644 --- a/src/object/sp-object.h +++ b/src/object/sp-object.h @@ -721,8 +721,10 @@ public: /** * Read value of key attribute from XML node into object. + * + * fallback - The key to use if the main key isn't available */ - void readAttr(char const *key); + void readAttr(char const *key, char const *fallback = nullptr); char const *getTagName(SPException *ex) const; diff --git a/src/object/sp-offset.cpp b/src/object/sp-offset.cpp index 5ddcde2a9a..fb2b4b0359 100644 --- a/src/object/sp-offset.cpp +++ b/src/object/sp-offset.cpp @@ -134,11 +134,7 @@ void SPOffset::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "inkscape:original" ); } - if (this->getRepr()->attribute("href")) { - this->readAttr( "href" ); - } else if(this->getAttribute("xlink:href")) { - this->readAttr( "xlink:href" ); - } else { + if (this->getRepr()->attribute("inkscape:href")) { gchar const *oldA = this->getRepr()->attribute("inkscape:href"); if (oldA) { @@ -156,9 +152,9 @@ void SPOffset::build(SPDocument *document, Inkscape::XML::Node *repr) { this->removeAttribute("inkscape:href"); } - - this->readAttr( "xlink:href" ); } + + this->readAttr("href", "xlink:href"); } Inkscape::XML::Node* SPOffset::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { diff --git a/src/object/sp-pattern.cpp b/src/object/sp-pattern.cpp index 66e0d04ced..35c422a047 100644 --- a/src/object/sp-pattern.cpp +++ b/src/object/sp-pattern.cpp @@ -75,8 +75,7 @@ void SPPattern::build(SPDocument *doc, Inkscape::XML::Node *repr) this->readAttr("height"); this->readAttr("viewBox"); this->readAttr("preserveAspectRatio"); - this->readAttr("href"); - this->readAttr("xlink:href"); + this->readAttr("href", "xlink:href"); this->readAttr("style"); /* Register ourselves */ diff --git a/src/object/sp-script.cpp b/src/object/sp-script.cpp index 805e2be028..0223837cce 100644 --- a/src/object/sp-script.cpp +++ b/src/object/sp-script.cpp @@ -25,8 +25,7 @@ void SPScript::build(SPDocument* doc, Inkscape::XML::Node* repr) { SPObject::build(doc, repr); //Read values of key attributes from XML nodes into object. - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); doc->addResource("script", this); } diff --git a/src/object/sp-tag-use.cpp b/src/object/sp-tag-use.cpp index f3ae1dad2c..a611b638be 100644 --- a/src/object/sp-tag-use.cpp +++ b/src/object/sp-tag-use.cpp @@ -58,8 +58,7 @@ void SPTagUse::build(SPDocument *document, Inkscape::XML::Node *repr) { SPObject::build(document, repr); - readAttr( "href" ); - readAttr( "xlink:href" ); + readAttr("href", "xlink:href"); // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, diff --git a/src/object/sp-tref.cpp b/src/object/sp-tref.cpp index cdf5a011b0..145dae6edf 100644 --- a/src/object/sp-tref.cpp +++ b/src/object/sp-tref.cpp @@ -64,8 +64,7 @@ SPTRef::~SPTRef() { void SPTRef::build(SPDocument *document, Inkscape::XML::Node *repr) { SPItem::build(document, repr); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); this->readAttr( "x" ); this->readAttr( "y" ); this->readAttr( "dx" ); diff --git a/src/object/sp-tspan.cpp b/src/object/sp-tspan.cpp index 9d5f51a1fe..a7beb6a09b 100644 --- a/src/object/sp-tspan.cpp +++ b/src/object/sp-tspan.cpp @@ -264,8 +264,7 @@ void SPTextPath::build(SPDocument *doc, Inkscape::XML::Node *repr) { this->readAttr( "rotate" ); this->readAttr( "startOffset" ); this->readAttr( "side" ); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); this->readAttr( "style"); diff --git a/src/object/sp-use.cpp b/src/object/sp-use.cpp index 708dc7b7ab..2168cacfb1 100644 --- a/src/object/sp-use.cpp +++ b/src/object/sp-use.cpp @@ -82,8 +82,7 @@ void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "y" ); this->readAttr( "width" ); this->readAttr( "height" ); - this->readAttr( "href" ); - this->readAttr( "xlink:href" ); + this->readAttr("href", "xlink:href"); // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, -- GitLab From 49e955f2498aac8a08d8b5dd97524f82d6ac2f22 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sun, 3 May 2020 21:02:36 -0400 Subject: [PATCH 7/8] Remove old href attributes and point all at href without xlink --- src/attributes.cpp | 2 -- src/attributes.h | 2 -- src/object/color-profile.cpp | 1 - src/object/filters/image.cpp | 1 - src/object/sp-anchor.cpp | 1 - src/object/sp-filter.cpp | 1 - src/object/sp-gradient.cpp | 1 - src/object/sp-hatch.cpp | 1 - src/object/sp-image.cpp | 1 - src/object/sp-object.h | 4 +++- src/object/sp-offset.cpp | 2 -- src/object/sp-pattern.cpp | 1 - src/object/sp-script.cpp | 1 - src/object/sp-tag-use.cpp | 3 +-- src/object/sp-tref.cpp | 2 +- src/object/sp-tspan.cpp | 1 - src/object/sp-use.cpp | 1 - src/ui/dialog/filter-effects-dialog.cpp | 2 +- 18 files changed, 6 insertions(+), 22 deletions(-) diff --git a/src/attributes.cpp b/src/attributes.cpp index b0f7e91edf..324f75e5fe 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -55,7 +55,6 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_SPRAY_ORIGIN, "inkscape:spray-origin"}, /* SPAnchor */ {SP_ATTR_HREF, "href"}, - {SP_ATTR_XLINK_HREF, "xlink:href"}, {SP_ATTR_XLINK_TYPE, "xlink:type"}, {SP_ATTR_XLINK_ROLE, "xlink:role"}, {SP_ATTR_XLINK_ARCROLE, "xlink:arcrole"}, @@ -194,7 +193,6 @@ static SPStyleProp const props[] = { /* SPOffset */ {SP_ATTR_SODIPODI_ORIGINAL, "sodipodi:original"}, {SP_ATTR_INKSCAPE_ORIGINAL, "inkscape:original"}, - {SP_ATTR_INKSCAPE_HREF, "inkscape:href"}, {SP_ATTR_INKSCAPE_RADIUS, "inkscape:radius"}, /* SPLine */ {SP_ATTR_X1, "x1"}, diff --git a/src/attributes.h b/src/attributes.h index a6115847c8..79edde52dc 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -53,7 +53,6 @@ enum SPAttributeEnum : unsigned { SP_ATTR_INKSCAPE_SPRAY_ORIGIN, /* SPAnchor */ SP_ATTR_HREF, - SP_ATTR_XLINK_HREF, SP_ATTR_XLINK_TYPE, SP_ATTR_XLINK_ROLE, SP_ATTR_XLINK_ARCROLE, @@ -193,7 +192,6 @@ enum SPAttributeEnum : unsigned { /* SPOffset */ SP_ATTR_SODIPODI_ORIGINAL, SP_ATTR_INKSCAPE_ORIGINAL, - SP_ATTR_INKSCAPE_HREF, SP_ATTR_INKSCAPE_RADIUS, /* SPLine */ SP_ATTR_X1, diff --git a/src/object/color-profile.cpp b/src/object/color-profile.cpp index bbaf46a73d..d828250faa 100644 --- a/src/object/color-profile.cpp +++ b/src/object/color-profile.cpp @@ -322,7 +322,6 @@ void ColorProfile::build(SPDocument *document, Inkscape::XML::Node *repr) { void ColorProfile::set(SPAttributeEnum key, gchar const *value) { switch (key) { case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: if ( this->href ) { g_free( this->href ); this->href = nullptr; diff --git a/src/object/filters/image.cpp b/src/object/filters/image.cpp index a878623f7e..6c777bd825 100644 --- a/src/object/filters/image.cpp +++ b/src/object/filters/image.cpp @@ -101,7 +101,6 @@ void SPFeImage::set(SPAttributeEnum key, gchar const *value) { switch(key) { /*DEAL WITH SETTING ATTRIBUTES HERE*/ case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: if (this->href) { g_free(this->href); } diff --git a/src/object/sp-anchor.cpp b/src/object/sp-anchor.cpp index 0a2d714614..c26b5f29c9 100644 --- a/src/object/sp-anchor.cpp +++ b/src/object/sp-anchor.cpp @@ -69,7 +69,6 @@ void SPAnchor::release() { void SPAnchor::set(SPAttributeEnum key, const gchar* value) { switch (key) { case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: g_free(this->href); this->href = g_strdup(value); this->requestModified(SP_OBJECT_MODIFIED_FLAG); diff --git a/src/object/sp-filter.cpp b/src/object/sp-filter.cpp index 0cf81b81f2..d5184deb8f 100644 --- a/src/object/sp-filter.cpp +++ b/src/object/sp-filter.cpp @@ -166,7 +166,6 @@ void SPFilter::set(SPAttributeEnum key, gchar const *value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: if (value) { try { this->href->attach(Inkscape::URI(value)); diff --git a/src/object/sp-gradient.cpp b/src/object/sp-gradient.cpp index 2feef6c95a..df7c04feaa 100644 --- a/src/object/sp-gradient.cpp +++ b/src/object/sp-gradient.cpp @@ -388,7 +388,6 @@ void SPGradient::set(SPAttributeEnum key, gchar const *value) break; case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: if (value) { try { this->ref->attach(Inkscape::URI(value)); diff --git a/src/object/sp-hatch.cpp b/src/object/sp-hatch.cpp index 2e8ecf394d..19177130f2 100644 --- a/src/object/sp-hatch.cpp +++ b/src/object/sp-hatch.cpp @@ -200,7 +200,6 @@ void SPHatch::set(SPAttributeEnum key, const gchar* value) break; case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: if (value && href == value) { // Href unchanged, do nothing. } else { diff --git a/src/object/sp-image.cpp b/src/object/sp-image.cpp index c4eba785a2..b9a308b42d 100644 --- a/src/object/sp-image.cpp +++ b/src/object/sp-image.cpp @@ -175,7 +175,6 @@ void SPImage::release() { void SPImage::set(SPAttributeEnum key, const gchar* value) { switch (key) { case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: g_free (this->href); this->href = (value) ? g_strdup (value) : nullptr; this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); diff --git a/src/object/sp-object.h b/src/object/sp-object.h index 4ca2dfd8f2..15b96199e7 100644 --- a/src/object/sp-object.h +++ b/src/object/sp-object.h @@ -722,7 +722,9 @@ public: /** * Read value of key attribute from XML node into object. * - * fallback - The key to use if the main key isn't available + * @param key The name of the attribute being read. Is converted to an SPAttributeEnum + * @param fallback The key to use if the main key isn't available, does not need + * to exist in SPAttributeEnum. */ void readAttr(char const *key, char const *fallback = nullptr); diff --git a/src/object/sp-offset.cpp b/src/object/sp-offset.cpp index fb2b4b0359..a5f04c1024 100644 --- a/src/object/sp-offset.cpp +++ b/src/object/sp-offset.cpp @@ -266,8 +266,6 @@ void SPOffset::set(SPAttributeEnum key, const gchar* value) { break; case SP_ATTR_HREF: - case SP_ATTR_INKSCAPE_HREF: - case SP_ATTR_XLINK_HREF: if ( value == nullptr ) { sp_offset_quit_listening(this); if ( this->sourceHref ) { diff --git a/src/object/sp-pattern.cpp b/src/object/sp-pattern.cpp index 35c422a047..fe9af904cb 100644 --- a/src/object/sp-pattern.cpp +++ b/src/object/sp-pattern.cpp @@ -184,7 +184,6 @@ void SPPattern::set(SPAttributeEnum key, const gchar *value) break; case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: if (value && this->href == value) { /* Href unchanged, do nothing. */ } diff --git a/src/object/sp-script.cpp b/src/object/sp-script.cpp index 0223837cce..3dad6332ae 100644 --- a/src/object/sp-script.cpp +++ b/src/object/sp-script.cpp @@ -56,7 +56,6 @@ void SPScript::modified(unsigned int /*flags*/) { void SPScript::set(SPAttributeEnum key, const gchar* value) { switch (key) { case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: if (this->xlinkhref) { g_free(this->xlinkhref); } diff --git a/src/object/sp-tag-use.cpp b/src/object/sp-tag-use.cpp index a611b638be..c821df79f5 100644 --- a/src/object/sp-tag-use.cpp +++ b/src/object/sp-tag-use.cpp @@ -90,7 +90,7 @@ SPTagUse::set(SPAttributeEnum key, gchar const *value) switch (key) { case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: { + { if ( value && href && ( strcmp(value, href) == 0 ) ) { /* No change, do nothing. */ } else { @@ -113,7 +113,6 @@ SPTagUse::set(SPAttributeEnum key, gchar const *value) } break; } - default: SPObject::set(key, value); break; diff --git a/src/object/sp-tref.cpp b/src/object/sp-tref.cpp index 145dae6edf..636eb2429a 100644 --- a/src/object/sp-tref.cpp +++ b/src/object/sp-tref.cpp @@ -92,7 +92,7 @@ void SPTRef::set(SPAttributeEnum key, const gchar* value) { if (this->attributes.readSingleAttribute(key, value, style, &viewport)) { // x, y, dx, dy, rotate this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } else if (key == SP_ATTR_XLINK_HREF || key == SP_ATTR_HREF) { // xlink:href or href + } else if (key == SP_ATTR_HREF) { // xlink:href or href if ( !value ) { // No value g_free(this->href); diff --git a/src/object/sp-tspan.cpp b/src/object/sp-tspan.cpp index a7beb6a09b..8c8cccb3f5 100644 --- a/src/object/sp-tspan.cpp +++ b/src/object/sp-tspan.cpp @@ -290,7 +290,6 @@ void SPTextPath::set(SPAttributeEnum key, const gchar* value) { } else { switch (key) { case SP_ATTR_HREF: - case SP_ATTR_XLINK_HREF: this->sourcePath->link((char*)value); break; case SP_ATTR_SIDE: diff --git a/src/object/sp-use.cpp b/src/object/sp-use.cpp index 2168cacfb1..c45f06e58d 100644 --- a/src/object/sp-use.cpp +++ b/src/object/sp-use.cpp @@ -129,7 +129,6 @@ void SPUse::set(SPAttributeEnum key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_XLINK_HREF: case SP_ATTR_HREF: { if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { /* No change, do nothing. */ diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index a1575fee92..0efc4185d9 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -2842,7 +2842,7 @@ void FilterEffectsDialog::init_settings_widgets() _settings->add_dualspinscale(SP_ATTR_RADIUS, _("Radius:"), 0, 100, 1, 0.01, 1); _settings->type(NR_FILTER_IMAGE); - _settings->add_fileorelement(SP_ATTR_XLINK_HREF, _("Source of Image:")); + _settings->add_fileorelement(SP_ATTR_HREF, _("Source of Image:")); _image_x = _settings->add_entry(SP_ATTR_X,_("X"),_("X")); _image_x->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::image_x_changed)); //This commented because we want the default empty value of X or Y and couldent get it from SpinButton -- GitLab From 5c878066a61eb0fbda92de05841a647aae8a09a9 Mon Sep 17 00:00:00 2001 From: Thomas Holder Date: Mon, 4 May 2020 16:38:42 +0200 Subject: [PATCH 8/8] fix attributes test --- testfiles/src/attributes-test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testfiles/src/attributes-test.cpp b/testfiles/src/attributes-test.cpp index cdbf7151b3..d71e12b000 100644 --- a/testfiles/src/attributes-test.cpp +++ b/testfiles/src/attributes-test.cpp @@ -360,7 +360,7 @@ std::vector getKnownAttrs() AttributeInfo("x1", true), AttributeInfo("x2", true), AttributeInfo("href", true), - AttributeInfo("xlink:href", true), + // AttributeInfo("xlink:href", true), AttributeInfo("xChannelSelector", true), AttributeInfo("xlink:actuate", true), AttributeInfo("xlink:arcrole", true), @@ -412,7 +412,7 @@ std::vector getKnownAttrs() AttributeInfo("inkscape:flatsided", true), AttributeInfo("inkscape:groupmode", true), AttributeInfo("inkscape:highlight-color", true), - AttributeInfo("inkscape:href", true), + // AttributeInfo("inkscape:href", true), AttributeInfo("inkscape:label", true), AttributeInfo("inkscape:layoutOptions", true), AttributeInfo("inkscape:lockguides", true), -- GitLab