Skip to content

Commit 878e070

Browse files
feat: initial release v1.0.0
HyperRender — custom RenderObject HTML/Markdown/Delta renderer for Flutter. Highlights: - CSS float layout with full text reflow (unique among Flutter HTML libs) - W3C two-pass table layout with colspan/rowspan and nested tables - CSS Grid, Flexbox, CSS Variables, calc(), RTL/BiDi - <ruby>/<rt> furigana, kinsoku shori line-breaking - <details>/<summary> collapsible sections - Text selection with context menu (crash-free on large documents) - Image LRU cache (50 MB), viewport culling, virtualized ListView - HTML sanitizer: XSS, javascript:/vbscript: URLs, CSS expression() - Accessibility: ARIA roles, landmark elements, list ordinal hints - Screenshot export via captureKey + HyperCaptureExtension - CommonMark + GFM Markdown adapter, Quill Delta adapter - 97+ unit/integration/golden tests passing
0 parents  commit 878e070

400 files changed

Lines changed: 82047 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/analyze.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Static Analysis
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
analyze:
11+
name: Analyze Code
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Flutter
19+
uses: subosito/flutter-action@v2
20+
with:
21+
channel: stable
22+
cache: true
23+
24+
- name: Get dependencies
25+
run: flutter pub get
26+
27+
- name: Run flutter analyze
28+
run: flutter analyze --no-pub > analyze_report.txt || true
29+
30+
- name: Check for errors
31+
run: |
32+
errors=$(grep -c "error •" analyze_report.txt || true)
33+
warnings=$(grep -c "warning •" analyze_report.txt || true)
34+
infos=$(grep -c "info •" analyze_report.txt || true)
35+
36+
echo "Static Analysis Results:"
37+
echo " Errors: $errors"
38+
echo " Warnings: $warnings"
39+
echo " Infos: $infos"
40+
41+
# Fail if there are errors
42+
if [ "$errors" -gt 0 ]; then
43+
echo "❌ Found $errors errors"
44+
cat analyze_report.txt
45+
exit 1
46+
fi
47+
48+
# Warn if there are many warnings
49+
if [ "$warnings" -gt 20 ]; then
50+
echo "⚠️ High number of warnings: $warnings"
51+
fi
52+
53+
echo "✅ Static analysis passed"
54+
55+
- name: Upload analyze report
56+
if: always()
57+
uses: actions/upload-artifact@v4
58+
with:
59+
name: analyze-report
60+
path: analyze_report.txt

.github/workflows/benchmark.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Benchmarks
2+
3+
on:
4+
# Run benchmarks weekly
5+
schedule:
6+
- cron: '0 0 * * 0' # Every Sunday at midnight UTC
7+
8+
# Allow manual trigger
9+
workflow_dispatch:
10+
11+
# Run on release branches
12+
push:
13+
branches:
14+
- 'release/**'
15+
16+
jobs:
17+
benchmark:
18+
name: Run Performance Benchmarks
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v4
24+
25+
- name: Setup Flutter
26+
uses: subosito/flutter-action@v2
27+
with:
28+
channel: stable
29+
cache: true
30+
31+
- name: Get dependencies
32+
run: flutter pub get
33+
34+
- name: Run benchmarks
35+
run: |
36+
echo "Running benchmarks..."
37+
flutter test benchmark/ --no-test-randomize-ordering-seed
38+
39+
- name: Save benchmark results
40+
run: |
41+
mkdir -p benchmark_results
42+
echo "Date: $(date)" > benchmark_results/latest.txt
43+
echo "Commit: ${{ github.sha }}" >> benchmark_results/latest.txt
44+
echo "" >> benchmark_results/latest.txt
45+
echo "See test output above for detailed results" >> benchmark_results/latest.txt
46+
47+
- name: Upload benchmark results
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: benchmark-results
51+
path: benchmark_results/
52+
53+
- name: Comment on PR (if applicable)
54+
if: github.event_name == 'pull_request'
55+
uses: actions/github-script@v7
56+
with:
57+
script: |
58+
github.rest.issues.createComment({
59+
issue_number: context.issue.number,
60+
owner: context.repo.owner,
61+
repo: context.repo.repo,
62+
body: '🏎️ Benchmark tests completed. Check the Actions tab for detailed results.'
63+
})

.github/workflows/coverage.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Coverage
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
coverage:
11+
name: Generate Coverage
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Flutter
19+
uses: subosito/flutter-action@v2
20+
with:
21+
channel: stable
22+
cache: true
23+
24+
- name: Install dependencies
25+
run: flutter pub get
26+
27+
- name: Run tests with coverage
28+
run: flutter test --coverage
29+
30+
- name: Upload coverage to Codecov
31+
uses: codecov/codecov-action@v4
32+
with:
33+
file: ./coverage/lcov.info
34+
fail_ci_if_error: false
35+
token: ${{ secrets.CODECOV_TOKEN }}
36+
37+
- name: Check coverage threshold
38+
run: |
39+
sudo apt-get install -y lcov
40+
total=$(lcov --summary coverage/lcov.info 2>&1 | grep "lines" | awk '{print $2}' | cut -d'%' -f1)
41+
echo "Coverage: $total%"
42+
43+
if (( $(echo "$total < 65" | bc -l) )); then
44+
echo "❌ Coverage below 65% threshold: $total%"
45+
exit 1
46+
else
47+
echo "✅ Coverage meets threshold: $total%"
48+
fi
49+
50+
- name: Generate HTML report
51+
run: |
52+
genhtml coverage/lcov.info -o coverage/html
53+
54+
- name: Upload HTML report
55+
uses: actions/upload-artifact@v4
56+
with:
57+
name: coverage-report
58+
path: coverage/html

.github/workflows/golden.yml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Visual Regression
2+
3+
on:
4+
pull_request:
5+
branches: [main, develop]
6+
push:
7+
branches: [main]
8+
9+
jobs:
10+
golden:
11+
name: Golden Tests
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Flutter
19+
uses: subosito/flutter-action@v2
20+
with:
21+
channel: stable
22+
cache: true
23+
24+
- name: Get dependencies
25+
run: flutter pub get
26+
27+
- name: Run golden tests
28+
id: golden
29+
run: |
30+
flutter test test/golden/ \
31+
--reporter json \
32+
> golden_results.json 2>&1 || true
33+
34+
# Count failures
35+
FAILURES=$(grep -c '"result":"error"' golden_results.json 2>/dev/null || echo 0)
36+
echo "failures=$FAILURES" >> "$GITHUB_OUTPUT"
37+
38+
# Exit with error if there were failures
39+
if [ "$FAILURES" -gt "0" ]; then
40+
echo "::error::$FAILURES golden test(s) failed"
41+
exit 1
42+
fi
43+
44+
- name: Upload failure diffs
45+
if: failure()
46+
uses: actions/upload-artifact@v4
47+
with:
48+
name: golden-failures-${{ github.run_number }}
49+
path: |
50+
test/golden/goldens/failures/
51+
golden_results.json
52+
retention-days: 14
53+
54+
- name: Post PR comment on failure
55+
if: failure() && github.event_name == 'pull_request'
56+
uses: actions/github-script@v7
57+
with:
58+
script: |
59+
const failures = '${{ steps.golden.outputs.failures }}';
60+
await github.rest.issues.createComment({
61+
owner: context.repo.owner,
62+
repo: context.repo.repo,
63+
issue_number: context.issue.number,
64+
body: [
65+
'## ❌ Visual Regression Detected',
66+
'',
67+
`**${failures} golden test(s) failed.**`,
68+
'',
69+
'The rendered output no longer matches the reference images.',
70+
'',
71+
'**If the change is intentional**, regenerate the goldens locally:',
72+
'```bash',
73+
'flutter test test/golden/ --update-goldens',
74+
'git add test/golden/goldens/',
75+
'git commit -m "chore: update golden references"',
76+
'```',
77+
'',
78+
'Download the diff artifacts from this workflow run to inspect changes.',
79+
].join('\n'),
80+
});
81+
82+
# Separate job: update goldens on direct push to main (manual trigger)
83+
update-goldens:
84+
name: Update Goldens (manual)
85+
runs-on: ubuntu-latest
86+
if: github.event_name == 'workflow_dispatch'
87+
88+
steps:
89+
- name: Checkout
90+
uses: actions/checkout@v4
91+
with:
92+
token: ${{ secrets.GITHUB_TOKEN }}
93+
94+
- name: Setup Flutter
95+
uses: subosito/flutter-action@v2
96+
with:
97+
channel: stable
98+
cache: true
99+
100+
- name: Get dependencies
101+
run: flutter pub get
102+
103+
- name: Regenerate goldens
104+
run: flutter test test/golden/ --update-goldens
105+
106+
- name: Commit updated goldens
107+
run: |
108+
git config user.name "github-actions[bot]"
109+
git config user.email "github-actions[bot]@users.noreply.github.com"
110+
git add test/golden/goldens/
111+
git diff --staged --quiet || git commit -m "chore: regenerate golden references [skip ci]"
112+
git push

.github/workflows/test.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
test:
11+
name: Run Tests
12+
runs-on: ${{ matrix.os }}
13+
14+
strategy:
15+
matrix:
16+
os: [ubuntu-latest, macos-latest, windows-latest]
17+
flutter-channel: [stable, beta]
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Flutter
24+
uses: subosito/flutter-action@v2
25+
with:
26+
channel: ${{ matrix.flutter-channel }}
27+
cache: true
28+
29+
- name: Get dependencies
30+
run: flutter pub get
31+
32+
- name: Verify formatting
33+
run: dart format --set-exit-if-changed .
34+
if: matrix.os == 'ubuntu-latest' && matrix.flutter-channel == 'stable'
35+
36+
- name: Analyze code
37+
run: flutter analyze
38+
39+
- name: Run tests
40+
run: flutter test
41+
42+
- name: Upload test results
43+
if: failure()
44+
uses: actions/upload-artifact@v4
45+
with:
46+
name: test-results-${{ matrix.os }}-${{ matrix.flutter-channel }}
47+
path: test/**/*.dart

0 commit comments

Comments
 (0)