WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
94469
enable <animate> of viewBox attribute in <view> element
https://bugs.webkit.org/show_bug.cgi?id=94469
Summary
enable <animate> of viewBox attribute in <view> element
bugmenot
Reported
2012-08-20 05:21:19 PDT
testcase in URL field: zoom out on click when at #w Testing revealed <animate> either as a child element of <view> like in the testcase, or outside it with xlink:href="#w" (at
http://imgh.us/twZoomOutTest.svg#w
) fails to zoom the viewBox out to show the whole SVG. The begin="click" is only in the testcase for easier manual testing. Testcase works in Opera, not in Firefox.
Attachments
Patch
(12.59 KB, patch)
2019-09-03 04:21 PDT
,
Nikolas Zimmermann
no flags
Details
Formatted Diff
Diff
Patch
(29.04 KB, patch)
2019-09-05 03:20 PDT
,
Nikolas Zimmermann
no flags
Details
Formatted Diff
Diff
Patch
(18.01 KB, patch)
2019-09-10 14:16 PDT
,
Nikolas Zimmermann
no flags
Details
Formatted Diff
Diff
Patch
(17.85 KB, patch)
2019-09-13 04:21 PDT
,
Nikolas Zimmermann
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
bugmenot
Comment 1
2012-09-10 05:54:16 PDT
Mozilla has just fixed this in Firefox nightly builds:
https://bugzilla.mozilla.org/show_bug.cgi?id=783995
Nikolas Zimmermann
Comment 2
2019-09-03 03:43:08 PDT
I have a patch for this, will upload it soon.
Nikolas Zimmermann
Comment 3
2019-09-03 04:21:37 PDT
Created
attachment 377887
[details]
Patch
Nikolas Zimmermann
Comment 4
2019-09-03 04:23:16 PDT
My first patch after 7 years :-) Feels like home. NOTE: I plan to add more test coverage, especially dynamic updates for all the properties that we care about in SVGViewElement, just wanted to test the whole toolchain: webkit-patch, prepare-ChangeLog in combination with Git. Works like a charme!
Sam Weinig
Comment 5
2019-09-03 07:11:13 PDT
(In reply to Nikolas Zimmermann from
comment #4
)
> My first patch after 7 years :-) Feels like home. > NOTE: I plan to add more test coverage, especially dynamic updates for all > the properties that we care about in SVGViewElement, just wanted to test the > whole toolchain: webkit-patch, prepare-ChangeLog in combination with Git. > Works like a charme!
!!
Said Abou-Hallawa
Comment 6
2019-09-03 10:48:01 PDT
Comment on
attachment 377887
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=377887&action=review
Welcome back Niko.
> Source/WebCore/ChangeLog:10 > + visual effect. If a SVGSVGElement references a SVGViewElement, e.g. by loading an URL like > + "test.svg#customView", the custom view if parsed once in SVGSVGElement::scrollToFragment().
This statement is a little bit hard to read.
> Source/WebCore/svg/SVGSVGElement.cpp:669 > + if (rootElement->m_currentViewElement)
Should we check if (rootElement->m_currentViewElement != viewElement) before connecting the rootElement to the same viewElement?
> Source/WebCore/svg/SVGSVGElement.cpp:670 > + rootElement->m_currentViewElement->resetTargetElement();
Should we ASSERT(rootElement->m_currentViewElement->targetElement() == rootElement);?
> Source/WebCore/svg/SVGSVGElement.h:164 > + WeakPtr<SVGViewElement> m_currentViewElement { nullptr };
Is there a SVGViewElement per SVGSVGElement? What happens if an HTML page references the same SVG but with different views, e.g. "test.svg#customView1", "test.svg#customView2"? We may not optimize this case now and treat these URLs as different URLs. But this may change in the future.
> LayoutTests/ChangeLog:8 > + Add a new reftest demonstrating that animations of SVG <view> elements now behave as expected.
Should we include a test case for referencing the same SVG from the same HTML but with different view elements?
> LayoutTests/svg/custom/animation-on-view-element-expected.html:15 > + <iframe style="border: none" onload="loaded()" width='200' height='200' src='resources/animation-on-view-element-final.svg'></iframe>
Why do we have to have two SVGs: one for the test page and one for the expected page? Can't we use one SVG with two different views: one covers the whole SVG and the other one animates till it cover the whole SVG?
> LayoutTests/svg/custom/animation-on-view-element.html:17 > + <iframe id="svgFrame" style="border: none" onload="loaded()" width='200' height='200' src='resources/animation-on-view-element.svg#customView'></iframe>
Should not <img src='resources/animation-on-view-element.svg#customView'> work the same way?
> LayoutTests/svg/custom/resources/animation-on-view-element.svg:1 > +<svg xmlns="
http://www.w3.org/2000/svg
" width="200" height="200" id="outermostSVG">
What is the use of id="outermostSVG"?
> LayoutTests/svg/custom/resources/animation-on-view-element.svg:14 > + <animate attributeName="viewBox" dur="2s" begin="1s" to="0 0 200 200" fill="freeze"/>
Another way to do this or maybe it can be used in another test is <set attributeName="viewBox" to="0 0 200 200"/>
Said Abou-Hallawa
Comment 7
2019-09-03 12:43:44 PDT
Should
https://bugs.webkit.org/show_bug.cgi?id=196554
be duped to this one?
Nikolas Zimmermann
Comment 8
2019-09-03 13:30:35 PDT
(In reply to Said Abou-Hallawa from
comment #6
)
> Welcome back Niko.
Thanks Said!
> > > Source/WebCore/ChangeLog:10 > > + visual effect. If a SVGSVGElement references a SVGViewElement, e.g. by loading an URL like > > + "test.svg#customView", the custom view if parsed once in SVGSVGElement::scrollToFragment(). > > This statement is a little bit hard to read.
Indeed, and wrong as well, I will revisit this.
> > > Source/WebCore/svg/SVGSVGElement.cpp:669 > > + if (rootElement->m_currentViewElement) > > Should we check if (rootElement->m_currentViewElement != viewElement) before > connecting the rootElement to the same viewElement?
To my current understanding, this should not be possible, as the scrollToFragment() path should only be executed once per page load. I am currently preparing a few more tests to clarify all the corner cases and document the intended behavior. Let us rediscuss this, once I am confident, if it is possible to trigger this condition or not.
> > > Source/WebCore/svg/SVGSVGElement.cpp:670 > > + rootElement->m_currentViewElement->resetTargetElement(); > > Should we ASSERT(rootElement->m_currentViewElement->targetElement() == > rootElement);?
Good idea.
> > Source/WebCore/svg/SVGSVGElement.h:164 > > + WeakPtr<SVGViewElement> m_currentViewElement { nullptr }; > > Is there a SVGViewElement per SVGSVGElement?
The outermost SVG element of a document, could reference max. one SVGViewElement.
> What happens if an HTML page > references the same SVG but with different views, e.g. > "test.svg#customView1", "test.svg#customView2"?
These are separated documents, I see no issue?
> We may not optimize this > case now and treat these URLs as different URLs. But this may change in the > future.
I see - you are worried that the same <view> element is referenced by multiple "outermost SVG elements", steming from different documents. This would affect a lot more places throughout the SVG codebase.
> > > LayoutTests/ChangeLog:8 > > + Add a new reftest demonstrating that animations of SVG <view> elements now behave as expected. > > Should we include a test case for referencing the same SVG from the same > HTML but with different view elements?
Sure, I plan to add exactly a test like this. Also we should check the SVGViewSpec is correct, also in cases when the view element is animated.
> > > LayoutTests/svg/custom/animation-on-view-element-expected.html:15 > > + <iframe style="border: none" onload="loaded()" width='200' height='200' src='resources/animation-on-view-element-final.svg'></iframe> > > Why do we have to have two SVGs: one for the test page and one for the > expected page? Can't we use one SVG with two different views: one covers the > whole SVG and the other one animates till it cover the whole SVG?
Ahh, just stupidity :-) I uploaded the patch early, and did not carefully check the test yet - you are right, I will fix this.
> > > LayoutTests/svg/custom/animation-on-view-element.html:17 > > + <iframe id="svgFrame" style="border: none" onload="loaded()" width='200' height='200' src='resources/animation-on-view-element.svg#customView'></iframe> > > Should not <img src='resources/animation-on-view-element.svg#customView'> > work the same way?
From the visual point of view yes, but I have no access to the content document in that case, this only works using <embed> / <object> / <iframe>. In this particular test, I am modifying the SVG currentTime attribute and thus need access to the content document from the host document.
> > > LayoutTests/svg/custom/resources/animation-on-view-element.svg:1 > > +<svg xmlns="
http://www.w3.org/2000/svg
" width="200" height="200" id="outermostSVG"> > > What is the use of id="outermostSVG"?
This is a relict from the original test case which used begin="outermostSVG.click" (just with a different naming convention for the id).
> > > LayoutTests/svg/custom/resources/animation-on-view-element.svg:14 > > + <animate attributeName="viewBox" dur="2s" begin="1s" to="0 0 200 200" fill="freeze"/> > > Another way to do this or maybe it can be used in another test is > > <set attributeName="viewBox" to="0 0 200 200"/>
Sure, we should check this as well. I tried to stay as close as possible to the original test case referenced in this bug report. Thanks Said for the review! More tests and checks will follow.
Nikolas Zimmermann
Comment 9
2019-09-03 13:39:17 PDT
***
Bug 196554
has been marked as a duplicate of this bug. ***
Nikolas Zimmermann
Comment 10
2019-09-03 13:39:33 PDT
(In reply to Said Abou-Hallawa from
comment #7
)
> Should
https://bugs.webkit.org/show_bug.cgi?id=196554
be duped to this one?
Done.
Daniel Bates
Comment 11
2019-09-04 16:47:53 PDT
Welcome back!!!
Nikolas Zimmermann
Comment 12
2019-09-05 03:20:55 PDT
Created
attachment 378072
[details]
Patch
Nikolas Zimmermann
Comment 13
2019-09-05 03:21:46 PDT
(In reply to Daniel Bates from
comment #11
)
> Welcome back!!!
Thanks, nice to hear from you again Daniel :-)
Nikolas Zimmermann
Comment 14
2019-09-05 03:22:53 PDT
Said, please check again. I've added more assertions, incorporated your comments and added two more layout tests.
Daniel Bates
Comment 15
2019-09-05 03:42:13 PDT
Comment on
attachment 378072
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=378072&action=review
> Source/WebCore/svg/SVGSVGElement.cpp:670 > + ASSERT(rootElement->m_currentViewElement->targetElement());
Can this assert be removed given the one below?
Nikolas Zimmermann
Comment 16
2019-09-05 04:34:47 PDT
(In reply to Daniel Bates from
comment #15
)
> Comment on
attachment 378072
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=378072&action=review
> > > Source/WebCore/svg/SVGSVGElement.cpp:670 > > + ASSERT(rootElement->m_currentViewElement->targetElement()); > > Can this assert be removed given the one below?
In principle yes, I split them up to to differentiate between the "targetElement is null" and "the targetElement differs from the rootElement" (rootElement is already non-null).
Said Abou-Hallawa
Comment 17
2019-09-05 11:05:53 PDT
Comment on
attachment 378072
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=378072&action=review
> Source/WebCore/ChangeLog:12 > + The settings from the SVGViewElement are only pasrsed onco in SVGSVGElement::scrollToFragment(). Dynamic updates
onco -> once
> Source/WebCore/ChangeLog:14 > + the SVGSVGElement does not re-evaluates its viewBox. Fix that by introducing a link between SVGSVGElement
does not re-evaluates -> does not re-evaluate
> LayoutTests/ChangeLog:22 > + Verify that dynamic updates to the <view> element in the external SVG, are reflect in the SVGViewSpec API as well (SVGSVGElement::currentView).
This test is great but I think it deserves a separate patch because most of it is not related to this patch and can pass without it.
> LayoutTests/svg/dom/SVGViewSpec-multiple-views.html:124 > + iframeElement.contentDocument.documentElement.getElementById("view2").setAttribute("viewBox", "10 10 30 30"); > + > + debug(""); > + debug("Check viewBox value after modification"); > + shouldBe("currentView.viewBox.baseVal.x", "10"); > + shouldBe("currentView.viewBox.baseVal.y", "10"); > + shouldBe("currentView.viewBox.baseVal.width", "30"); > + shouldBe("currentView.viewBox.baseVal.height", "30"); > + shouldBeEqualToString("currentView.viewBoxString", "10 10 30 30");
This section is the only one that calls setAttribute("viewBox"). So I think the rest of this test can pass without this patch. I guess this is because of the missing SVGViewElement::svgAttributeChanged(). So I would suggest submitting this test in a separate patch before this one after removing this section. Then add this section the test in this patch or make a new test for setAttribute("viewBox").
Nikolas Zimmermann
Comment 18
2019-09-05 14:53:31 PDT
(In reply to Said Abou-Hallawa from
comment #17
)
> Comment on
attachment 378072
[details]
> Patch > > onco -> once > does not re-evaluates -> does not re-evaluate
Sorry for the typos, I will make sure to re-read the ChangeLog next time before submitting.
> > LayoutTests/ChangeLog:22 > > + Verify that dynamic updates to the <view> element in the external SVG, are reflect in the SVGViewSpec API as well (SVGSVGElement::currentView). > > This test is great but I think it deserves a separate patch because most of > it is not related to this patch and can pass without it.
Fair enough, I will split it into a separated ticket.
> > > LayoutTests/svg/dom/SVGViewSpec-multiple-views.html:124 > > + iframeElement.contentDocument.documentElement.getElementById("view2").setAttribute("viewBox", "10 10 30 30"); > > + > > + debug(""); > > + debug("Check viewBox value after modification"); > > + shouldBe("currentView.viewBox.baseVal.x", "10"); > > + shouldBe("currentView.viewBox.baseVal.y", "10"); > > + shouldBe("currentView.viewBox.baseVal.width", "30"); > > + shouldBe("currentView.viewBox.baseVal.height", "30"); > > + shouldBeEqualToString("currentView.viewBoxString", "10 10 30 30"); > > This section is the only one that calls setAttribute("viewBox"). So I think > the rest of this test can pass without this patch. I guess this is because > of the missing SVGViewElement::svgAttributeChanged().
Sure! The intention of the test was to convince myself, that the loading of external SVGs with fragment identifiers works as intended (no reloads, only scrollToAnchor() calls).
> So I would suggest submitting this test in a separate patch before this one > after removing this section. Then add this section the test in this patch or > make a new test for setAttribute("viewBox").
Okay, will take care of this tomorrow. Thanks for the quick review!
Nikolas Zimmermann
Comment 19
2019-09-06 00:57:47 PDT
(In reply to Nikolas Zimmermann from
comment #18
)
> > This test is great but I think it deserves a separate patch because most of > > it is not related to this patch and can pass without it. > Fair enough, I will split it into a separated ticket.
Filed
https://bugs.webkit.org/show_bug.cgi?id=201536
. Will update this patch once the ticket is done. P.S. Whom shall I mail to regain commiter rights? My Subversion account is disabled for sure. For reviewer status it is too early, still need to fix a few more issues and do unofficial reviews :-)
Nikolas Zimmermann
Comment 20
2019-09-06 08:23:36 PDT
(In reply to Nikolas Zimmermann from
comment #19
)
> P.S. Whom shall I mail to regain commiter rights? My Subversion account is > disabled for sure. For reviewer status it is too early, still need to fix a > few more issues and do unofficial reviews :-)
Never mind, I found all information on
https://webkit.org/commit-and-review-policy/
.
Nikolas Zimmermann
Comment 21
2019-09-10 13:35:49 PDT
Will upload a new patch tomorrow morning, now that the SVGViewSpec test landed.
Nikolas Zimmermann
Comment 22
2019-09-10 14:16:55 PDT
Created
attachment 378490
[details]
Patch
Said Abou-Hallawa
Comment 23
2019-09-12 10:00:25 PDT
Comment on
attachment 378490
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=378490&action=review
> Source/WebCore/svg/SVGSVGElement.cpp:671 > + ASSERT(rootElement->m_currentViewElement->targetElement()); > + ASSERT(rootElement->m_currentViewElement->targetElement() == rootElement);
I think the second assertion is sufficient since at this point we are sure rootElement != nullptr.
> Source/WebCore/svg/SVGSVGElement.cpp:678 > + if (!rootElement->m_currentViewElement || rootElement->m_currentViewElement != viewElement)
The first clause is not needed. We know that viewElement != nullptr so if rootElement->m_currentViewElement == nullptr, rootElement->m_currentViewElement != viewElement will be true.
> Source/WebCore/svg/SVGSVGElement.cpp:680 > + rootElement->m_currentViewElement->setTargetElement(*rootElement);
I think this statement should be moved under the previous if-statement. If we are not setting rootElement->m_currentViewElement to a new value, then the target element of the rootElement->m_currentViewElement should be equal to rootElement. In fact this what we assert a few lines above.
> Source/WebCore/svg/SVGSVGElement.h:164 > + WeakPtr<SVGViewElement> m_currentViewElement { nullptr };
Why is this a WeakPtr? My understanding is SVGSVGElement should own its current view so there should an ownership relation from SVGSVGElement to SVGViewElement. Even in the new code, SVGSVGElement is the one that controls the life cycle of both SVGSVGElement::m_currentViewElement and SVGViewElement::m_targetElement. SVGSVGElement::m_currentViewElement is changed here: rootElement->m_currentViewElement = makeWeakPtr(viewElement); SVGViewElement::m_targetElement is changed here: rootElement->m_currentViewElement->resetTargetElement(); and rootElement->m_currentViewElement->setTargetElement(*rootElement); On contrary to this SVGViewElement does not change any of these pointers. So I think this should be RefPtr while SVGViewElement::m_targetElement should stay WeakPtr.
Nikolas Zimmermann
Comment 24
2019-09-13 03:38:05 PDT
(In reply to Said Abou-Hallawa from
comment #23
)
> Comment on
attachment 378490
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=378490&action=review
> > > Source/WebCore/svg/SVGSVGElement.cpp:671 > > + ASSERT(rootElement->m_currentViewElement->targetElement()); > > + ASSERT(rootElement->m_currentViewElement->targetElement() == rootElement); > > I think the second assertion is sufficient since at this point we are sure > rootElement != nullptr.
Agreed, that alone is enough to be sure that targetElement() was null if the assertion fires.
> > Source/WebCore/svg/SVGSVGElement.cpp:678 > > + if (!rootElement->m_currentViewElement || rootElement->m_currentViewElement != viewElement) > > The first clause is not needed. We know that viewElement != nullptr so if > rootElement->m_currentViewElement == nullptr, > rootElement->m_currentViewElement != viewElement will be true.
Sure, I just found it easier to read, but I can change it you like, I do not have a strong opinion.
> > Source/WebCore/svg/SVGSVGElement.cpp:680 > > + rootElement->m_currentViewElement->setTargetElement(*rootElement); > > I think this statement should be moved under the previous if-statement. If > we are not setting rootElement->m_currentViewElement to a new value, then > the target element of the rootElement->m_currentViewElement should be equal > to rootElement. In fact this what we assert a few lines above.
Good catch, that was the initial intention and got lost in refactoring.
> > Source/WebCore/svg/SVGSVGElement.h:164 > > + WeakPtr<SVGViewElement> m_currentViewElement { nullptr }; > > Why is this a WeakPtr? My understanding is SVGSVGElement should own its > current view so there should an ownership relation from SVGSVGElement to > SVGViewElement. Even in the new code, SVGSVGElement is the one that controls > the life cycle of both SVGSVGElement::m_currentViewElement and > SVGViewElement::m_targetElement. > > SVGSVGElement::m_currentViewElement is changed here: > > rootElement->m_currentViewElement = makeWeakPtr(viewElement); > > SVGViewElement::m_targetElement is changed here: > > rootElement->m_currentViewElement->resetTargetElement(); > > and > > rootElement->m_currentViewElement->setTargetElement(*rootElement); > > On contrary to this SVGViewElement does not change any of these pointers. So > I think this should be RefPtr while SVGViewElement::m_targetElement should > stay WeakPtr.
I initially chose WeakPtr for both to a) avoid dangling pointers and b) do not potentially introduce refcounting cycles. But I agree there is no risk in changing to RefPtr and it clarifies the ownership situation. I will make the changes and upload a new patch, thanks Said! Feels good to receive valuable comments! :-)
Nikolas Zimmermann
Comment 25
2019-09-13 04:21:01 PDT
Created
attachment 378722
[details]
Patch
EWS
Comment 26
2019-09-13 10:36:39 PDT
Comment on
attachment 378722
[details]
Patch Rejecting
attachment 378722
[details]
from commit-queue.
zimmermann@kde.org
does not have committer permissions according to
https://trac.webkit.org/browser/trunk/Tools/Scripts/webkitpy/common/config/contributors.json
. - If you do not have committer rights please read
http://webkit.org/coding/contributing.html
for instructions on how to use bugzilla flags. - If you have committer rights please correct the error in Tools/Scripts/webkitpy/common/config/contributors.json by adding yourself to the file (no review needed). The commit-queue restarts itself every 2 hours. After restart the commit-queue will correctly respect your committer rights.
Nikolas Zimmermann
Comment 27
2019-09-13 10:38:44 PDT
Thanks a lot Said.
WebKit Commit Bot
Comment 28
2019-09-13 11:21:20 PDT
Comment on
attachment 378722
[details]
Patch Clearing flags on attachment: 378722 Committed
r249843
: <
https://trac.webkit.org/changeset/249843
>
WebKit Commit Bot
Comment 29
2019-09-13 11:21:22 PDT
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 30
2019-09-13 11:22:38 PDT
<
rdar://problem/55346015
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug