Skip to content

Commit 1a0d6bc

Browse files
Improve some doc comments
+ That were discovered while doing the memory leak audit
1 parent bc46e9c commit 1a0d6bc

16 files changed

+307
-151
lines changed

lib/src/component/resize_sensor.dart

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import 'dart:html';
2121

2222
import 'package:meta/meta.dart';
2323
import 'package:platform_detect/platform_detect.dart';
24-
import 'package:react/react.dart' as react;
2524
import 'package:over_react/over_react.dart';
2625

2726
/// A wrapper component that detects when its parent is resized.
@@ -189,7 +188,7 @@ class ResizeSensorComponent extends UiComponent<ResizeSensorProps> with _SafeAni
189188

190189
/// When the expand or collapse sensors are resized, builds a [ResizeSensorEvent] and calls
191190
/// props.onResize with it. Then, calls through to [_reset()].
192-
void _handleSensorScroll(react.SyntheticEvent _) {
191+
void _handleSensorScroll(SyntheticEvent _) {
193192
if (_scrollEventsToIgnore > 0) {
194193
_scrollEventsToIgnore--;
195194
return;

lib/src/component_declaration/component_base.dart

+123-40
Large diffs are not rendered by default.

lib/src/component_declaration/component_type_checking.dart

+44-8
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
library over_react.component_declaration.component_type_checking;
1717

1818
import 'package:over_react/src/component_declaration/component_base.dart' show UiFactory;
19+
import 'package:over_react/src/component_declaration/annotations.dart' as annotations show Component;
1920
import 'package:over_react/src/util/react_wrappers.dart';
2021
import 'package:react/react_client.dart';
2122
import 'package:react/react_client/js_interop_helpers.dart';
23+
import 'package:react/react_client/react_interop.dart';
2224

2325
// ----------------------------------------------------------------------
2426
// Component type registration and internal type metadata management
@@ -73,10 +75,40 @@ class ComponentTypeMeta {
7375
///
7476
/// Used to enable inheritance in component type-checking in [isComponentOfType].
7577
///
76-
/// E.g., if component `Bar` is a subtype of component `Foo`, then:
78+
/// E.g., if component `Bar` is a subtype of component `Foo`:
79+
///
80+
/// //
81+
/// // foo.dart
82+
/// //
83+
///
84+
/// @Factory()
85+
/// UiFactory<FooProps> Foo;
86+
///
87+
/// @Component()
88+
/// class FooComponent extends UiComponent<FooProps> {
89+
/// // ...
90+
/// }
91+
///
92+
/// //
93+
/// // bar.dart
94+
/// //
95+
///
96+
/// @Factory()
97+
/// UiFactory<FooProps> Foo;
98+
///
99+
/// @Component(subtypeOf: FooComponent)
100+
/// class BarComponent extends UiComponent<BarProps> {
101+
/// // ...
102+
/// }
103+
///
104+
/// //
105+
/// // app.dart
106+
/// //
77107
///
78108
/// isComponentOfType(Bar()(), Bar); // true (due to normal type-checking)
79109
/// isComponentOfType(Bar()(), Foo); // true (due to parent type-checking)
110+
///
111+
/// > See: `subtypeOf` (within [annotations.Component])
80112
final ReactDartComponentFactoryProxy parentType;
81113

82114
ComponentTypeMeta(this.isWrapper, this.parentType);
@@ -108,7 +140,7 @@ class ComponentTypeMeta {
108140
///
109141
/// Consumers of this function should be sure to take the latter case into consideration.
110142
///
111-
/// __CAVEAT:__ Due to type-checking limitations on JS-interop types, when [typeAlias] is a [Function],
143+
/// > __CAVEAT:__ Due to type-checking limitations on JS-interop types, when [typeAlias] is a [Function],
112144
/// and it is not found to be an alias for another type, it will be returned as if it were a valid type.
113145
dynamic getComponentTypeFromAlias(dynamic typeAlias) {
114146
/// If `typeAlias` is a factory, return its type.
@@ -143,19 +175,19 @@ dynamic getComponentTypeFromAlias(dynamic typeAlias) {
143175
/// * [String] tag name (DOM components)
144176
/// * [Function] ([ReactClass]) factory (Dart/JS composite components)
145177
///
146-
/// Note: It's impossible to determine know whether something is a ReactClass due to type-checking restrictions
147-
/// for JS-interop classes, so a Function type-check is the best we can do.
178+
/// > __NOTE:__ It's impossible to determine know whether something is a [ReactClass] due to type-checking restrictions
179+
/// for JS-interop classes, so a Function type-check is the best we can do.
148180
bool isPotentiallyValidComponentType(dynamic type) {
149181
return type is Function || type is String;
150182
}
151183

152-
/// Returns an [Iterable] of all component types that are ancestors of [typeAlias].
184+
/// Returns an [Iterable] of all component types that are ancestors of [type].
153185
///
154186
/// For example, given components A, B, and C, where B subtypes A and C subtypes B:
155187
///
156-
/// getParentTypes(getTypeFromAlias(A)); // []
157-
/// getParentTypes(getTypeFromAlias(B)); // [A].map(getTypeFromAlias)
158-
/// getParentTypes(getTypeFromAlias(C)); // [B, A].map(getTypeFromAlias)
188+
/// getParentTypes(getComponentTypeFromAlias(A)); // []
189+
/// getParentTypes(getComponentTypeFromAlias(B)); // [A].map(getTypeFromAlias)
190+
/// getParentTypes(getComponentTypeFromAlias(C)); // [B, A].map(getTypeFromAlias)
159191
Iterable<dynamic> getParentTypes(dynamic type) sync* {
160192
assert(isPotentiallyValidComponentType(type) &&
161193
'`type` should be a valid component type (and not null or a type alias).' is String);
@@ -182,6 +214,8 @@ Iterable<dynamic> getParentTypes(dynamic type) sync* {
182214
/// * [ReactComponentFactoryProxy]
183215
/// * [ReactClass] component factory
184216
/// * [String] tag name (DOM components only)
217+
///
218+
/// > Related: [isValidElementOfType]
185219
bool isComponentOfType(ReactElement instance, dynamic typeAlias, {
186220
bool traverseWrappers: true,
187221
bool matchParentTypes: true
@@ -228,6 +262,8 @@ bool isComponentOfType(ReactElement instance, dynamic typeAlias, {
228262
/// * [ReactComponentFactoryProxy]
229263
/// * [ReactClass] component factory
230264
/// * [String] tag name (DOM components only)
265+
///
266+
/// > Related: [isComponentOfType]
231267
bool isValidElementOfType(dynamic instance, dynamic typeAlias) {
232268
return isValidElement(instance) && isComponentOfType(instance, typeAlias);
233269
}

lib/src/component_declaration/flux_component.dart

+6-2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ abstract class FluxUiProps<ActionsT, StoresT> extends UiProps {
6666
/// the resulting component.
6767
///
6868
/// Use with the over_react transformer via the `@Component()` ([annotations.Component]) annotation.
69+
///
70+
/// > Related: [FluxUiStatefulComponent]
6971
abstract class FluxUiComponent<TProps extends FluxUiProps> extends UiComponent<TProps>
7072
with _FluxComponentMixin<TProps>, BatchedRedraws {
7173
// Redeclare these lifecycle methods with `mustCallSuper`, since `mustCallSuper` added to methods within
@@ -102,6 +104,8 @@ abstract class FluxUiComponent<TProps extends FluxUiProps> extends UiComponent<T
102104
/// the resulting component.
103105
///
104106
/// Use with the over_react transformer via the `@Component()` ([annotations.Component]) annotation.
107+
///
108+
/// > Related: [FluxUiComponent]
105109
abstract class FluxUiStatefulComponent<TProps extends FluxUiProps, TState extends UiState>
106110
extends UiStatefulComponent<TProps, TState>
107111
with _FluxComponentMixin<TProps>, BatchedRedraws {
@@ -156,9 +160,9 @@ abstract class _FluxComponentMixin<TProps extends FluxUiProps> implements Batche
156160

157161
handlers.forEach((store, handler) {
158162
String message = 'Cannot listen to a disposed/disposing Store.';
159-
163+
160164
var isDisposedOrDisposing = store.isDisposedOrDisposing ?? false;
161-
165+
162166
assert(!isDisposedOrDisposing, '$message This can be caused by BatchedRedraws '
163167
'mounting the component asynchronously after the store has been disposed. If you are '
164168
'in a test environment, try adding an `await window.animationFrame;` before disposing your '

lib/src/util/class_names.dart

+31-20
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,25 @@ class CssClassPropsMapView extends MapView with CssClassPropsMixin {
5353
Map get props => this;
5454
}
5555

56-
/// StringBuffer-backed className builder optimized for adding classNames, with support for blacklisting CSS classes.
56+
/// [StringBuffer]-backed CSS className builder optimized for adding classNames,
57+
/// with support for blacklisting CSS classes.
5758
class ClassNameBuilder {
5859
StringBuffer _classNamesBuffer = new StringBuffer();
5960
StringBuffer _blacklistBuffer;
6061

6162
/// Creates a new, empty ClassNameBuilder.
6263
ClassNameBuilder();
6364

64-
/// Creates a new ClassNameBuilder with className and blacklist values added from [CssClassProps.className] and
65-
/// [CssClassProps.classNameBlackList], if they are specified.
65+
/// Creates a new ClassNameBuilder with className and blacklist values added from [CssClassPropsMixin.className] and
66+
/// [CssClassPropsMixin.classNameBlacklist], if they are specified within the provided [props] Map.
6667
///
6768
/// This method gracefully handles null [props], as well as unspecified/null prop values.
6869
ClassNameBuilder.fromProps(Map props) {
6970
addFromProps(props);
7071
}
7172

72-
/// Adds the className and blacklist values from a [props] Map, using the
73-
/// [CssClassProps.className] and [CssClassProps.classNameBlackList] values.
73+
/// Adds the className and blacklist values from the provided [props] Map, using the
74+
/// [CssClassPropsMixin.className] and [CssClassPropsMixin.classNameBlacklist] values.
7475
///
7576
/// This method gracefully handles null [props], as well as unspecified/null prop values.
7677
///
@@ -87,10 +88,12 @@ class ClassNameBuilder {
8788
..blacklist(cssClassProps.classNameBlacklist);
8889
}
8990

90-
/// Adds a className string. May be a single CSS class 'token', or multiple space-delimited classes,
91-
/// IF [should] is true, otherwise, does nothing (convenience for helping to inline addition conditionals).
91+
/// Adds all of the CSS classes represented by [className] _(a space-delimited list)_ to the [_classNamesBuffer] -
92+
/// only if [should] is true.
9293
///
93-
/// There is no checking for duplicate CSS classes.
94+
/// Otherwise, does nothing _(convenience for helping to inline addition conditionals)_.
95+
///
96+
/// > There is no checking for duplicate CSS classes.
9497
void add(String className, [bool should = true]) {
9598
if (!should || className == null || className == '') {
9699
return;
@@ -102,8 +105,10 @@ class ClassNameBuilder {
102105
_classNamesBuffer.write(className);
103106
}
104107

105-
/// Adds all of the CSS classes represented by [className] (a space-delimited list) to the blacklist,
106-
/// IF [should] is true, otherwise, does nothing (convenience for helping to inline blacklisting conditionals).
108+
/// Adds all of the CSS classes represented by [className] _(a space-delimited list)_ to the [_blacklistBuffer] -
109+
/// only if [should] is true.
110+
///
111+
/// Otherwise, does nothing _(convenience for helping to inline blacklisting conditionals)_.
107112
///
108113
/// Classes added to the blacklist will not appear in the result of [toClassName].
109114
void blacklist(String className, [bool should = true]) {
@@ -121,34 +126,40 @@ class ClassNameBuilder {
121126
_blacklistBuffer.write(className);
122127
}
123128

124-
/// Returns a String representation of the built className, which includes any added classes, and none of the blacklisted classes.
129+
/// Returns a String representation of the built className, which includes any added classes,
130+
/// and none of the blacklisted classes.
131+
///
132+
/// > There is no checking for duplicate CSS classes.
125133
///
126-
/// Duplicate classes will be added.
134+
/// > Related: [toClassNameBlacklist]
127135
String toClassName() {
128136
String className = _classNamesBuffer.toString();
129137

130138
if (_blacklistBuffer != null && _blacklistBuffer.isNotEmpty) {
131139
List blacklistedClasses = splitSpaceDelimitedString(_blacklistBuffer.toString());
132140

133141
className = splitSpaceDelimitedString(className)
134-
.where((String cssClass) => !blacklistedClasses.contains(cssClass))
135-
.join(' ');
142+
.where((String cssClass) => !blacklistedClasses.contains(cssClass))
143+
.join(' ');
136144
}
137145

138146
return className;
139147
}
140148

141149
/// Returns a String representation of only the blacklisted classes.
150+
///
142151
/// Useful for blacklist forwarding.
143152
///
144-
/// Duplicate classes will be added.
153+
/// > There is no checking for duplicate CSS classes.
154+
///
155+
/// > Related: [toClassName]
145156
String toClassNameBlacklist() {
146157
return _blacklistBuffer == null || _blacklistBuffer.isEmpty
147-
? null
148-
: _blacklistBuffer.toString();
158+
? null
159+
: _blacklistBuffer.toString();
149160
}
150161

151-
/// Returns a Map with the [CssClassProps.className] and [CssClassProps.classNameBlackList] props
162+
/// Returns a Map with the [CssClassPropsMixin.className] and [CssClassPropsMixin.classNameBlacklist] props
152163
/// populated from the return values of [toClassName] and [toClassNameBlacklist], respectively.
153164
///
154165
/// This method, along with [addFromProps], is useful for merging sets of className/blacklist props.
@@ -164,9 +175,9 @@ class ClassNameBuilder {
164175
}
165176
}
166177

167-
/// Returns a List of space-delimited tokens efficiently split from the specified string.
178+
/// Returns a List of space-delimited tokens efficiently split from the specified [string].
168179
///
169-
/// Useful for splitting CSS class name strings into class tokens, or `data-test-id` values into individual test IDs.
180+
/// Useful for splitting CSS className strings into class tokens, or `data-test-id` values into individual test IDs.
170181
///
171182
/// Handles leading and trailing spaces, as well as token separated by multiple spaces.
172183
///

lib/src/util/css_value_util.dart

+11-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ library over_react.css_value_util;
1616

1717
import 'package:quiver/core.dart';
1818

19-
/// A CSS length value, with a number and unit component, for use in CSS properties such as `width`, `top`, `padding`, etc.
19+
/// A CSS length value, with a number and unit component,
20+
/// for use in CSS properties such as `width`, `top`, `padding`, etc.
2021
class CssValue implements Comparable<CssValue> {
2122
/// The number component of this CSS value.
2223
///
@@ -28,14 +29,20 @@ class CssValue implements Comparable<CssValue> {
2829
/// E.g., 'px' for '1px'
2930
final String unit;
3031

31-
/// Creates a new [CssValue]. If no [unit] is specified, `'px'` is used instead.
32+
/// Creates a new [CssValue].
33+
///
34+
/// If no [unit] is specified, `'px'` is used instead.
3235
const CssValue(this.number, [this.unit = 'px']);
3336

3437
/// Parse [source] and return its [CssValue] representation.
3538
///
36-
/// Accepts a number optionally followed by a CSS length unit. If no unit is present, `'px'` is used as the unit instead.
39+
/// Accepts a number optionally followed by a CSS length unit.
40+
/// If no unit is present, `'px'` is used as the unit instead.
3741
///
38-
/// If `source` is not a valid CSS value, the [onError] callback is called with [source] and an error object, and its return value is used instead. If no `onError` is provided, `null` is returned.
42+
/// If `source` is not a valid CSS value, the [onError] callback
43+
/// is called with [source] and an error object, and its return
44+
/// value is used instead. If no `onError` is provided, `null`
45+
/// is returned.
3946
///
4047
/// Examples of accepted values:
4148
///

lib/src/util/dom_util.dart

+3-4
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Iterable<Element> _hierarchy(Element element) sync* {
3838
}
3939

4040
/// Returns the closest element in the hierarchy of [lowerBound] up to an optional [upperBound] (both inclusive)
41-
/// that matches [selector], or `null if no matches are found.
41+
/// that matches [selector], or `null` if no matches are found.
4242
Element closest(Element lowerBound, String selector, {Element upperBound}) {
4343
for (var element in _hierarchy(lowerBound)) {
4444
if (element.matches(selector)) return element;
@@ -48,7 +48,8 @@ Element closest(Element lowerBound, String selector, {Element upperBound}) {
4848
return null;
4949
}
5050

51-
/// Returns the currently focused element, or `null` if there is none.
51+
/// Returns the currently focused element ([HtmlDocument.activeElement]),
52+
/// or `null` if nothing is focused (e.g. [HtmlDocument.activeElement] is [BodyElement]).
5253
Element getActiveElement() {
5354
var activeElement = document.activeElement;
5455

@@ -62,8 +63,6 @@ Element getActiveElement() {
6263
/// Necessary because of the circular inheritance hierarchy in Dart's [InputElement] class structure.
6364
///
6465
/// See: <https://github.com/dart-lang/sdk/issues/22967>
65-
///
66-
/// Related: [isTextInputElementBase]
6766
const List<String> inputTypesWithSelectionRangeSupport = const [
6867
'search',
6968
'text',

lib/src/util/event_helpers.dart

+13-13
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ library over_react.event_helpers;
1616

1717
import 'dart:html';
1818

19-
import 'package:react/react.dart' as react;
19+
import 'package:over_react/over_react.dart';
2020

21-
/// Helper util that wraps a native [KeyboardEvent] in a [react.SyntheticKeyboardEvent].
21+
/// Helper util that wraps a native [KeyboardEvent] in a [SyntheticKeyboardEvent].
2222
///
23-
/// Used where a native [KeyboardEvent] is given and a [react.SyntheticKeyboardEvent] is needed.
24-
react.SyntheticKeyboardEvent wrapNativeKeyboardEvent(KeyboardEvent nativeKeyboardEvent) {
25-
return new react.SyntheticKeyboardEvent(
23+
/// Used where a native [KeyboardEvent] is given and a [SyntheticKeyboardEvent] is needed.
24+
SyntheticKeyboardEvent wrapNativeKeyboardEvent(KeyboardEvent nativeKeyboardEvent) {
25+
return new SyntheticKeyboardEvent(
2626
nativeKeyboardEvent.bubbles,
2727
nativeKeyboardEvent.cancelable,
2828
nativeKeyboardEvent.currentTarget,
@@ -48,11 +48,11 @@ react.SyntheticKeyboardEvent wrapNativeKeyboardEvent(KeyboardEvent nativeKeyboar
4848
nativeKeyboardEvent.shiftKey);
4949
}
5050

51-
/// Helper util that wraps a native [MouseEvent] in a [react.MouseEvent].
51+
/// Helper util that wraps a native [MouseEvent] in a [SyntheticMouseEvent].
5252
///
53-
/// Used where a native [MouseEvent] is given and a [react.MouseEvent] is needed.
54-
react.SyntheticMouseEvent wrapNativeMouseEvent(MouseEvent nativeMouseEvent) {
55-
return new react.SyntheticMouseEvent(
53+
/// Used where a native [MouseEvent] is given and a [SyntheticMouseEvent] is needed.
54+
SyntheticMouseEvent wrapNativeMouseEvent(MouseEvent nativeMouseEvent) {
55+
return new SyntheticMouseEvent(
5656
nativeMouseEvent.bubbles,
5757
nativeMouseEvent.cancelable,
5858
nativeMouseEvent.currentTarget,
@@ -83,12 +83,12 @@ react.SyntheticMouseEvent wrapNativeMouseEvent(MouseEvent nativeMouseEvent) {
8383
}
8484

8585
/// If the consumer specifies a callback like `onChange` on one of our custom form components that are not *actually*
86-
/// form elements - we still need a valid [react.SyntheticFormEvent] to pass as the expected parameter to that callback.
86+
/// form elements - we still need a valid [SyntheticFormEvent] to pass as the expected parameter to that callback.
8787
///
88-
/// This helper method generates a "fake" [react.SyntheticFormEvent], with nothing but the `target` set to [element],
88+
/// This helper method generates a "fake" [SyntheticFormEvent], with nothing but the `target` set to [element],
8989
/// `type` set to [type] and `timeStamp` set to the current time. All other arguments are `noop`, `false` or `null`.
90-
react.SyntheticFormEvent fakeSyntheticFormEvent(Element element, String type) {
91-
return new react.SyntheticFormEvent(
90+
SyntheticFormEvent fakeSyntheticFormEvent(Element element, String type) {
91+
return new SyntheticFormEvent(
9292
false,
9393
false,
9494
element,

0 commit comments

Comments
 (0)