debug.dart 2.95 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/widgets.dart';

import 'material.dart';
8
import 'scaffold.dart';
9

10
/// Asserts that the given context has a [Material] ancestor.
11
///
12 13 14
/// Used by many material design widgets to make sure that they are
/// only used in contexts where they can print ink onto some material.
///
15
/// To call this function, use the following pattern, typically in the
16 17 18 19 20 21 22
/// relevant Widget's [build] method:
///
/// ```dart
/// assert(debugCheckHasMaterial(context));
/// ```
///
/// Does nothing if asserts are disabled. Always returns true.
23 24
bool debugCheckHasMaterial(BuildContext context) {
  assert(() {
Hixie's avatar
Hixie committed
25 26
    if (context.widget is! Material && context.ancestorWidgetOfExactType(Material) == null) {
      Element element = context;
27
      throw new FlutterError(
28
        'No Material widget found.\n'
29
        '${context.widget.runtimeType} widgets require a Material widget ancestor.\n'
30 31 32 33 34
        'In material design, most widgets are conceptually "printed" on a sheet of material. In Flutter\'s material library, '
        'that material is represented by the Material widget. It is the Material widget that renders ink splashes, for instance. '
        'Because of this, many material library widgets require that there be a Material widget in the tree above them.\n'
        'To introduce a Material widget, you can either directly include one, or use a widget that contains Material itself, '
        'such as a Card, Dialog, Drawer, or Scaffold.\n'
35
        'The specific widget that could not find a Material ancestor was:\n'
36
        '  ${context.widget}\n'
37
        'The ownership chain for the affected widget is:\n'
38
        '  ${element.debugGetCreatorChain(10)}'
Hixie's avatar
Hixie committed
39 40 41
      );
    }
    return true;
42 43 44
  });
  return true;
}
45

46 47 48 49 50 51 52 53
/// Asserts that the given context has a [Scaffold] ancestor.
///
/// Used by some material design widgets to make sure that they are
/// only used in contexts where they can communicate with a Scaffold.
///
/// For example, the [AppBar] in some situations requires a Scaffold
/// to do the right thing with scrolling.
///
54
/// To call this function, use the following pattern, typically in the
55 56 57 58 59
/// relevant Widget's [build] method:
///
/// ```dart
/// assert(debugCheckHasScaffold(context));
/// ```
60
///
61
/// Does nothing if asserts are disabled. Always returns true.
62 63 64 65
bool debugCheckHasScaffold(BuildContext context) {
  assert(() {
    if (Scaffold.of(context) == null) {
      Element element = context;
66
      throw new FlutterError(
67
        'No Scaffold widget found.\n'
68 69
        '${context.widget.runtimeType} widgets require a Scaffold widget ancestor.\n'
        'The specific widget that could not find a Scaffold ancestor was:\n'
70
        '  ${context.widget}\n'
71
        'The ownership chain for the affected widget is:\n'
72
        '  ${element.debugGetCreatorChain(10)}'
73 74 75 76 77 78
      );
    }
    return true;
  });
  return true;
}