mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Use curly_braces_in_flow_control_structures for services, scheduler, semantics (#104616)
This commit is contained in:
parent
e71eb183d8
commit
a0248ebdf2
@ -25,8 +25,9 @@ double _timeDilation = 1.0;
|
||||
/// It is safe to set this before initializing the binding.
|
||||
set timeDilation(double value) {
|
||||
assert(value > 0.0);
|
||||
if (_timeDilation == value)
|
||||
if (_timeDilation == value) {
|
||||
return;
|
||||
}
|
||||
// If the binding has been created, we need to resetEpoch first so that we
|
||||
// capture start of the epoch with the current time dilation.
|
||||
SchedulerBinding._instance?.resetEpoch();
|
||||
@ -409,16 +410,18 @@ mixin SchedulerBinding on BindingBase {
|
||||
flow,
|
||||
);
|
||||
_taskQueue.add(entry);
|
||||
if (isFirstTask && !locked)
|
||||
if (isFirstTask && !locked) {
|
||||
_ensureEventLoopCallback();
|
||||
}
|
||||
return entry.completer.future;
|
||||
}
|
||||
|
||||
@override
|
||||
void unlocked() {
|
||||
super.unlocked();
|
||||
if (_taskQueue.isNotEmpty)
|
||||
if (_taskQueue.isNotEmpty) {
|
||||
_ensureEventLoopCallback();
|
||||
}
|
||||
}
|
||||
|
||||
// Whether this scheduler already requested to be called from the event loop.
|
||||
@ -429,8 +432,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
void _ensureEventLoopCallback() {
|
||||
assert(!locked);
|
||||
assert(_taskQueue.isNotEmpty);
|
||||
if (_hasRequestedAnEventLoopCallback)
|
||||
if (_hasRequestedAnEventLoopCallback) {
|
||||
return;
|
||||
}
|
||||
_hasRequestedAnEventLoopCallback = true;
|
||||
Timer.run(_runTasks);
|
||||
}
|
||||
@ -438,8 +442,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
// Scheduled by _ensureEventLoopCallback.
|
||||
void _runTasks() {
|
||||
_hasRequestedAnEventLoopCallback = false;
|
||||
if (handleEventLoopCallback())
|
||||
_ensureEventLoopCallback(); // runs next task when there's time
|
||||
if (handleEventLoopCallback()) {
|
||||
_ensureEventLoopCallback();
|
||||
} // runs next task when there's time
|
||||
}
|
||||
|
||||
/// Execute the highest-priority task, if it is of a high enough priority.
|
||||
@ -455,8 +460,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
@visibleForTesting
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
bool handleEventLoopCallback() {
|
||||
if (_taskQueue.isEmpty || locked)
|
||||
if (_taskQueue.isEmpty || locked) {
|
||||
return false;
|
||||
}
|
||||
final _TaskEntry<dynamic> entry = _taskQueue.first;
|
||||
if (schedulingStrategy(priority: entry.priority, scheduler: this)) {
|
||||
try {
|
||||
@ -690,8 +696,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
/// off.
|
||||
Future<void> get endOfFrame {
|
||||
if (_nextFrameCompleter == null) {
|
||||
if (schedulerPhase == SchedulerPhase.idle)
|
||||
if (schedulerPhase == SchedulerPhase.idle) {
|
||||
scheduleFrame();
|
||||
}
|
||||
_nextFrameCompleter = Completer<void>();
|
||||
addPostFrameCallback((Duration timeStamp) {
|
||||
_nextFrameCompleter!.complete();
|
||||
@ -716,11 +723,13 @@ mixin SchedulerBinding on BindingBase {
|
||||
|
||||
bool _framesEnabled = true;
|
||||
void _setFramesEnabledState(bool enabled) {
|
||||
if (_framesEnabled == enabled)
|
||||
if (_framesEnabled == enabled) {
|
||||
return;
|
||||
}
|
||||
_framesEnabled = enabled;
|
||||
if (enabled)
|
||||
if (enabled) {
|
||||
scheduleFrame();
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures callbacks for [PlatformDispatcher.onBeginFrame] and
|
||||
@ -785,11 +794,13 @@ mixin SchedulerBinding on BindingBase {
|
||||
/// * [scheduleWarmUpFrame], which ignores the "Vsync" signal entirely and
|
||||
/// triggers a frame immediately.
|
||||
void scheduleFrame() {
|
||||
if (_hasScheduledFrame || !framesEnabled)
|
||||
if (_hasScheduledFrame || !framesEnabled) {
|
||||
return;
|
||||
}
|
||||
assert(() {
|
||||
if (debugPrintScheduleFrameStacks)
|
||||
if (debugPrintScheduleFrameStacks) {
|
||||
debugPrintStack(label: 'scheduleFrame() called. Current phase is $schedulerPhase.');
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
ensureFrameCallbacksRegistered();
|
||||
@ -818,11 +829,13 @@ mixin SchedulerBinding on BindingBase {
|
||||
/// Consider using [scheduleWarmUpFrame] instead if the goal is to update the
|
||||
/// rendering as soon as possible (e.g. at application startup).
|
||||
void scheduleForcedFrame() {
|
||||
if (_hasScheduledFrame)
|
||||
if (_hasScheduledFrame) {
|
||||
return;
|
||||
}
|
||||
assert(() {
|
||||
if (debugPrintScheduleFrameStacks)
|
||||
if (debugPrintScheduleFrameStacks) {
|
||||
debugPrintStack(label: 'scheduleForcedFrame() called. Current phase is $schedulerPhase.');
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
ensureFrameCallbacksRegistered();
|
||||
@ -848,8 +861,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
///
|
||||
/// Prefer [scheduleFrame] to update the display in normal operation.
|
||||
void scheduleWarmUpFrame() {
|
||||
if (_warmUpFrame || schedulerPhase != SchedulerPhase.idle)
|
||||
if (_warmUpFrame || schedulerPhase != SchedulerPhase.idle) {
|
||||
return;
|
||||
}
|
||||
|
||||
_warmUpFrame = true;
|
||||
final TimelineTask timelineTask = TimelineTask()..start('Warm-up frame');
|
||||
@ -872,8 +886,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
// then skipping every frame and finishing in the new time.
|
||||
resetEpoch();
|
||||
_warmUpFrame = false;
|
||||
if (hadScheduledFrame)
|
||||
if (hadScheduledFrame) {
|
||||
scheduleFrame();
|
||||
}
|
||||
});
|
||||
|
||||
// Lock events so touch events etc don't insert themselves until the
|
||||
@ -1026,8 +1041,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
_frameTimelineTask?.start('Frame');
|
||||
_firstRawTimeStampInEpoch ??= rawTimeStamp;
|
||||
_currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp);
|
||||
if (rawTimeStamp != null)
|
||||
if (rawTimeStamp != null) {
|
||||
_lastRawTimeStamp = rawTimeStamp;
|
||||
}
|
||||
|
||||
assert(() {
|
||||
_debugFrameNumber += 1;
|
||||
@ -1040,8 +1056,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
frameTimeStampDescription.write('(warm-up frame)');
|
||||
}
|
||||
_debugBanner = '▄▄▄▄▄▄▄▄ Frame ${_debugFrameNumber.toString().padRight(7)} ${frameTimeStampDescription.toString().padLeft(18)} ▄▄▄▄▄▄▄▄';
|
||||
if (debugPrintBeginFrameBanner)
|
||||
if (debugPrintBeginFrameBanner) {
|
||||
debugPrint(_debugBanner);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
@ -1055,8 +1072,9 @@ mixin SchedulerBinding on BindingBase {
|
||||
final Map<int, _FrameCallbackEntry> callbacks = _transientCallbacks;
|
||||
_transientCallbacks = <int, _FrameCallbackEntry>{};
|
||||
callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) {
|
||||
if (!_removedIds.contains(id))
|
||||
if (!_removedIds.contains(id)) {
|
||||
_invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp!, callbackEntry.debugStack);
|
||||
}
|
||||
});
|
||||
_removedIds.clear();
|
||||
} finally {
|
||||
@ -1079,22 +1097,25 @@ mixin SchedulerBinding on BindingBase {
|
||||
try {
|
||||
// PERSISTENT FRAME CALLBACKS
|
||||
_schedulerPhase = SchedulerPhase.persistentCallbacks;
|
||||
for (final FrameCallback callback in _persistentCallbacks)
|
||||
for (final FrameCallback callback in _persistentCallbacks) {
|
||||
_invokeFrameCallback(callback, _currentFrameTimeStamp!);
|
||||
}
|
||||
|
||||
// POST-FRAME CALLBACKS
|
||||
_schedulerPhase = SchedulerPhase.postFrameCallbacks;
|
||||
final List<FrameCallback> localPostFrameCallbacks =
|
||||
List<FrameCallback>.of(_postFrameCallbacks);
|
||||
_postFrameCallbacks.clear();
|
||||
for (final FrameCallback callback in localPostFrameCallbacks)
|
||||
for (final FrameCallback callback in localPostFrameCallbacks) {
|
||||
_invokeFrameCallback(callback, _currentFrameTimeStamp!);
|
||||
}
|
||||
} finally {
|
||||
_schedulerPhase = SchedulerPhase.idle;
|
||||
_frameTimelineTask?.finish(); // end the Frame
|
||||
assert(() {
|
||||
if (debugPrintEndFrameBanner)
|
||||
if (debugPrintEndFrameBanner) {
|
||||
debugPrint('▀' * _debugBanner!.length);
|
||||
}
|
||||
_debugBanner = null;
|
||||
return true;
|
||||
}());
|
||||
@ -1114,18 +1135,23 @@ mixin SchedulerBinding on BindingBase {
|
||||
}
|
||||
|
||||
static void _debugDescribeTimeStamp(Duration timeStamp, StringBuffer buffer) {
|
||||
if (timeStamp.inDays > 0)
|
||||
if (timeStamp.inDays > 0) {
|
||||
buffer.write('${timeStamp.inDays}d ');
|
||||
if (timeStamp.inHours > 0)
|
||||
}
|
||||
if (timeStamp.inHours > 0) {
|
||||
buffer.write('${timeStamp.inHours - timeStamp.inDays * Duration.hoursPerDay}h ');
|
||||
if (timeStamp.inMinutes > 0)
|
||||
}
|
||||
if (timeStamp.inMinutes > 0) {
|
||||
buffer.write('${timeStamp.inMinutes - timeStamp.inHours * Duration.minutesPerHour}m ');
|
||||
if (timeStamp.inSeconds > 0)
|
||||
}
|
||||
if (timeStamp.inSeconds > 0) {
|
||||
buffer.write('${timeStamp.inSeconds - timeStamp.inMinutes * Duration.secondsPerMinute}s ');
|
||||
}
|
||||
buffer.write('${timeStamp.inMilliseconds - timeStamp.inSeconds * Duration.millisecondsPerSecond}');
|
||||
final int microseconds = timeStamp.inMicroseconds - timeStamp.inMilliseconds * Duration.microsecondsPerMillisecond;
|
||||
if (microseconds > 0)
|
||||
if (microseconds > 0) {
|
||||
buffer.write('.${microseconds.toString().padLeft(3, "0")}');
|
||||
}
|
||||
buffer.write('ms');
|
||||
}
|
||||
|
||||
@ -1175,7 +1201,8 @@ mixin SchedulerBinding on BindingBase {
|
||||
/// a [Priority] of [Priority.animation] or higher. Otherwise, runs
|
||||
/// all tasks.
|
||||
bool defaultSchedulingStrategy({ required int priority, required SchedulerBinding scheduler }) {
|
||||
if (scheduler.transientCallbackCount > 0)
|
||||
if (scheduler.transientCallbackCount > 0) {
|
||||
return priority >= Priority.animation.value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -88,8 +88,9 @@ class Ticker {
|
||||
/// created the [Ticker] (typically a [TickerProvider]), not the object that
|
||||
/// listens to the ticker's ticks.
|
||||
set muted(bool value) {
|
||||
if (value == muted)
|
||||
if (value == muted) {
|
||||
return;
|
||||
}
|
||||
_muted = value;
|
||||
if (value) {
|
||||
unscheduleTick();
|
||||
@ -109,14 +110,18 @@ class Ticker {
|
||||
/// that indicates the application is not currently visible (e.g. if the
|
||||
/// device's screen is turned off).
|
||||
bool get isTicking {
|
||||
if (_future == null)
|
||||
if (_future == null) {
|
||||
return false;
|
||||
if (muted)
|
||||
}
|
||||
if (muted) {
|
||||
return false;
|
||||
if (SchedulerBinding.instance.framesEnabled)
|
||||
}
|
||||
if (SchedulerBinding.instance.framesEnabled) {
|
||||
return true;
|
||||
if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle)
|
||||
return true; // for example, we might be in a warm-up frame or forced frame
|
||||
}
|
||||
if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle) {
|
||||
return true;
|
||||
} // for example, we might be in a warm-up frame or forced frame
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -162,8 +167,9 @@ class Ticker {
|
||||
scheduleTick();
|
||||
}
|
||||
if (SchedulerBinding.instance.schedulerPhase.index > SchedulerPhase.idle.index &&
|
||||
SchedulerBinding.instance.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index)
|
||||
SchedulerBinding.instance.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index) {
|
||||
_startTime = SchedulerBinding.instance.currentFrameTimeStamp;
|
||||
}
|
||||
return _future!;
|
||||
}
|
||||
|
||||
@ -189,8 +195,9 @@ class Ticker {
|
||||
/// By convention, this method is used by the object that receives the ticks
|
||||
/// (as opposed to the [TickerProvider] which created the ticker).
|
||||
void stop({ bool canceled = false }) {
|
||||
if (!isActive)
|
||||
if (!isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We take the _future into a local variable so that isTicking is false
|
||||
// when we actually complete the future (isTicking uses _future to
|
||||
@ -239,8 +246,9 @@ class Ticker {
|
||||
|
||||
// The onTick callback may have scheduled another tick already, for
|
||||
// example by calling stop then start again.
|
||||
if (shouldScheduleTick)
|
||||
if (shouldScheduleTick) {
|
||||
scheduleTick(rescheduling: true);
|
||||
}
|
||||
}
|
||||
|
||||
/// Schedules a tick for the next frame.
|
||||
@ -286,8 +294,9 @@ class Ticker {
|
||||
if (originalTicker._future != null) {
|
||||
_future = originalTicker._future;
|
||||
_startTime = originalTicker._startTime;
|
||||
if (shouldScheduleTick)
|
||||
if (shouldScheduleTick) {
|
||||
scheduleTick();
|
||||
}
|
||||
originalTicker._future = null; // so that it doesn't get disposed when we dispose of originalTicker
|
||||
originalTicker.unscheduleTick();
|
||||
}
|
||||
@ -474,8 +483,9 @@ class TickerCanceled implements Exception {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
if (ticker != null)
|
||||
if (ticker != null) {
|
||||
return 'This ticker was canceled: $ticker';
|
||||
}
|
||||
return 'The ticker was canceled before the "orCancel" property was first used.';
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,8 +64,9 @@ mixin SemanticsBinding on BindingBase {
|
||||
bool get disableAnimations {
|
||||
bool value = _accessibilityFeatures.disableAnimations;
|
||||
assert(() {
|
||||
if (debugSemanticsDisableAnimations != null)
|
||||
if (debugSemanticsDisableAnimations != null) {
|
||||
value = debugSemanticsDisableAnimations!;
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
return value;
|
||||
|
||||
@ -134,8 +134,9 @@ class CustomSemanticsAction {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is CustomSemanticsAction
|
||||
&& other.label == label
|
||||
&& other.hint == hint
|
||||
@ -278,8 +279,9 @@ class AttributedStringProperty extends DiagnosticsProperty<AttributedString> {
|
||||
|
||||
@override
|
||||
String valueToString({TextTreeConfiguration? parentConfiguration}) {
|
||||
if (value == null)
|
||||
if (value == null) {
|
||||
return 'null';
|
||||
}
|
||||
String text = value!.string;
|
||||
if (parentConfiguration != null &&
|
||||
!parentConfiguration.lineBreakProperties) {
|
||||
@ -596,8 +598,9 @@ class SemanticsData with Diagnosticable {
|
||||
properties.add(AttributedStringProperty('hint', attributedHint));
|
||||
properties.add(StringProperty('tooltip', tooltip, defaultValue: ''));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
|
||||
if (textSelection?.isValid ?? false)
|
||||
if (textSelection?.isValid ?? false) {
|
||||
properties.add(MessageProperty('textSelection', '[${textSelection!.start}, ${textSelection!.end}]'));
|
||||
}
|
||||
properties.add(IntProperty('platformViewId', platformViewId, defaultValue: null));
|
||||
properties.add(IntProperty('maxValueLength', maxValueLength, defaultValue: null));
|
||||
properties.add(IntProperty('currentValueLength', currentValueLength, defaultValue: null));
|
||||
@ -668,14 +671,18 @@ class SemanticsData with Diagnosticable {
|
||||
);
|
||||
|
||||
static bool _sortedListsEqual(List<int>? left, List<int>? right) {
|
||||
if (left == null && right == null)
|
||||
if (left == null && right == null) {
|
||||
return true;
|
||||
}
|
||||
if (left != null && right != null) {
|
||||
if (left.length != right.length)
|
||||
if (left.length != right.length) {
|
||||
return false;
|
||||
for (int i = 0; i < left.length; i++)
|
||||
if (left[i] != right[i])
|
||||
}
|
||||
for (int i = 0; i < left.length; i++) {
|
||||
if (left[i] != right[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -739,8 +746,9 @@ class SemanticsHintOverrides extends DiagnosticableTree {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is SemanticsHintOverrides
|
||||
&& other.onTapHint == onTapHint
|
||||
&& other.onLongPressHint == onLongPressHint;
|
||||
@ -1675,8 +1683,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
bool _isMergedIntoParent = false;
|
||||
set isMergedIntoParent(bool value) {
|
||||
assert(value != null);
|
||||
if (_isMergedIntoParent == value)
|
||||
if (_isMergedIntoParent == value) {
|
||||
return;
|
||||
}
|
||||
_isMergedIntoParent = value;
|
||||
_markDirty();
|
||||
}
|
||||
@ -1743,22 +1752,25 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
_debugPreviousSnapshot = List<SemanticsNode>.of(newChildren);
|
||||
|
||||
SemanticsNode ancestor = this;
|
||||
while (ancestor.parent is SemanticsNode)
|
||||
while (ancestor.parent is SemanticsNode) {
|
||||
ancestor = ancestor.parent!;
|
||||
}
|
||||
assert(!newChildren.any((SemanticsNode child) => child == ancestor));
|
||||
return true;
|
||||
}());
|
||||
assert(() {
|
||||
final Set<SemanticsNode> seenChildren = <SemanticsNode>{};
|
||||
for (final SemanticsNode child in newChildren)
|
||||
assert(seenChildren.add(child)); // check for duplicate adds
|
||||
for (final SemanticsNode child in newChildren) {
|
||||
assert(seenChildren.add(child));
|
||||
} // check for duplicate adds
|
||||
return true;
|
||||
}());
|
||||
|
||||
// The goal of this function is updating sawChange.
|
||||
if (_children != null) {
|
||||
for (final SemanticsNode child in _children!)
|
||||
for (final SemanticsNode child in _children!) {
|
||||
child._dead = true;
|
||||
}
|
||||
}
|
||||
for (final SemanticsNode child in newChildren) {
|
||||
assert(!child.isInvisible, 'Child $child is invisible and should not be added as a child of $this.');
|
||||
@ -1804,8 +1816,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
}
|
||||
}
|
||||
_children = newChildren;
|
||||
if (sawChange)
|
||||
if (sawChange) {
|
||||
_markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether this node has a non-zero number of children.
|
||||
@ -1823,8 +1836,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
void visitChildren(SemanticsNodeVisitor visitor) {
|
||||
if (_children != null) {
|
||||
for (final SemanticsNode child in _children!) {
|
||||
if (!visitor(child))
|
||||
if (!visitor(child)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1837,8 +1851,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
bool _visitDescendants(SemanticsNodeVisitor visitor) {
|
||||
if (_children != null) {
|
||||
for (final SemanticsNode child in _children!) {
|
||||
if (!visitor(child) || !child._visitDescendants(visitor))
|
||||
if (!visitor(child) || !child._visitDescendants(visitor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -1872,8 +1887,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
_markDirty();
|
||||
}
|
||||
if (_children != null) {
|
||||
for (final SemanticsNode child in _children!)
|
||||
for (final SemanticsNode child in _children!) {
|
||||
child.attach(owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1889,8 +1905,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
for (final SemanticsNode child in _children!) {
|
||||
// The list of children may be stale and may contain nodes that have
|
||||
// been assigned to a different parent.
|
||||
if (child.parent == this)
|
||||
if (child.parent == this) {
|
||||
child.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
// The other side will have forgotten this node if we ever send
|
||||
@ -1903,8 +1920,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
|
||||
bool _dirty = false;
|
||||
void _markDirty() {
|
||||
if (_dirty)
|
||||
if (_dirty) {
|
||||
return;
|
||||
}
|
||||
_dirty = true;
|
||||
if (attached) {
|
||||
assert(!owner!._detachedNodes.contains(this));
|
||||
@ -2250,8 +2268,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
List<SemanticsNode>? childrenInInversePaintOrder,
|
||||
}) {
|
||||
config ??= _kEmptyConfig;
|
||||
if (_isDifferentFromCurrentSemanticAnnotation(config))
|
||||
if (_isDifferentFromCurrentSemanticAnnotation(config)) {
|
||||
_markDirty();
|
||||
}
|
||||
|
||||
assert(
|
||||
config.platformViewId == null || childrenInInversePaintOrder == null || childrenInInversePaintOrder.isEmpty,
|
||||
@ -2326,8 +2345,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
final double elevation = _elevation;
|
||||
double thickness = _thickness;
|
||||
final Set<int> customSemanticsActionIds = <int>{};
|
||||
for (final CustomSemanticsAction action in _customSemanticsActions.keys)
|
||||
for (final CustomSemanticsAction action in _customSemanticsActions.keys) {
|
||||
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
|
||||
}
|
||||
if (hintOverrides != null) {
|
||||
if (hintOverrides!.onTapHint != null) {
|
||||
final CustomSemanticsAction action = CustomSemanticsAction.overridingAction(
|
||||
@ -2360,20 +2380,25 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
platformViewId ??= node._platformViewId;
|
||||
maxValueLength ??= node._maxValueLength;
|
||||
currentValueLength ??= node._currentValueLength;
|
||||
if (attributedValue == null || attributedValue.string == '')
|
||||
if (attributedValue == null || attributedValue.string == '') {
|
||||
attributedValue = node._attributedValue;
|
||||
if (attributedIncreasedValue == null || attributedIncreasedValue.string == '')
|
||||
}
|
||||
if (attributedIncreasedValue == null || attributedIncreasedValue.string == '') {
|
||||
attributedIncreasedValue = node._attributedIncreasedValue;
|
||||
if (attributedDecreasedValue == null || attributedDecreasedValue.string == '')
|
||||
}
|
||||
if (attributedDecreasedValue == null || attributedDecreasedValue.string == '') {
|
||||
attributedDecreasedValue = node._attributedDecreasedValue;
|
||||
if (tooltip == '')
|
||||
}
|
||||
if (tooltip == '') {
|
||||
tooltip = node._tooltip;
|
||||
}
|
||||
if (node.tags != null) {
|
||||
mergedTags ??= <SemanticsTag>{};
|
||||
mergedTags!.addAll(node.tags!);
|
||||
}
|
||||
for (final CustomSemanticsAction action in _customSemanticsActions.keys)
|
||||
for (final CustomSemanticsAction action in _customSemanticsActions.keys) {
|
||||
customSemanticsActionIds.add(CustomSemanticsAction.getIdentifier(action));
|
||||
}
|
||||
if (node.hintOverrides != null) {
|
||||
if (node.hintOverrides!.onTapHint != null) {
|
||||
final CustomSemanticsAction action = CustomSemanticsAction.overridingAction(
|
||||
@ -2579,8 +2604,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
/// Semantics events should be sent to inform interested parties (like
|
||||
/// the accessibility system of the operating system) about changes to the UI.
|
||||
void sendEvent(SemanticsEvent event) {
|
||||
if (!attached)
|
||||
if (!attached) {
|
||||
return;
|
||||
}
|
||||
SystemChannels.accessibility.send(event.toMap(nodeId: id));
|
||||
}
|
||||
|
||||
@ -2632,8 +2658,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
properties.add(StringProperty('tooltip', _tooltip, defaultValue: ''));
|
||||
properties.add(EnumProperty<TextDirection>('textDirection', _textDirection, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<SemanticsSortKey>('sortKey', sortKey, defaultValue: null));
|
||||
if (_textSelection?.isValid ?? false)
|
||||
if (_textSelection?.isValid ?? false) {
|
||||
properties.add(MessageProperty('text selection', '[${_textSelection!.start}, ${_textSelection!.end}]'));
|
||||
}
|
||||
properties.add(IntProperty('platformViewId', platformViewId, defaultValue: null));
|
||||
properties.add(IntProperty('maxValueLength', maxValueLength, defaultValue: null));
|
||||
properties.add(IntProperty('currentValueLength', currentValueLength, defaultValue: null));
|
||||
@ -2685,8 +2712,9 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
|
||||
/// Returns the list of direct children of this node in the specified order.
|
||||
List<SemanticsNode> debugListChildrenInOrder(DebugSemanticsDumpOrder childOrder) {
|
||||
assert(childOrder != null);
|
||||
if (_children == null)
|
||||
if (_children == null) {
|
||||
return const <SemanticsNode>[];
|
||||
}
|
||||
|
||||
switch (childOrder) {
|
||||
case DebugSemanticsDumpOrder.inverseHitTest:
|
||||
@ -3022,8 +3050,9 @@ class SemanticsOwner extends ChangeNotifier {
|
||||
|
||||
/// Update the semantics using [dart:ui.PlatformDispatcher.updateSemantics].
|
||||
void sendSemanticsUpdate() {
|
||||
if (_dirtyNodes.isEmpty)
|
||||
if (_dirtyNodes.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final Set<int> customSemanticsActionIds = <int>{};
|
||||
final List<SemanticsNode> visitedNodes = <SemanticsNode>[];
|
||||
while (_dirtyNodes.isNotEmpty) {
|
||||
@ -3059,8 +3088,9 @@ class SemanticsOwner extends ChangeNotifier {
|
||||
// calls reset() on its SemanticsNode if onlyChanges isn't set,
|
||||
// which happens e.g. when the node is no longer contributing
|
||||
// semantics).
|
||||
if (node._dirty && node.attached)
|
||||
if (node._dirty && node.attached) {
|
||||
node._addToUpdate(builder, customSemanticsActionIds);
|
||||
}
|
||||
}
|
||||
_dirtyNodes.clear();
|
||||
for (final int actionId in customSemanticsActionIds) {
|
||||
@ -3082,8 +3112,9 @@ class SemanticsOwner extends ChangeNotifier {
|
||||
return true; // continue walk
|
||||
});
|
||||
}
|
||||
if (result == null || !result!._canPerformAction(action))
|
||||
if (result == null || !result!._canPerformAction(action)) {
|
||||
return null;
|
||||
}
|
||||
return result!._actions[action];
|
||||
}
|
||||
|
||||
@ -3103,19 +3134,22 @@ class SemanticsOwner extends ChangeNotifier {
|
||||
}
|
||||
|
||||
// Default actions if no [handler] was provided.
|
||||
if (action == SemanticsAction.showOnScreen && _nodes[id]!._showOnScreen != null)
|
||||
if (action == SemanticsAction.showOnScreen && _nodes[id]!._showOnScreen != null) {
|
||||
_nodes[id]!._showOnScreen!();
|
||||
}
|
||||
}
|
||||
|
||||
SemanticsActionHandler? _getSemanticsActionHandlerForPosition(SemanticsNode node, Offset position, SemanticsAction action) {
|
||||
if (node.transform != null) {
|
||||
final Matrix4 inverse = Matrix4.identity();
|
||||
if (inverse.copyInverse(node.transform!) == 0.0)
|
||||
if (inverse.copyInverse(node.transform!) == 0.0) {
|
||||
return null;
|
||||
}
|
||||
position = MatrixUtils.transformPoint(inverse, position);
|
||||
}
|
||||
if (!node.rect.contains(position))
|
||||
if (!node.rect.contains(position)) {
|
||||
return null;
|
||||
}
|
||||
if (node.mergeAllDescendantsIntoThisNode) {
|
||||
SemanticsNode? result;
|
||||
node._visitDescendants((SemanticsNode child) {
|
||||
@ -3130,8 +3164,9 @@ class SemanticsOwner extends ChangeNotifier {
|
||||
if (node.hasChildren) {
|
||||
for (final SemanticsNode child in node._children!.reversed) {
|
||||
final SemanticsActionHandler? handler = _getSemanticsActionHandlerForPosition(child, position, action);
|
||||
if (handler != null)
|
||||
if (handler != null) {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node._actions[action];
|
||||
@ -3147,11 +3182,13 @@ class SemanticsOwner extends ChangeNotifier {
|
||||
void performActionAt(Offset position, SemanticsAction action, [ Object? args ]) {
|
||||
assert(action != null);
|
||||
final SemanticsNode? node = rootSemanticsNode;
|
||||
if (node == null)
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
final SemanticsActionHandler? handler = _getSemanticsActionHandlerForPosition(node, position, action);
|
||||
if (handler != null)
|
||||
if (handler != null) {
|
||||
handler(args);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@ -3691,8 +3728,9 @@ class SemanticsConfiguration {
|
||||
int? get scrollChildCount => _scrollChildCount;
|
||||
int? _scrollChildCount;
|
||||
set scrollChildCount(int? value) {
|
||||
if (value == scrollChildCount)
|
||||
if (value == scrollChildCount) {
|
||||
return;
|
||||
}
|
||||
_scrollChildCount = value;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
@ -3702,8 +3740,9 @@ class SemanticsConfiguration {
|
||||
int? get scrollIndex => _scrollIndex;
|
||||
int? _scrollIndex;
|
||||
set scrollIndex(int? value) {
|
||||
if (value == scrollIndex)
|
||||
if (value == scrollIndex) {
|
||||
return;
|
||||
}
|
||||
_scrollIndex = value;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
@ -3713,8 +3752,9 @@ class SemanticsConfiguration {
|
||||
int? get platformViewId => _platformViewId;
|
||||
int? _platformViewId;
|
||||
set platformViewId(int? value) {
|
||||
if (value == platformViewId)
|
||||
if (value == platformViewId) {
|
||||
return;
|
||||
}
|
||||
_platformViewId = value;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
@ -3730,8 +3770,9 @@ class SemanticsConfiguration {
|
||||
int? get maxValueLength => _maxValueLength;
|
||||
int? _maxValueLength;
|
||||
set maxValueLength(int? value) {
|
||||
if (value == maxValueLength)
|
||||
if (value == maxValueLength) {
|
||||
return;
|
||||
}
|
||||
_maxValueLength = value;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
@ -3747,8 +3788,9 @@ class SemanticsConfiguration {
|
||||
int? get currentValueLength => _currentValueLength;
|
||||
int? _currentValueLength;
|
||||
set currentValueLength(int? value) {
|
||||
if (value == currentValueLength)
|
||||
if (value == currentValueLength) {
|
||||
return;
|
||||
}
|
||||
_currentValueLength = value;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
@ -3786,11 +3828,13 @@ class SemanticsConfiguration {
|
||||
|
||||
void _onCustomSemanticsAction(Object? args) {
|
||||
final CustomSemanticsAction? action = CustomSemanticsAction.getAction(args! as int);
|
||||
if (action == null)
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
final VoidCallback? callback = _customSemanticsActions[action];
|
||||
if (callback != null)
|
||||
if (callback != null) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
/// A textual description of the owning [RenderObject].
|
||||
@ -4005,8 +4049,9 @@ class SemanticsConfiguration {
|
||||
SemanticsHintOverrides? get hintOverrides => _hintOverrides;
|
||||
SemanticsHintOverrides? _hintOverrides;
|
||||
set hintOverrides(SemanticsHintOverrides? value) {
|
||||
if (value == null)
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
_hintOverrides = value;
|
||||
_hasBeenAnnotated = true;
|
||||
}
|
||||
@ -4392,12 +4437,15 @@ class SemanticsConfiguration {
|
||||
/// Two configurations are said to be compatible if they can be added to the
|
||||
/// same [SemanticsNode] without losing any semantics information.
|
||||
bool isCompatibleWith(SemanticsConfiguration? other) {
|
||||
if (other == null || !other.hasBeenAnnotated || !hasBeenAnnotated)
|
||||
if (other == null || !other.hasBeenAnnotated || !hasBeenAnnotated) {
|
||||
return true;
|
||||
if (_actionsAsBits & other._actionsAsBits != 0)
|
||||
}
|
||||
if (_actionsAsBits & other._actionsAsBits != 0) {
|
||||
return false;
|
||||
if ((_flags & other._flags) != 0)
|
||||
}
|
||||
if ((_flags & other._flags) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (_platformViewId != null && other._platformViewId != null) {
|
||||
return false;
|
||||
}
|
||||
@ -4407,8 +4455,9 @@ class SemanticsConfiguration {
|
||||
if (_currentValueLength != null && other._currentValueLength != null) {
|
||||
return false;
|
||||
}
|
||||
if (_attributedValue != null && _attributedValue.string.isNotEmpty && other._attributedValue != null && other._attributedValue.string.isNotEmpty)
|
||||
if (_attributedValue != null && _attributedValue.string.isNotEmpty && other._attributedValue != null && other._attributedValue.string.isNotEmpty) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4426,8 +4475,9 @@ class SemanticsConfiguration {
|
||||
void absorb(SemanticsConfiguration child) {
|
||||
assert(!explicitChildNodes);
|
||||
|
||||
if (!child.hasBeenAnnotated)
|
||||
if (!child.hasBeenAnnotated) {
|
||||
return;
|
||||
}
|
||||
|
||||
_actions.addAll(child._actions);
|
||||
_customSemanticsActions.addAll(child._customSemanticsActions);
|
||||
@ -4453,20 +4503,24 @@ class SemanticsConfiguration {
|
||||
otherAttributedString: child._attributedLabel,
|
||||
otherTextDirection: child.textDirection,
|
||||
);
|
||||
if (_attributedValue == null || _attributedValue.string == '')
|
||||
if (_attributedValue == null || _attributedValue.string == '') {
|
||||
_attributedValue = child._attributedValue;
|
||||
if (_attributedIncreasedValue == null || _attributedIncreasedValue.string == '')
|
||||
}
|
||||
if (_attributedIncreasedValue == null || _attributedIncreasedValue.string == '') {
|
||||
_attributedIncreasedValue = child._attributedIncreasedValue;
|
||||
if (_attributedDecreasedValue == null || _attributedDecreasedValue.string == '')
|
||||
}
|
||||
if (_attributedDecreasedValue == null || _attributedDecreasedValue.string == '') {
|
||||
_attributedDecreasedValue = child._attributedDecreasedValue;
|
||||
}
|
||||
_attributedHint = _concatAttributedString(
|
||||
thisAttributedString: _attributedHint,
|
||||
thisTextDirection: textDirection,
|
||||
otherAttributedString: child._attributedHint,
|
||||
otherTextDirection: child.textDirection,
|
||||
);
|
||||
if (_tooltip == '')
|
||||
if (_tooltip == '') {
|
||||
_tooltip = child._tooltip;
|
||||
}
|
||||
|
||||
_thickness = math.max(_thickness, child._thickness + child._elevation);
|
||||
|
||||
@ -4533,8 +4587,9 @@ AttributedString _concatAttributedString({
|
||||
required TextDirection? thisTextDirection,
|
||||
required TextDirection? otherTextDirection,
|
||||
}) {
|
||||
if (otherAttributedString.string.isEmpty)
|
||||
if (otherAttributedString.string.isEmpty) {
|
||||
return thisAttributedString;
|
||||
}
|
||||
if (thisTextDirection != otherTextDirection && otherTextDirection != null) {
|
||||
switch (otherTextDirection) {
|
||||
case TextDirection.rtl:
|
||||
@ -4545,8 +4600,9 @@ AttributedString _concatAttributedString({
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (thisAttributedString.string.isEmpty)
|
||||
if (thisAttributedString.string.isEmpty) {
|
||||
return otherAttributedString;
|
||||
}
|
||||
|
||||
return thisAttributedString + AttributedString('\n') + otherAttributedString;
|
||||
}
|
||||
@ -4662,8 +4718,9 @@ class OrdinalSortKey extends SemanticsSortKey {
|
||||
|
||||
@override
|
||||
int doCompare(OrdinalSortKey other) {
|
||||
if (other.order == null || order == null || other.order == order)
|
||||
if (other.order == null || order == null || other.order == order) {
|
||||
return 0;
|
||||
}
|
||||
return order.compareTo(other.order);
|
||||
}
|
||||
|
||||
|
||||
@ -34,8 +34,9 @@ abstract class SemanticsEvent {
|
||||
'type': type,
|
||||
'data': getDataMap(),
|
||||
};
|
||||
if (nodeId != null)
|
||||
if (nodeId != null) {
|
||||
event['nodeId'] = nodeId;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
@ -48,8 +49,9 @@ abstract class SemanticsEvent {
|
||||
final List<String> pairs = <String>[];
|
||||
final Map<String, dynamic> dataMap = getDataMap();
|
||||
final List<String> sortedKeys = dataMap.keys.toList()..sort();
|
||||
for (final String key in sortedKeys)
|
||||
for (final String key in sortedKeys) {
|
||||
pairs.add('$key: ${dataMap[key]}');
|
||||
}
|
||||
return '${objectRuntimeType(this, 'SemanticsEvent')}(${pairs.join(', ')})';
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,8 +70,9 @@ abstract class AssetBundle {
|
||||
/// isolate to avoid jank on the main thread.
|
||||
Future<String> loadString(String key, { bool cache = true }) async {
|
||||
final ByteData data = await load(key);
|
||||
if (data == null)
|
||||
if (data == null) {
|
||||
throw FlutterError('Unable to load asset: $key');
|
||||
}
|
||||
// 50 KB of data should take 2-3 ms to parse on a Moto G4, and about 400 μs
|
||||
// on a Pixel 4.
|
||||
if (data.lengthInBytes < 50 * 1024) {
|
||||
@ -125,11 +126,12 @@ class NetworkAssetBundle extends AssetBundle {
|
||||
Future<ByteData> load(String key) async {
|
||||
final HttpClientRequest request = await _httpClient.getUrl(_urlFromKey(key));
|
||||
final HttpClientResponse response = await request.close();
|
||||
if (response.statusCode != HttpStatus.ok)
|
||||
if (response.statusCode != HttpStatus.ok) {
|
||||
throw FlutterError.fromParts(<DiagnosticsNode>[
|
||||
ErrorSummary('Unable to load asset: $key'),
|
||||
IntProperty('HTTP status code', response.statusCode),
|
||||
]);
|
||||
}
|
||||
final Uint8List bytes = await consolidateHttpClientResponseBytes(response);
|
||||
return bytes.buffer.asByteData();
|
||||
}
|
||||
@ -168,8 +170,9 @@ abstract class CachingAssetBundle extends AssetBundle {
|
||||
|
||||
@override
|
||||
Future<String> loadString(String key, { bool cache = true }) {
|
||||
if (cache)
|
||||
if (cache) {
|
||||
return _stringCache.putIfAbsent(key, () => super.loadString(key));
|
||||
}
|
||||
return super.loadString(key);
|
||||
}
|
||||
|
||||
@ -187,8 +190,9 @@ abstract class CachingAssetBundle extends AssetBundle {
|
||||
Future<T> loadStructuredData<T>(String key, Future<T> Function(String value) parser) {
|
||||
assert(key != null);
|
||||
assert(parser != null);
|
||||
if (_structuredDataCache.containsKey(key))
|
||||
if (_structuredDataCache.containsKey(key)) {
|
||||
return _structuredDataCache[key]! as Future<T>;
|
||||
}
|
||||
Completer<T>? completer;
|
||||
Future<T>? result;
|
||||
loadString(key, cache: false).then<T>(parser).then<void>((T value) {
|
||||
@ -233,8 +237,9 @@ class PlatformAssetBundle extends CachingAssetBundle {
|
||||
final Uint8List encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(key)).path);
|
||||
final ByteData? asset =
|
||||
await ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData());
|
||||
if (asset == null)
|
||||
if (asset == null) {
|
||||
throw FlutterError('Unable to load asset: $key');
|
||||
}
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,8 +338,9 @@ class _DefaultBinaryMessenger extends BinaryMessenger {
|
||||
ui.PlatformMessageResponseCallback? callback,
|
||||
) async {
|
||||
ui.channelBuffers.push(channel, message, (ByteData? data) {
|
||||
if (callback != null)
|
||||
if (callback != null) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -55,8 +55,9 @@ class Clipboard {
|
||||
'Clipboard.getData',
|
||||
format,
|
||||
);
|
||||
if (result == null)
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return ClipboardData(text: result['text'] as String?);
|
||||
}
|
||||
|
||||
|
||||
@ -34,8 +34,9 @@ class FontLoader {
|
||||
/// The [bytes] argument specifies the actual font asset bytes. Currently,
|
||||
/// only OpenType (OTF) and TrueType (TTF) fonts are supported.
|
||||
void addFont(Future<ByteData> bytes) {
|
||||
if (_loaded)
|
||||
if (_loaded) {
|
||||
throw StateError('FontLoader is already loaded');
|
||||
}
|
||||
|
||||
_fontFutures.add(bytes.then(
|
||||
(ByteData data) => Uint8List.view(data.buffer, data.offsetInBytes, data.lengthInBytes),
|
||||
@ -53,8 +54,9 @@ class FontLoader {
|
||||
/// The returned future will complete with an error if any of the font asset
|
||||
/// futures yield an error.
|
||||
Future<void> load() async {
|
||||
if (_loaded)
|
||||
if (_loaded) {
|
||||
throw StateError('FontLoader is already loaded');
|
||||
}
|
||||
_loaded = true;
|
||||
|
||||
final Iterable<Future<void>> loadFutures = _fontFutures.map(
|
||||
|
||||
@ -166,10 +166,12 @@ class LogicalKeyboardKey extends KeyboardKey {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is LogicalKeyboardKey
|
||||
&& other.keyId == keyId;
|
||||
}
|
||||
@ -3539,10 +3541,12 @@ class PhysicalKeyboardKey extends KeyboardKey {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is PhysicalKeyboardKey
|
||||
&& other.usbHidUsage == usbHidUsage;
|
||||
}
|
||||
|
||||
@ -41,15 +41,17 @@ class StringCodec implements MessageCodec<String> {
|
||||
|
||||
@override
|
||||
String? decodeMessage(ByteData? message) {
|
||||
if (message == null)
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
return utf8.decoder.convert(message.buffer.asUint8List(message.offsetInBytes, message.lengthInBytes));
|
||||
}
|
||||
|
||||
@override
|
||||
ByteData? encodeMessage(String? message) {
|
||||
if (message == null)
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
final Uint8List encoded = utf8.encoder.convert(message);
|
||||
return encoded.buffer.asByteData();
|
||||
}
|
||||
@ -89,15 +91,17 @@ class JSONMessageCodec implements MessageCodec<Object?> {
|
||||
|
||||
@override
|
||||
ByteData? encodeMessage(Object? message) {
|
||||
if (message == null)
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
return const StringCodec().encodeMessage(json.encode(message));
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic decodeMessage(ByteData? message) {
|
||||
if (message == null)
|
||||
if (message == null) {
|
||||
return message;
|
||||
}
|
||||
return json.decode(const StringCodec().decodeMessage(message)!);
|
||||
}
|
||||
}
|
||||
@ -135,40 +139,46 @@ class JSONMethodCodec implements MethodCodec {
|
||||
@override
|
||||
MethodCall decodeMethodCall(ByteData? methodCall) {
|
||||
final Object? decoded = const JSONMessageCodec().decodeMessage(methodCall);
|
||||
if (decoded is! Map)
|
||||
if (decoded is! Map) {
|
||||
throw FormatException('Expected method call Map, got $decoded');
|
||||
}
|
||||
final Object? method = decoded['method'];
|
||||
final Object? arguments = decoded['args'];
|
||||
if (method is String)
|
||||
if (method is String) {
|
||||
return MethodCall(method, arguments);
|
||||
}
|
||||
throw FormatException('Invalid method call: $decoded');
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic decodeEnvelope(ByteData envelope) {
|
||||
final Object? decoded = const JSONMessageCodec().decodeMessage(envelope);
|
||||
if (decoded is! List)
|
||||
if (decoded is! List) {
|
||||
throw FormatException('Expected envelope List, got $decoded');
|
||||
if (decoded.length == 1)
|
||||
}
|
||||
if (decoded.length == 1) {
|
||||
return decoded[0];
|
||||
}
|
||||
if (decoded.length == 3
|
||||
&& decoded[0] is String
|
||||
&& (decoded[1] == null || decoded[1] is String))
|
||||
&& (decoded[1] == null || decoded[1] is String)) {
|
||||
throw PlatformException(
|
||||
code: decoded[0] as String,
|
||||
message: decoded[1] as String?,
|
||||
details: decoded[2],
|
||||
);
|
||||
}
|
||||
if (decoded.length == 4
|
||||
&& decoded[0] is String
|
||||
&& (decoded[1] == null || decoded[1] is String)
|
||||
&& (decoded[3] == null || decoded[3] is String))
|
||||
&& (decoded[3] == null || decoded[3] is String)) {
|
||||
throw PlatformException(
|
||||
code: decoded[0] as String,
|
||||
message: decoded[1] as String?,
|
||||
details: decoded[2],
|
||||
stacktrace: decoded[3] as String?,
|
||||
);
|
||||
}
|
||||
throw FormatException('Invalid envelope: $decoded');
|
||||
}
|
||||
|
||||
@ -310,8 +320,9 @@ class StandardMessageCodec implements MessageCodec<Object?> {
|
||||
|
||||
@override
|
||||
ByteData? encodeMessage(Object? message) {
|
||||
if (message == null)
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
final WriteBuffer buffer = WriteBuffer(startCapacity: _writeBufferStartCapacity);
|
||||
writeValue(buffer, message);
|
||||
return buffer.done();
|
||||
@ -319,12 +330,14 @@ class StandardMessageCodec implements MessageCodec<Object?> {
|
||||
|
||||
@override
|
||||
dynamic decodeMessage(ByteData? message) {
|
||||
if (message == null)
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
final ReadBuffer buffer = ReadBuffer(message);
|
||||
final Object? result = readValue(buffer);
|
||||
if (buffer.hasRemaining)
|
||||
if (buffer.hasRemaining) {
|
||||
throw const FormatException('Message corrupted');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -453,8 +466,9 @@ class StandardMessageCodec implements MessageCodec<Object?> {
|
||||
/// This method is intended for use by subclasses overriding
|
||||
/// [readValueOfType].
|
||||
Object? readValue(ReadBuffer buffer) {
|
||||
if (!buffer.hasRemaining)
|
||||
if (!buffer.hasRemaining) {
|
||||
throw const FormatException('Message corrupted');
|
||||
}
|
||||
final int type = buffer.getUint8();
|
||||
return readValueOfType(type, buffer);
|
||||
}
|
||||
@ -500,14 +514,16 @@ class StandardMessageCodec implements MessageCodec<Object?> {
|
||||
case _valueList:
|
||||
final int length = readSize(buffer);
|
||||
final List<Object?> result = List<Object?>.filled(length, null);
|
||||
for (int i = 0; i < length; i++)
|
||||
for (int i = 0; i < length; i++) {
|
||||
result[i] = readValue(buffer);
|
||||
}
|
||||
return result;
|
||||
case _valueMap:
|
||||
final int length = readSize(buffer);
|
||||
final Map<Object?, Object?> result = <Object?, Object?>{};
|
||||
for (int i = 0; i < length; i++)
|
||||
for (int i = 0; i < length; i++) {
|
||||
result[readValue(buffer)] = readValue(buffer);
|
||||
}
|
||||
return result;
|
||||
default: throw const FormatException('Message corrupted');
|
||||
}
|
||||
@ -588,10 +604,11 @@ class StandardMethodCodec implements MethodCodec {
|
||||
final ReadBuffer buffer = ReadBuffer(methodCall!);
|
||||
final Object? method = messageCodec.readValue(buffer);
|
||||
final Object? arguments = messageCodec.readValue(buffer);
|
||||
if (method is String && !buffer.hasRemaining)
|
||||
if (method is String && !buffer.hasRemaining) {
|
||||
return MethodCall(method, arguments);
|
||||
else
|
||||
} else {
|
||||
throw const FormatException('Invalid method call');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@ -615,18 +632,21 @@ class StandardMethodCodec implements MethodCodec {
|
||||
@override
|
||||
dynamic decodeEnvelope(ByteData envelope) {
|
||||
// First byte is zero in success case, and non-zero otherwise.
|
||||
if (envelope.lengthInBytes == 0)
|
||||
if (envelope.lengthInBytes == 0) {
|
||||
throw const FormatException('Expected envelope, got nothing');
|
||||
}
|
||||
final ReadBuffer buffer = ReadBuffer(envelope);
|
||||
if (buffer.getUint8() == 0)
|
||||
if (buffer.getUint8() == 0) {
|
||||
return messageCodec.readValue(buffer);
|
||||
}
|
||||
final Object? errorCode = messageCodec.readValue(buffer);
|
||||
final Object? errorMessage = messageCodec.readValue(buffer);
|
||||
final Object? errorDetails = messageCodec.readValue(buffer);
|
||||
final String? errorStacktrace = (buffer.hasRemaining) ? messageCodec.readValue(buffer) as String? : null;
|
||||
if (errorCode is String && (errorMessage == null || errorMessage is String) && !buffer.hasRemaining)
|
||||
if (errorCode is String && (errorMessage == null || errorMessage is String) && !buffer.hasRemaining) {
|
||||
throw PlatformException(code: errorCode, message: errorMessage as String?, details: errorDetails, stacktrace: errorStacktrace);
|
||||
else
|
||||
} else {
|
||||
throw const FormatException('Invalid envelope');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,8 +66,9 @@ class MouseCursorManager {
|
||||
final MouseCursor nextCursor = _DeferringMouseCursor.firstNonDeferred(cursorCandidates)
|
||||
?? fallbackMouseCursor;
|
||||
assert(nextCursor is! _DeferringMouseCursor);
|
||||
if (lastSession?.cursor == nextCursor)
|
||||
if (lastSession?.cursor == nextCursor) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MouseCursorSession nextSession = nextCursor.createSession(device);
|
||||
_lastSession[device] = nextSession;
|
||||
@ -211,8 +212,9 @@ abstract class MouseCursor with Diagnosticable {
|
||||
@override
|
||||
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||
final String debugDescription = this.debugDescription;
|
||||
if (minLevel.index >= DiagnosticLevel.info.index && debugDescription != null)
|
||||
if (minLevel.index >= DiagnosticLevel.info.index && debugDescription != null) {
|
||||
return debugDescription;
|
||||
}
|
||||
return super.toString(minLevel: minLevel);
|
||||
}
|
||||
|
||||
@ -258,8 +260,9 @@ class _DeferringMouseCursor extends MouseCursor {
|
||||
static MouseCursor? firstNonDeferred(Iterable<MouseCursor> cursors) {
|
||||
for (final MouseCursor cursor in cursors) {
|
||||
assert(cursor != null);
|
||||
if (cursor != MouseCursor.defer)
|
||||
if (cursor != MouseCursor.defer) {
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -368,8 +371,9 @@ class SystemMouseCursor extends MouseCursor {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is SystemMouseCursor
|
||||
&& other.kind == kind;
|
||||
}
|
||||
|
||||
@ -860,16 +860,18 @@ abstract class AndroidViewController extends PlatformViewController {
|
||||
'trying to set a layout direction for a disposed UIView. View id: $viewId',
|
||||
);
|
||||
|
||||
if (layoutDirection == _layoutDirection)
|
||||
if (layoutDirection == _layoutDirection) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(layoutDirection != null);
|
||||
_layoutDirection = layoutDirection;
|
||||
|
||||
// If the view was not yet created we just update _layoutDirection and return, as the new
|
||||
// direction will be used in _create.
|
||||
if (_state == _AndroidViewState.waitingForSize)
|
||||
if (_state == _AndroidViewState.waitingForSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
await SystemChannels.platform_views
|
||||
.invokeMethod<void>('setDirection', <String, dynamic>{
|
||||
@ -931,8 +933,9 @@ abstract class AndroidViewController extends PlatformViewController {
|
||||
/// disposed.
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
if (_state == _AndroidViewState.creating || _state == _AndroidViewState.created)
|
||||
if (_state == _AndroidViewState.creating || _state == _AndroidViewState.created) {
|
||||
await _sendDisposeMessage();
|
||||
}
|
||||
_platformViewCreatedCallbacks.clear();
|
||||
_state = _AndroidViewState.disposed;
|
||||
PlatformViewsService._instance._focusCallbacks.remove(viewId);
|
||||
@ -1058,8 +1061,9 @@ class TextureAndroidViewController extends AndroidViewController {
|
||||
|
||||
@override
|
||||
Future<void> create({Size? size}) async {
|
||||
if (size == null)
|
||||
if (size == null) {
|
||||
return;
|
||||
}
|
||||
assert(_state == _AndroidViewState.waitingForSize, 'Android view is already sized. View id: $viewId');
|
||||
assert(!size.isEmpty);
|
||||
return super.create(size: size);
|
||||
@ -1067,14 +1071,16 @@ class TextureAndroidViewController extends AndroidViewController {
|
||||
|
||||
@override
|
||||
Future<void> setOffset(Offset off) async {
|
||||
if (off == _off)
|
||||
if (off == _off) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't set the offset unless the Android view has been created.
|
||||
// The implementation of this method channel throws if the Android view for this viewId
|
||||
// isn't addressable.
|
||||
if (_state != _AndroidViewState.created)
|
||||
if (_state != _AndroidViewState.created) {
|
||||
return;
|
||||
}
|
||||
|
||||
_off = off;
|
||||
|
||||
@ -1090,8 +1096,9 @@ class TextureAndroidViewController extends AndroidViewController {
|
||||
|
||||
@override
|
||||
Future<void> _sendCreateMessage({Size? size}) async {
|
||||
if (size == null)
|
||||
if (size == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!size.isEmpty, 'trying to create $TextureAndroidViewController without setting a valid size.');
|
||||
|
||||
@ -1149,8 +1156,9 @@ class UiKitViewController {
|
||||
Future<void> setLayoutDirection(TextDirection layoutDirection) async {
|
||||
assert(!_debugDisposed, 'trying to set a layout direction for a disposed iOS UIView. View id: $id');
|
||||
|
||||
if (layoutDirection == _layoutDirection)
|
||||
if (layoutDirection == _layoutDirection) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(layoutDirection != null);
|
||||
_layoutDirection = layoutDirection;
|
||||
|
||||
@ -527,8 +527,9 @@ abstract class RawKeyEvent with Diagnosticable {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(DiagnosticsProperty<LogicalKeyboardKey>('logicalKey', logicalKey));
|
||||
properties.add(DiagnosticsProperty<PhysicalKeyboardKey>('physicalKey', physicalKey));
|
||||
if (this is RawKeyDownEvent)
|
||||
if (this is RawKeyDownEvent) {
|
||||
properties.add(DiagnosticsProperty<bool>('repeat', repeat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,8 +652,9 @@ class RawKeyboard {
|
||||
_cachedKeyMessageHandler = handler == null ?
|
||||
null :
|
||||
(KeyMessage message) {
|
||||
if (message.rawEvent != null)
|
||||
if (message.rawEvent != null) {
|
||||
return handler(message.rawEvent!);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
ServicesBinding.instance.keyEventManager.keyMessageHandler = _cachedKeyMessageHandler;
|
||||
@ -783,8 +785,9 @@ class RawKeyboard {
|
||||
ModifierKey? thisKeyModifier;
|
||||
for (final ModifierKey key in ModifierKey.values) {
|
||||
final Set<PhysicalKeyboardKey>? thisModifierKeys = _modifierKeyMap[_ModifierSidePair(key, KeyboardSide.all)];
|
||||
if (thisModifierKeys == null)
|
||||
if (thisModifierKeys == null) {
|
||||
continue;
|
||||
}
|
||||
if (thisModifierKeys.contains(event.physicalKey)) {
|
||||
thisKeyModifier = key;
|
||||
}
|
||||
@ -869,8 +872,9 @@ class _ModifierSidePair {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is _ModifierSidePair
|
||||
&& other.modifier == modifier
|
||||
&& other.side == side;
|
||||
|
||||
@ -298,10 +298,12 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
|
||||
|
||||
@override
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is RawKeyEventDataAndroid
|
||||
&& other.flags == flags
|
||||
&& other.codePoint == codePoint
|
||||
|
||||
@ -168,10 +168,12 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
|
||||
|
||||
@override
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is RawKeyEventDataFuchsia
|
||||
&& other.hidUsage == hidUsage
|
||||
&& other.codePoint == codePoint
|
||||
|
||||
@ -264,10 +264,12 @@ class RawKeyEventDataIos extends RawKeyEventData {
|
||||
|
||||
@override
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is RawKeyEventDataIos
|
||||
&& other.characters == characters
|
||||
&& other.charactersIgnoringModifiers == charactersIgnoringModifiers
|
||||
|
||||
@ -143,10 +143,12 @@ class RawKeyEventDataLinux extends RawKeyEventData {
|
||||
|
||||
@override
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is RawKeyEventDataLinux
|
||||
&& other.keyHelper.runtimeType == keyHelper.runtimeType
|
||||
&& other.unicodeScalarValues == unicodeScalarValues
|
||||
|
||||
@ -13,8 +13,9 @@ int runeToLowerCase(int rune) {
|
||||
// Assume only Basic Multilingual Plane runes have lower and upper cases.
|
||||
// For other characters, return them as is.
|
||||
const int utf16BmpUpperBound = 0xD7FF;
|
||||
if (rune > utf16BmpUpperBound)
|
||||
if (rune > utf16BmpUpperBound) {
|
||||
return rune;
|
||||
}
|
||||
return String.fromCharCode(rune).toLowerCase().codeUnitAt(0);
|
||||
}
|
||||
|
||||
@ -251,10 +252,12 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
||||
|
||||
@override
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is RawKeyEventDataMacOs
|
||||
&& other.characters == characters
|
||||
&& other.charactersIgnoringModifiers == charactersIgnoringModifiers
|
||||
|
||||
@ -98,8 +98,9 @@ class RawKeyEventDataWeb extends RawKeyEventData {
|
||||
// Look to see if the keyCode is a key based on location. Typically they are
|
||||
// numpad keys (versus main area keys) and left/right modifiers.
|
||||
final LogicalKeyboardKey? maybeLocationKey = kWebLocationMap[key]?[location];
|
||||
if (maybeLocationKey != null)
|
||||
if (maybeLocationKey != null) {
|
||||
return maybeLocationKey;
|
||||
}
|
||||
|
||||
// Look to see if the [code] is one we know about and have a mapping for.
|
||||
final LogicalKeyboardKey? newKey = kWebToLogicalKey[code];
|
||||
@ -108,8 +109,9 @@ class RawKeyEventDataWeb extends RawKeyEventData {
|
||||
}
|
||||
|
||||
final bool isPrintable = key.length == 1;
|
||||
if (isPrintable)
|
||||
if (isPrintable) {
|
||||
return LogicalKeyboardKey(key.toLowerCase().codeUnitAt(0));
|
||||
}
|
||||
|
||||
// This is a non-printable key that we don't know about, so we mint a new
|
||||
// key from `code`. Don't mint with `key`, because the `key` will always be
|
||||
@ -166,10 +168,12 @@ class RawKeyEventDataWeb extends RawKeyEventData {
|
||||
|
||||
@override
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is RawKeyEventDataWeb
|
||||
&& other.code == code
|
||||
&& other.key == key
|
||||
|
||||
@ -209,10 +209,12 @@ class RawKeyEventDataWindows extends RawKeyEventData {
|
||||
|
||||
@override
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
}
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is RawKeyEventDataWindows
|
||||
&& other.keyCode == keyCode
|
||||
&& other.scanCode == scanCode
|
||||
|
||||
@ -333,8 +333,9 @@ class SystemUiOverlayStyle {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is SystemUiOverlayStyle
|
||||
&& other.systemNavigationBarColor == systemNavigationBarColor
|
||||
&& other.systemNavigationBarDividerColor == systemNavigationBarDividerColor
|
||||
|
||||
@ -140,10 +140,12 @@ class TextSelection extends TextRange {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (other is! TextSelection)
|
||||
}
|
||||
if (other is! TextSelection) {
|
||||
return false;
|
||||
}
|
||||
if (!isValid) {
|
||||
return !other.isValid;
|
||||
}
|
||||
|
||||
@ -916,8 +916,9 @@ class TextEditingValue {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
return other is TextEditingValue
|
||||
&& other.text == text
|
||||
&& other.selection == selection
|
||||
@ -1165,10 +1166,12 @@ class SelectionRect {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other))
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
if (runtimeType != other.runtimeType)
|
||||
}
|
||||
if (runtimeType != other.runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is SelectionRect
|
||||
&& other.position == position
|
||||
&& other.bounds == bounds;
|
||||
@ -1330,8 +1333,9 @@ class TextInputConnection {
|
||||
/// platform.
|
||||
void setComposingRect(Rect rect) {
|
||||
assert(rect != null);
|
||||
if (rect == _cachedRect)
|
||||
if (rect == _cachedRect) {
|
||||
return;
|
||||
}
|
||||
_cachedRect = rect;
|
||||
final Rect validRect = rect.isFinite ? rect : Offset.zero & const Size(-1, -1);
|
||||
TextInput._instance._setComposingTextRect(
|
||||
@ -1348,8 +1352,9 @@ class TextInputConnection {
|
||||
/// the accent selection menu.
|
||||
void setCaretRect(Rect rect) {
|
||||
assert(rect != null);
|
||||
if (rect == _cachedCaretRect)
|
||||
if (rect == _cachedCaretRect) {
|
||||
return;
|
||||
}
|
||||
_cachedCaretRect = rect;
|
||||
final Rect validRect = rect.isFinite ? rect : Offset.zero & const Size(-1, -1);
|
||||
TextInput._instance._setCaretRect(
|
||||
@ -1662,8 +1667,9 @@ class TextInput {
|
||||
final List<double> args = (methodCall.arguments as List<dynamic>).cast<num>().map<double>((num value) => value.toDouble()).toList();
|
||||
return _scribbleClients.keys.where((String elementIdentifier) {
|
||||
final Rect rect = Rect.fromLTWH(args[0], args[1], args[2], args[3]);
|
||||
if (!(_scribbleClients[elementIdentifier]?.isInScribbleRect(rect) ?? false))
|
||||
if (!(_scribbleClients[elementIdentifier]?.isInScribbleRect(rect) ?? false)) {
|
||||
return false;
|
||||
}
|
||||
final Rect bounds = _scribbleClients[elementIdentifier]?.bounds ?? Rect.zero;
|
||||
return !(bounds == Rect.zero || bounds.hasNaN || bounds.isInfinite);
|
||||
}).map((String elementIdentifier) {
|
||||
@ -1677,8 +1683,9 @@ class TextInput {
|
||||
_scribbleInProgress = false;
|
||||
return;
|
||||
}
|
||||
if (_currentConnection == null)
|
||||
if (_currentConnection == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The requestExistingInputState request needs to be handled regardless of
|
||||
// the client ID, as long as we have a _currentConnection.
|
||||
@ -1723,12 +1730,14 @@ class TextInput {
|
||||
// In debug builds we allow "-1" as a magical client ID that ignores
|
||||
// this verification step so that tests can always get through, even
|
||||
// when they are not mocking the engine side of text input.
|
||||
if (client == -1)
|
||||
if (client == -1) {
|
||||
debugAllowAnyway = true;
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
if (!debugAllowAnyway)
|
||||
if (!debugAllowAnyway) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (method) {
|
||||
@ -1787,8 +1796,9 @@ class TextInput {
|
||||
bool _hidePending = false;
|
||||
|
||||
void _scheduleHide() {
|
||||
if (_hidePending)
|
||||
if (_hidePending) {
|
||||
return;
|
||||
}
|
||||
_hidePending = true;
|
||||
|
||||
// Schedule a deferred task that hides the text input. If someone else
|
||||
@ -1796,8 +1806,9 @@ class TextInput {
|
||||
// nothing.
|
||||
scheduleMicrotask(() {
|
||||
_hidePending = false;
|
||||
if (_currentConnection == null)
|
||||
if (_currentConnection == null) {
|
||||
_channel.invokeMethod<void>('TextInput.hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -52,20 +52,23 @@ void main() {
|
||||
input.forEach(scheduleAddingTask);
|
||||
|
||||
strategy.allowedPriority = 100;
|
||||
for (int i = 0; i < 3; i += 1)
|
||||
for (int i = 0; i < 3; i += 1) {
|
||||
expect(scheduler.handleEventLoopCallback(), isFalse);
|
||||
}
|
||||
expect(executedTasks.isEmpty, isTrue);
|
||||
|
||||
strategy.allowedPriority = 50;
|
||||
for (int i = 0; i < 3; i += 1)
|
||||
for (int i = 0; i < 3; i += 1) {
|
||||
expect(scheduler.handleEventLoopCallback(), i == 0 ? isTrue : isFalse);
|
||||
}
|
||||
expect(executedTasks, hasLength(1));
|
||||
expect(executedTasks.single, equals(80));
|
||||
executedTasks.clear();
|
||||
|
||||
strategy.allowedPriority = 20;
|
||||
for (int i = 0; i < 3; i += 1)
|
||||
for (int i = 0; i < 3; i += 1) {
|
||||
expect(scheduler.handleEventLoopCallback(), i < 2 ? isTrue : isFalse);
|
||||
}
|
||||
expect(executedTasks, hasLength(2));
|
||||
expect(executedTasks[0], equals(23));
|
||||
expect(executedTasks[1], equals(23));
|
||||
@ -75,24 +78,27 @@ void main() {
|
||||
scheduleAddingTask(19);
|
||||
scheduleAddingTask(5);
|
||||
scheduleAddingTask(97);
|
||||
for (int i = 0; i < 3; i += 1)
|
||||
for (int i = 0; i < 3; i += 1) {
|
||||
expect(scheduler.handleEventLoopCallback(), i < 2 ? isTrue : isFalse);
|
||||
}
|
||||
expect(executedTasks, hasLength(2));
|
||||
expect(executedTasks[0], equals(99));
|
||||
expect(executedTasks[1], equals(97));
|
||||
executedTasks.clear();
|
||||
|
||||
strategy.allowedPriority = 10;
|
||||
for (int i = 0; i < 3; i += 1)
|
||||
for (int i = 0; i < 3; i += 1) {
|
||||
expect(scheduler.handleEventLoopCallback(), i < 2 ? isTrue : isFalse);
|
||||
}
|
||||
expect(executedTasks, hasLength(2));
|
||||
expect(executedTasks[0], equals(19));
|
||||
expect(executedTasks[1], equals(11));
|
||||
executedTasks.clear();
|
||||
|
||||
strategy.allowedPriority = 1;
|
||||
for (int i = 0; i < 4; i += 1)
|
||||
for (int i = 0; i < 4; i += 1) {
|
||||
expect(scheduler.handleEventLoopCallback(), i < 3 ? isTrue : isFalse);
|
||||
}
|
||||
expect(executedTasks, hasLength(3));
|
||||
expect(executedTasks[0], equals(5));
|
||||
expect(executedTasks[1], equals(3));
|
||||
|
||||
@ -842,18 +842,24 @@ class TestRender extends RenderProxyBox {
|
||||
super.describeSemanticsConfiguration(config);
|
||||
|
||||
config.isSemanticBoundary = isSemanticBoundary;
|
||||
if (hasTapAction)
|
||||
if (hasTapAction) {
|
||||
config.onTap = () { };
|
||||
if (hasLongPressAction)
|
||||
}
|
||||
if (hasLongPressAction) {
|
||||
config.onLongPress = () { };
|
||||
if (hasScrollLeftAction)
|
||||
}
|
||||
if (hasScrollLeftAction) {
|
||||
config.onScrollLeft = () { };
|
||||
if (hasScrollRightAction)
|
||||
}
|
||||
if (hasScrollRightAction) {
|
||||
config.onScrollRight = () { };
|
||||
if (hasScrollUpAction)
|
||||
}
|
||||
if (hasScrollUpAction) {
|
||||
config.onScrollUp = () { };
|
||||
if (hasScrollDownAction)
|
||||
}
|
||||
if (hasScrollDownAction) {
|
||||
config.onScrollDown = () { };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,11 +16,13 @@ class TestAssetBundle extends CachingAssetBundle {
|
||||
@override
|
||||
Future<ByteData> load(String key) async {
|
||||
loadCallCount[key] = loadCallCount[key] ?? 0 + 1;
|
||||
if (key == 'AssetManifest.json')
|
||||
if (key == 'AssetManifest.json') {
|
||||
return ByteData.view(Uint8List.fromList(const Utf8Encoder().convert('{"one": ["one"]}')).buffer);
|
||||
}
|
||||
|
||||
if (key == 'one')
|
||||
if (key == 'one') {
|
||||
return ByteData(1)..setInt8(0, 49);
|
||||
}
|
||||
throw FlutterError('key not found');
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,17 +186,19 @@ class FakeAndroidPlatformViewsController {
|
||||
final bool? hybrid = args['hybrid'] as bool?;
|
||||
final Uint8List? creationParams = args['params'] as Uint8List?;
|
||||
|
||||
if (_views.containsKey(id))
|
||||
if (_views.containsKey(id)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to create an already created platform view, view id: $id',
|
||||
);
|
||||
}
|
||||
|
||||
if (!_registeredViewTypes.contains(viewType))
|
||||
if (!_registeredViewTypes.contains(viewType)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to create a platform view of unregistered type: $viewType',
|
||||
);
|
||||
}
|
||||
|
||||
if (createCompleter != null) {
|
||||
await createCompleter!.future;
|
||||
@ -225,11 +227,12 @@ class FakeAndroidPlatformViewsController {
|
||||
throw ArgumentError('An $AndroidViewController not using hybrid composition must pass `hybrid: false`');
|
||||
}
|
||||
|
||||
if (!_views.containsKey(id))
|
||||
if (!_views.containsKey(id)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to dispose a platform view with unknown id: $id',
|
||||
);
|
||||
}
|
||||
|
||||
_views.remove(id);
|
||||
return Future<dynamic>.sync(() => null);
|
||||
@ -241,11 +244,12 @@ class FakeAndroidPlatformViewsController {
|
||||
final double width = args['width'] as double;
|
||||
final double height = args['height'] as double;
|
||||
|
||||
if (!_views.containsKey(id))
|
||||
if (!_views.containsKey(id)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to resize a platform view with unknown id: $id',
|
||||
);
|
||||
}
|
||||
|
||||
if (resizeCompleter != null) {
|
||||
await resizeCompleter!.future;
|
||||
@ -279,8 +283,9 @@ class FakeAndroidPlatformViewsController {
|
||||
pointerOffsets.add(Offset(x, y));
|
||||
}
|
||||
|
||||
if (!motionEvents.containsKey(id))
|
||||
if (!motionEvents.containsKey(id)) {
|
||||
motionEvents[id] = <FakeAndroidMotionEvent> [];
|
||||
}
|
||||
|
||||
motionEvents[id]!.add(FakeAndroidMotionEvent(action, pointerIds, pointerOffsets));
|
||||
return Future<dynamic>.sync(() => null);
|
||||
@ -291,11 +296,12 @@ class FakeAndroidPlatformViewsController {
|
||||
final int id = args['id'] as int;
|
||||
final int layoutDirection = args['direction'] as int;
|
||||
|
||||
if (!_views.containsKey(id))
|
||||
if (!_views.containsKey(id)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to resize a platform view with unknown id: $id',
|
||||
);
|
||||
}
|
||||
|
||||
_views[id] = _views[id]!.copyWith(layoutDirection: layoutDirection);
|
||||
|
||||
@ -305,11 +311,12 @@ class FakeAndroidPlatformViewsController {
|
||||
Future<dynamic> _clearFocus(MethodCall call) {
|
||||
final int id = call.arguments as int;
|
||||
|
||||
if (!_views.containsKey(id))
|
||||
if (!_views.containsKey(id)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to clear the focus on a platform view with unknown id: $id',
|
||||
);
|
||||
}
|
||||
|
||||
lastClearedFocusViewId = id;
|
||||
return Future<dynamic>.sync(() => null);
|
||||
@ -362,8 +369,9 @@ class FakeIosPlatformViewsController {
|
||||
}
|
||||
|
||||
Future<dynamic> _create(MethodCall call) async {
|
||||
if (creationDelay != null)
|
||||
if (creationDelay != null) {
|
||||
await creationDelay!.future;
|
||||
}
|
||||
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
|
||||
final int id = args['id'] as int;
|
||||
final String viewType = args['viewType'] as String;
|
||||
@ -451,17 +459,19 @@ class FakeHtmlPlatformViewsController {
|
||||
final int id = args['id'] as int;
|
||||
final String viewType = args['viewType'] as String;
|
||||
|
||||
if (_views.containsKey(id))
|
||||
if (_views.containsKey(id)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to create an already created platform view, view id: $id',
|
||||
);
|
||||
}
|
||||
|
||||
if (!_registeredViewTypes.contains(viewType))
|
||||
if (!_registeredViewTypes.contains(viewType)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to create a platform view of unregistered type: $viewType',
|
||||
);
|
||||
}
|
||||
|
||||
if (createCompleter != null) {
|
||||
await createCompleter!.future;
|
||||
@ -474,11 +484,12 @@ class FakeHtmlPlatformViewsController {
|
||||
Future<dynamic> _dispose(MethodCall call) {
|
||||
final int id = call.arguments as int;
|
||||
|
||||
if (!_views.containsKey(id))
|
||||
if (!_views.containsKey(id)) {
|
||||
throw PlatformException(
|
||||
code: 'error',
|
||||
message: 'Trying to dispose a platform view with unknown id: $id',
|
||||
);
|
||||
}
|
||||
|
||||
_views.remove(id);
|
||||
return Future<dynamic>.sync(() => null);
|
||||
@ -507,8 +518,9 @@ class FakeAndroidPlatformView {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is FakeAndroidPlatformView
|
||||
&& other.id == id
|
||||
&& other.type == type
|
||||
@ -570,8 +582,9 @@ class FakeUiKitView {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is FakeUiKitView
|
||||
&& other.id == id
|
||||
&& other.type == type
|
||||
@ -596,8 +609,9 @@ class FakeHtmlPlatformView {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is FakeHtmlPlatformView
|
||||
&& other.id == id
|
||||
&& other.type == type;
|
||||
|
||||
@ -32,14 +32,18 @@ void checkEncodeDecode<T>(MessageCodec<T> codec, T message) {
|
||||
}
|
||||
|
||||
bool deepEquals(dynamic valueA, dynamic valueB) {
|
||||
if (valueA is TypedData)
|
||||
if (valueA is TypedData) {
|
||||
return valueB is TypedData && deepEqualsTypedData(valueA, valueB);
|
||||
if (valueA is List)
|
||||
}
|
||||
if (valueA is List) {
|
||||
return valueB is List && deepEqualsList(valueA, valueB);
|
||||
if (valueA is Map)
|
||||
}
|
||||
if (valueA is Map) {
|
||||
return valueB is Map && deepEqualsMap(valueA, valueB);
|
||||
if (valueA is double && valueA.isNaN)
|
||||
}
|
||||
if (valueA is double && valueA.isNaN) {
|
||||
return valueB is double && valueB.isNaN;
|
||||
}
|
||||
return valueA == valueB;
|
||||
}
|
||||
|
||||
@ -48,35 +52,44 @@ bool deepEqualsTypedData(TypedData valueA, TypedData valueB) {
|
||||
return valueB is ByteData
|
||||
&& deepEqualsList(valueA.buffer.asUint8List(), valueB.buffer.asUint8List());
|
||||
}
|
||||
if (valueA is Uint8List)
|
||||
if (valueA is Uint8List) {
|
||||
return valueB is Uint8List && deepEqualsList(valueA, valueB);
|
||||
if (valueA is Int32List)
|
||||
}
|
||||
if (valueA is Int32List) {
|
||||
return valueB is Int32List && deepEqualsList(valueA, valueB);
|
||||
if (valueA is Int64List)
|
||||
}
|
||||
if (valueA is Int64List) {
|
||||
return valueB is Int64List && deepEqualsList(valueA, valueB);
|
||||
if (valueA is Float32List)
|
||||
}
|
||||
if (valueA is Float32List) {
|
||||
return valueB is Float32List && deepEqualsList(valueA, valueB);
|
||||
if (valueA is Float64List)
|
||||
}
|
||||
if (valueA is Float64List) {
|
||||
return valueB is Float64List && deepEqualsList(valueA, valueB);
|
||||
}
|
||||
throw 'Unexpected typed data: $valueA';
|
||||
}
|
||||
|
||||
bool deepEqualsList(List<dynamic> valueA, List<dynamic> valueB) {
|
||||
if (valueA.length != valueB.length)
|
||||
if (valueA.length != valueB.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < valueA.length; i++) {
|
||||
if (!deepEquals(valueA[i], valueB[i]))
|
||||
if (!deepEquals(valueA[i], valueB[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deepEqualsMap(Map<dynamic, dynamic> valueA, Map<dynamic, dynamic> valueB) {
|
||||
if (valueA.length != valueB.length)
|
||||
if (valueA.length != valueB.length) {
|
||||
return false;
|
||||
}
|
||||
for (final dynamic key in valueA.keys) {
|
||||
if (!valueB.containsKey(key) || !deepEquals(valueA[key], valueB[key]))
|
||||
if (!valueB.containsKey(key) || !deepEquals(valueA[key], valueB[key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -19,8 +19,9 @@ class MockRestorationManager extends TestRestorationManager {
|
||||
|
||||
@override
|
||||
void initChannels() {
|
||||
if (enableChannels)
|
||||
if (enableChannels) {
|
||||
super.initChannels();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user