-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AF-390 Add detection for / utilities to work around ResizeSensors that are detached from the DOM #187
Conversation
TODO: Can we make this less stinky?
Security InsightsNo security relevant content was detected by automated scans. Action Items
Questions or Comments? Reach out on HipChat: InfoSec Forum. |
lib/src/component/resize_sensor.dart
Outdated
ResizeSensorHandler onInitialize; | ||
|
||
/// A function invoked when the parent element is resized. | ||
/// A function invoked with a [ResizeSensorEvent] argument when the `children` of the | ||
/// sensor causes the root node rendered by the [ResizeSensor] to resize. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when the
children
should be:
when the ResizeSensor resizes, either due to its parent or children resizing
lib/src/component/resize_sensor.dart
Outdated
@@ -44,10 +73,20 @@ abstract class ResizeSensorPropsMixin { | |||
|
|||
Map get props; | |||
|
|||
/// A function invoked when the resize sensor is initialized. | |||
/// A function invoked with a [ResizeSensorEvent] argument when the resize sensor is initialized. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#nit ResizeSensorEvent
is a redundant type reference; it's implied in the ResizeSensorHandler
typing.
lib/src/component/resize_sensor.dart
Outdated
ResizeSensorHandler onInitialize; | ||
|
||
/// A function invoked when the parent element is resized. | ||
/// A function invoked with a [ResizeSensorEvent] argument when the `children` of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#nit ResizeSensorEvent
is a redundant type reference; it's implied in the ResizeSensorHandler
typing.
lib/src/component/resize_sensor.dart
Outdated
// Only perform this check if the consumer sets the callback. | ||
if (props.onDidMountDetached == null) return; | ||
|
||
var wasMountedDetachedFromDom = _needsReset(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we glean this information from the DOM hierachy instead, so that we avoid accessing scrollTop
/scrollLeft
and causing reflows when quickMount
is true
?
bool _isAttachedToDocument(Node node) {
Node current = node;
while (current != null) {
if (current == document) return true;
current = node.parentNode;
}
return false;
}
var wasMountedDetachedFromDom = !_isAttachedToDocument(findDomNode(this));
lib/src/component/resize_sensor.dart
Outdated
/// > __NOTE:__ If this happens - you most likely do not need to set this callback. If for some reason the callback | ||
/// sometimes returns `true`, and sometimes returns `false` _(unexpected)_, | ||
/// you may have other underlying issues in your implementation that should be addressed separately. | ||
BoolCallback onDidMountDetached; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name of this callback is a little misleading, and might imply that it's only called when the node was mounted detached from the DOM.
What about something like onDetachedMountCheck
lib/src/component/resize_sensor.dart
Outdated
/// repair the resize behavior via a call to [ResizeSensorComponent.forceResetDetachedSensor] at a time | ||
/// when you are sure that the sensor has become attached to the DOM. | ||
/// | ||
/// ### What does the bool return value indicate? ### |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/return value/argument
lib/src/component/resize_sensor.dart
Outdated
/// | ||
/// ### What does the bool return value indicate? ### | ||
/// | ||
/// * A `true` return value indicates that __the [ResizeSensor] was mounted detached from the DOM__, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/return value/argument
lib/src/component/resize_sensor.dart
Outdated
/// values of the expand / collapse sensor nodes to the maximum possible value - which is what forces the | ||
/// reflow / paint that makes the [onResize] callbacks begin firing when expected again. | ||
/// | ||
/// * A `false` return value indicates that __the [ResizeSensor] was mounted attached to the DOM__. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/return value/argument
Codecov Report
@@ Coverage Diff @@
## master #187 +/- ##
==========================================
+ Coverage 94.44% 94.48% +0.05%
==========================================
Files 34 34
Lines 1617 1630 +13
==========================================
+ Hits 1527 1540 +13
Misses 90 90 |
QA +1 @Workiva/release-management-pp |
Ultimate problem:
When a
ResizeSensor
is mounted into a node that is detached from the DOM, theoffsetWidth
/offsetHeight
values of theexpand
/collapse
nodes rendered by theResizeSensor
are 0, causing an invalid state within theResizeSensor
that will result inprops.onResize
events to not fire as expected.How it was fixed:
props.onDetachedMountCheck
callback, which will returntrue
if the sensor was mounted into a detached node. That true value gives consumers the knowledge that they will most likely need to make use of a call toforceResetDetachedSensor()
to get theironResize
prop callbacks working again once they are confident that the node is now attached to the DOM.Testing suggestions:
Passing tests.
Potential areas of regression:
None expected - new functionality only.