-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathtable_processor.dart
More file actions
73 lines (60 loc) · 2.35 KB
/
table_processor.dart
File metadata and controls
73 lines (60 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2025 The Flutter 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:jaspr_content/jaspr_content.dart';
/// A node-processing, page extension for Jaspr Content that
/// wraps each `<table>` element in a div with the `table-wrapper` class to
/// enable improved styling and horizontal scrolling.
final class TableWrapperExtension implements PageExtension {
const TableWrapperExtension();
@override
Future<List<Node>> apply(Page page, List<Node> nodes) async {
return _processNodes(nodes, isRoot: true);
}
List<Node> _processNodes(List<Node> nodes, {bool isRoot = false}) {
final processedNodes = <Node>[];
for (var i = 0; i < nodes.length; i++) {
final node = nodes[i];
if (node is ElementNode && node.tag.toLowerCase() == 'table') {
// Check if the previous node was a div with table-wrapper class
// (only check at root level to avoid issues with nested structures).
if (isRoot && i > 0) {
final prevNode = processedNodes.last;
if (prevNode is ElementNode &&
prevNode.tag.toLowerCase() == 'div' &&
(prevNode.attributes['class'] ?? '').contains('table-wrapper')) {
// This table is already wrapped, skip wrapping.
processedNodes.add(_processNode(node));
continue;
}
}
// Wrap the table.
processedNodes.add(
ElementNode('div', {'class': 'table-wrapper'}, [node]),
);
} else {
processedNodes.add(_processNode(node));
}
}
return processedNodes;
}
Node _processNode(Node node) {
if (node is! ElementNode) return node;
final tagName = node.tag.toLowerCase();
// Don't process table elements here as they're handled in _processNodes.
if (tagName == 'table') return node;
// Check if this is already a table-wrapper div.
if (tagName == 'div' &&
(node.attributes['class'] ?? '').contains('table-wrapper')) {
// Don't recurse into table-wrapper divs to avoid double wrapping.
return node;
}
// Recurse into children for other elements.
final nodeChildren = node.children;
return ElementNode(
node.tag,
node.attributes,
nodeChildren != null ? _processNodes(nodeChildren) : null,
);
}
}