Skip to content

Commit d6ba144

Browse files
committed
content [nfc]: Extract base class BlockInlineContainerNode
This abstraction doesn't pull a lot of weight yet, but it will when we start tracking LinkNode descendants, for #71.
1 parent bae5cdc commit d6ba144

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

lib/model/content.dart

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ class UnimplementedBlockContentNode extends BlockContentNode
8484
// No ==/hashCode, because htmlNode is a whole subtree.
8585
}
8686

87+
/// A block content node whose children are inline content nodes.
88+
///
89+
/// A node of this type expects a block layout context from its parent,
90+
/// but provides an inline layout context for its children.
91+
///
92+
/// See also [InlineContainerNode].
93+
class BlockInlineContainerNode extends BlockContentNode {
94+
const BlockInlineContainerNode({
95+
super.debugHtmlNode,
96+
required this.nodes,
97+
});
98+
99+
final List<InlineContentNode> nodes;
100+
}
101+
87102
// A `br` element.
88103
class LineBreakNode extends BlockContentNode {
89104
const LineBreakNode({super.debugHtmlNode});
@@ -105,15 +120,13 @@ class LineBreakNode extends BlockContentNode {
105120
// with [wasImplicit].
106121
//
107122
// See also [parseImplicitParagraphBlockContentList].
108-
class ParagraphNode extends BlockContentNode {
123+
class ParagraphNode extends BlockInlineContainerNode {
109124
const ParagraphNode(
110-
{super.debugHtmlNode, this.wasImplicit = false, required this.nodes});
125+
{super.debugHtmlNode, required super.nodes, this.wasImplicit = false});
111126

112127
/// True when there was no corresponding `p` element in the original HTML.
113128
final bool wasImplicit;
114129

115-
final List<InlineContentNode> nodes;
116-
117130
@override
118131
String toString() => '${objectRuntimeType(this, 'ParagraphNode')}(wasImplicit: $wasImplicit, $nodes)';
119132
}
@@ -129,11 +142,14 @@ class ListNode extends BlockContentNode {
129142

130143
enum HeadingLevel { h1, h2, h3, h4, h5, h6 }
131144

132-
class HeadingNode extends BlockContentNode {
133-
const HeadingNode(this.level, this.nodes, {super.debugHtmlNode});
145+
class HeadingNode extends BlockInlineContainerNode {
146+
const HeadingNode({
147+
super.debugHtmlNode,
148+
required super.nodes,
149+
required this.level,
150+
});
134151

135152
final HeadingLevel level;
136-
final List<InlineContentNode> nodes;
137153
}
138154

139155
class QuotationNode extends BlockContentNode {
@@ -243,6 +259,8 @@ class LineBreakInlineNode extends InlineContentNode {
243259
/// the [InlineSpan]s built from this node's children. In that case,
244260
/// the children participate in the same paragraph layout as this node
245261
/// itself does.
262+
///
263+
/// See also [BlockInlineContainerNode].
246264
abstract class InlineContainerNode extends InlineContentNode {
247265
const InlineContainerNode({super.debugHtmlNode, required this.nodes});
248266

@@ -538,7 +556,7 @@ BlockContentNode parseBlockContent(dom.Node node) {
538556
if (headingLevel == HeadingLevel.h6 && classes.isEmpty) {
539557
// TODO(#192) handle h1, h2, h3, h4, h5
540558
return HeadingNode(
541-
headingLevel!, inlineNodes(), debugHtmlNode: debugHtmlNode);
559+
level: headingLevel!, nodes: inlineNodes(), debugHtmlNode: debugHtmlNode);
542560
}
543561

544562
if (localName == 'blockquote' && classes.isEmpty) {

test/model/content_checks.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,12 @@ extension BlockContentNodeListChecks on Subject<List<BlockContentNode>> {
6969
}
7070
}
7171

72+
extension BlockInlineContainerNodeChecks on Subject<BlockInlineContainerNode> {
73+
Subject<List<InlineContentNode>> get nodes => has((n) => n.nodes, 'nodes');
74+
}
75+
7276
extension ParagraphNodeChecks on Subject<ParagraphNode> {
7377
Subject<bool> get wasImplicit => has((n) => n.wasImplicit, 'wasImplicit');
74-
Subject<List<InlineContentNode>> get nodes => has((n) => n.nodes, 'nodes');
7578
}
7679

7780
extension ListNodeChecks on Subject<ListNode> {
@@ -81,7 +84,6 @@ extension ListNodeChecks on Subject<ListNode> {
8184

8285
extension HeadingNodeChecks on Subject<HeadingNode> {
8386
Subject<HeadingLevel> get level => has((n) => n.level, 'level');
84-
Subject<List<InlineContentNode>> get nodes => has((n) => n.nodes, 'nodes');
8587
}
8688

8789
extension QuotationNodeChecks on Subject<QuotationNode> {

0 commit comments

Comments
 (0)