Merge branch 'master' into maybe-sync-signal
This commit is contained in:
41 files changed
+15956
-389
No files matched your search
+132
-50
@@ -27,93 +27,177 @@ on:
|
|||||||
- lib.rs
|
- lib.rs
|
||||||
- Cargo.toml
|
- Cargo.toml
|
||||||
|
|
||||||
|
# workflow_dispatch:
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
CARGO_INCREMENTAL: "0"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
name: Check
|
name: Check
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
SCCACHE_GHA_ENABLED: "true"
|
|
||||||
RUSTC_WRAPPER: "sccache"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: mozilla-actions/sccache-action@v0.0.3
|
|
||||||
- uses: ilammy/setup-nasm@v1
|
|
||||||
- run: sudo apt-get update
|
|
||||||
- run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- run: sudo apt-get update
|
||||||
|
- run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
|
- uses: ilammy/setup-nasm@v1
|
||||||
- run: cargo check --all --examples --tests
|
- run: cargo check --all --examples --tests
|
||||||
|
|
||||||
test:
|
test:
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
name: Test Suite
|
name: Test Suite
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
SCCACHE_GHA_ENABLED: "true"
|
|
||||||
RUSTC_WRAPPER: "sccache"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: actions/checkout@v4
|
||||||
- uses: mozilla-actions/sccache-action@v0.0.3
|
|
||||||
- uses: ilammy/setup-nasm@v1
|
|
||||||
- run: sudo apt-get update
|
- run: sudo apt-get update
|
||||||
- run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev
|
- run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
|
- uses: ilammy/setup-nasm@v1
|
||||||
- uses: davidB/rust-cargo-make@v1
|
- uses: davidB/rust-cargo-make@v1
|
||||||
- uses: browser-actions/setup-firefox@latest
|
- uses: browser-actions/setup-firefox@latest
|
||||||
- uses: jetli/wasm-pack-action@v0.4.0
|
- uses: jetli/wasm-pack-action@v0.4.0
|
||||||
- uses: actions/checkout@v4
|
- run: sudo rm -rf /usr/share/dotnet
|
||||||
|
- run: sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
|
- run: |
|
||||||
|
df -h
|
||||||
|
sudo rm -rf ${GITHUB_WORKSPACE}/.git
|
||||||
|
df -h
|
||||||
- run: cargo make tests
|
- run: cargo make tests
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
name: Rustfmt
|
name: Rustfmt
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
SCCACHE_GHA_ENABLED: "true"
|
|
||||||
RUSTC_WRAPPER: "sccache"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: mozilla-actions/sccache-action@v0.0.3
|
|
||||||
- uses: ilammy/setup-nasm@v1
|
|
||||||
- run: rustup component add rustfmt
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ilammy/setup-nasm@v1
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
components: rustfmt
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
- run: cargo fmt --all -- --check
|
- run: cargo fmt --all -- --check
|
||||||
|
|
||||||
clippy:
|
clippy:
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
name: Clippy
|
name: Clippy
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
SCCACHE_GHA_ENABLED: "true"
|
|
||||||
RUSTC_WRAPPER: "sccache"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: actions/checkout@v4
|
||||||
- uses: mozilla-actions/sccache-action@v0.0.3
|
|
||||||
- uses: ilammy/setup-nasm@v1
|
|
||||||
- run: sudo apt-get update
|
- run: sudo apt-get update
|
||||||
- run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev
|
- run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev
|
||||||
- run: rustup component add clippy
|
- uses: ilammy/setup-nasm@v1
|
||||||
- uses: actions/checkout@v4
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
components: rustfmt, clippy
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
- run: cargo clippy --workspace --examples --tests -- -D warnings
|
- run: cargo clippy --workspace --examples --tests -- -D warnings
|
||||||
|
|
||||||
|
miri:
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
name: Miri
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CARGO_UNSTABLE_SPARSE_REGISTRY: 'true'
|
||||||
|
RUSTFLAGS: -Dwarnings
|
||||||
|
RUST_BACKTRACE: 1
|
||||||
|
MIRIFLAGS: -Zmiri-tag-gc=1
|
||||||
|
# Change to specific Rust release to pin
|
||||||
|
rust_stable: stable
|
||||||
|
rust_nightly: nightly-2023-11-16
|
||||||
|
rust_clippy: 1.70.0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ilammy/setup-nasm@v1
|
||||||
|
- name: Install Rust ${{ env.rust_nightly }}
|
||||||
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
with:
|
||||||
|
toolchain: ${{ env.rust_nightly }}
|
||||||
|
components: miri
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
|
- name: miri
|
||||||
|
# Many of tests in tokio/tests and doctests use #[tokio::test] or
|
||||||
|
# #[tokio::main] that calls epoll_create1 that Miri does not support.
|
||||||
|
# run: cargo miri test --features full --lib --no-fail-fast
|
||||||
|
run: |
|
||||||
|
cargo miri test --package dioxus-core -- --exact --nocapture
|
||||||
|
cargo miri test --package dioxus-native-core --test miri_native -- --exact --nocapture
|
||||||
|
env:
|
||||||
|
MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields
|
||||||
|
PROPTEST_CASES: 10
|
||||||
|
|
||||||
|
playwright:
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
name: Playwright Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Do our best to cache the toolchain and node install steps
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: ilammy/setup-nasm@v1
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
targets: x86_64-unknown-linux-gnu,wasm32-unknown-unknown
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
working-directory: ./playwright-tests
|
||||||
|
|
||||||
|
- name: Install Playwright
|
||||||
|
run: npm install -D @playwright/test
|
||||||
|
working-directory: ./playwright-tests
|
||||||
|
|
||||||
|
- name: Install Playwright Browsers
|
||||||
|
run: npx playwright install --with-deps
|
||||||
|
working-directory: ./playwright-tests
|
||||||
|
|
||||||
|
- name: Run Playwright tests
|
||||||
|
run: npx playwright test
|
||||||
|
working-directory: ./playwright-tests
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: playwright-report
|
||||||
|
path: playwright-report/
|
||||||
|
retention-days: 30
|
||||||
|
|
||||||
|
|
||||||
matrix_test:
|
matrix_test:
|
||||||
runs-on: ${{ matrix.platform.os }}
|
runs-on: ${{ matrix.platform.os }}
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
CARGO_INCREMENTAL: 0
|
|
||||||
SCCACHE_GHA_ENABLED: "true"
|
|
||||||
RUSTC_WRAPPER: "sccache"
|
|
||||||
RUST_CARGO_COMMAND: ${{ matrix.platform.cross == true && 'cross' || 'cargo' }}
|
RUST_CARGO_COMMAND: ${{ matrix.platform.cross == true && 'cross' || 'cargo' }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -159,20 +243,18 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
toolchain: ${{ matrix.platform.toolchain }}
|
toolchain: ${{ matrix.platform.toolchain }}
|
||||||
targets: ${{ matrix.platform.target }}
|
targets: ${{ matrix.platform.target }}
|
||||||
|
components: rustfmt
|
||||||
|
|
||||||
- name: Install cross
|
- name: Install cross
|
||||||
if: ${{ matrix.platform.cross == true }}
|
if: ${{ matrix.platform.cross == true }}
|
||||||
|
|
||||||
uses: taiki-e/install-action@cross
|
uses: taiki-e/install-action@cross
|
||||||
|
|
||||||
- uses: mozilla-actions/sccache-action@v0.0.3
|
- uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
workspaces: core -> ../target
|
key: "${{ matrix.platform.target }}"
|
||||||
save-if: ${{ matrix.features.key == 'all' }}
|
cache-all-crates: "true"
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
||||||
- name: Install rustfmt
|
|
||||||
run: rustup component add rustfmt
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
name: Miri Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
# Run in PRs and for bors, but not on master.
|
|
||||||
branches:
|
|
||||||
- 'auto'
|
|
||||||
- 'try'
|
|
||||||
paths:
|
|
||||||
- packages/**
|
|
||||||
- examples/**
|
|
||||||
- src/**
|
|
||||||
- .github/**
|
|
||||||
- lib.rs
|
|
||||||
- Cargo.toml
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened, ready_for_review]
|
|
||||||
branches:
|
|
||||||
- 'master'
|
|
||||||
schedule:
|
|
||||||
- cron: '6 6 * * *' # At 6:06 UTC every day.
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_UNSTABLE_SPARSE_REGISTRY: 'true'
|
|
||||||
RUSTFLAGS: -Dwarnings
|
|
||||||
RUST_BACKTRACE: 1
|
|
||||||
# Change to specific Rust release to pin
|
|
||||||
rust_stable: stable
|
|
||||||
rust_nightly: nightly-2023-11-16
|
|
||||||
rust_clippy: 1.70.0
|
|
||||||
# When updating this, also update:
|
|
||||||
# - README.md
|
|
||||||
# - tokio/README.md
|
|
||||||
# - CONTRIBUTING.md
|
|
||||||
# - tokio/Cargo.toml
|
|
||||||
# - tokio-util/Cargo.toml
|
|
||||||
# - tokio-test/Cargo.toml
|
|
||||||
# - tokio-stream/Cargo.toml
|
|
||||||
# rust_min: 1.49.0
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
env:
|
|
||||||
RUST_BACKTRACE: 1
|
|
||||||
HOST_TARGET: ${{ matrix.host_target }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: ubuntu-latest
|
|
||||||
host_target: x86_64-unknown-linux-gnu
|
|
||||||
# - os: macos-latest
|
|
||||||
# host_target: x86_64-apple-darwin
|
|
||||||
# - os: windows-latest
|
|
||||||
# host_target: i686-pc-windows-msvc
|
|
||||||
# - os: windows-latest
|
|
||||||
# host_target: i686-pc-windows-msvc
|
|
||||||
# - os: windows-latest
|
|
||||||
# host_target: i686-pc-windows-msvc
|
|
||||||
# - os: windows-latest
|
|
||||||
# host_target: i686-pc-windows-msvc
|
|
||||||
steps:
|
|
||||||
- name: Set the tag GC interval to 1 on linux
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: echo "MIRIFLAGS=-Zmiri-tag-gc=1" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: ilammy/setup-nasm@v1
|
|
||||||
- name: Install Rust ${{ env.rust_nightly }}
|
|
||||||
uses: dtolnay/rust-toolchain@master
|
|
||||||
with:
|
|
||||||
toolchain: ${{ env.rust_nightly }}
|
|
||||||
components: miri
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
- name: miri
|
|
||||||
# Many of tests in tokio/tests and doctests use #[tokio::test] or
|
|
||||||
# #[tokio::main] that calls epoll_create1 that Miri does not support.
|
|
||||||
# run: cargo miri test --features full --lib --no-fail-fast
|
|
||||||
run: |
|
|
||||||
cargo miri test --package dioxus-core -- --exact --nocapture
|
|
||||||
cargo miri test --package dioxus-native-core --test miri_native -- --exact --nocapture
|
|
||||||
|
|
||||||
# working-directory: tokio
|
|
||||||
env:
|
|
||||||
MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields
|
|
||||||
PROPTEST_CASES: 10
|
|
||||||
|
|
||||||
# Cache the global cargo directory, but NOT the local `target` directory which
|
|
||||||
# we cannot reuse anyway when the nightly changes (and it grows quite large
|
|
||||||
# over time).
|
|
||||||
# - name: Add cache for cargo
|
|
||||||
# id: cache
|
|
||||||
# uses: actions/cache@v3
|
|
||||||
# with:
|
|
||||||
# path: |
|
|
||||||
# # Taken from <https://doc.rust-lang.org/nightly/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci>.
|
|
||||||
# ~/.cargo/bin
|
|
||||||
# ~/.cargo/registry/index
|
|
||||||
# ~/.cargo/registry/cache
|
|
||||||
# ~/.cargo/git/db
|
|
||||||
# # contains package information of crates installed via `cargo install`.
|
|
||||||
# ~/.cargo/.crates.toml
|
|
||||||
# ~/.cargo/.crates2.json
|
|
||||||
# key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
||||||
# restore-keys: ${{ runner.os }}-cargo
|
|
||||||
|
|
||||||
# - name: Install rustup-toolchain-install-master
|
|
||||||
# if: ${{ steps.cache.outputs.cache-hit != 'true' }}
|
|
||||||
# shell: bash
|
|
||||||
# run: |
|
|
||||||
# cargo install -f rustup-toolchain-install-master
|
|
||||||
# - name: Install "master" toolchain
|
|
||||||
# shell: bash
|
|
||||||
# run: |
|
|
||||||
# if [[ ${{ github.event_name }} == 'schedule' ]]; then
|
|
||||||
# echo "Building against latest rustc git version"
|
|
||||||
# git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1 > rust-version
|
|
||||||
# fi
|
|
||||||
# toolchain --host ${{ matrix.host_target }}
|
|
||||||
# - name: Show Rust version
|
|
||||||
# run: |
|
|
||||||
# rustup show
|
|
||||||
# rustc -Vv
|
|
||||||
# cargo -V
|
|
||||||
# - name: Test
|
|
||||||
# run: |
|
|
||||||
# MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks" cargo +nightly miri test --package dioxus-core --test miri_stress -- --exact --nocapture
|
|
||||||
# MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks" cargo +nightly miri test --package dioxus-native-core --test miri_native -- --exact --nocapture
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
name: Playwright Tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main, master]
|
|
||||||
pull_request:
|
|
||||||
branches: [main, master]
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: ./playwright-tests
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
if: github.event.pull_request.draft == false
|
|
||||||
timeout-minutes: 60
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Do our best to cache the toolchain and node install steps
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: ilammy/setup-nasm@v1
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- name: Install Rust
|
|
||||||
uses: dtolnay/rust-toolchain@master
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
targets: x86_64-unknown-linux-gnu,wasm32-unknown-unknown
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
- name: Install Playwright
|
|
||||||
run: npm install -D @playwright/test
|
|
||||||
- name: Install Playwright Browsers
|
|
||||||
run: npx playwright install --with-deps
|
|
||||||
# Cache the CLI by using cargo run internally
|
|
||||||
# - name: Install Dioxus CLI
|
|
||||||
# uses: actions-rs/cargo@v1
|
|
||||||
# with:
|
|
||||||
# command: install
|
|
||||||
# args: --path packages/cli
|
|
||||||
- name: Run Playwright tests
|
|
||||||
run: npx playwright test
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: playwright-report
|
|
||||||
path: playwright-report/
|
|
||||||
retention-days: 30
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
name: Clear cache
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
actions: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
clear-cache:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clear cache
|
||||||
|
uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.cache_controller }}
|
||||||
|
script: |
|
||||||
|
console.log("About to clear")
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const caches = await github.rest.actions.getActionsCacheList({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
})
|
||||||
|
if (caches.data.actions_caches.length === 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for (const cache of caches.data.actions_caches) {
|
||||||
|
console.log(cache)
|
||||||
|
github.rest.actions.deleteActionsCacheById({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
cache_id: cache.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Clear completed")
|
||||||
+3
-1
@@ -2,10 +2,12 @@
|
|||||||
/playwright-tests/web/dist
|
/playwright-tests/web/dist
|
||||||
/playwright-tests/fullstack/dist
|
/playwright-tests/fullstack/dist
|
||||||
/dist
|
/dist
|
||||||
Cargo.lock
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/examples/assets/test_video.mp4
|
/examples/assets/test_video.mp4
|
||||||
|
|
||||||
|
# new recommendation to keep the lockfile in for CI and reproducible builds
|
||||||
|
# Cargo.lock
|
||||||
|
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
|
|||||||
Generated
+12339
File diff suppressed because it is too large.
Load diff
+8
-3
@@ -98,6 +98,12 @@ thiserror = "1.0.40"
|
|||||||
prettyplease = { package = "prettier-please", version = "0.2", features = [
|
prettyplease = { package = "prettier-please", version = "0.2", features = [
|
||||||
"verbatim",
|
"verbatim",
|
||||||
] }
|
] }
|
||||||
|
manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", rev = "94ea6f7", features = [
|
||||||
|
"webp",
|
||||||
|
"html",
|
||||||
|
] }
|
||||||
|
manganis = { git = "https://github.com/DioxusLabs/collect-assets", rev = "94ea6f7" }
|
||||||
|
|
||||||
|
|
||||||
# This is a "virtual package"
|
# This is a "virtual package"
|
||||||
# It is not meant to be published, but is used so "cargo run --example XYZ" works properly
|
# It is not meant to be published, but is used so "cargo run --example XYZ" works properly
|
||||||
@@ -136,8 +142,7 @@ reqwest = { version = "0.11.9", features = ["json"] }
|
|||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
simple_logger = "4.0.0"
|
simple_logger = "4.0.0"
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
manganis = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tracing-subscriber = "0.3.17"
|
tracing-subscriber = "0.3.17"
|
||||||
http-range = "0.1.5"
|
http-range = "0.1.5"
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ fn app(cx: Scope) -> Element {
|
|||||||
p {
|
p {
|
||||||
"This should show an image:"
|
"This should show an image:"
|
||||||
}
|
}
|
||||||
img { src: mg!(image("examples/assets/logo.png").format(ImageType::Avif)).to_string() }
|
img { src: manganis::mg!(image("examples/assets/logo.png").format(ImageType::Avif)).to_string() }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ fn main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const _STYLE: &str = mg!(file("./examples/assets/fileexplorer.css"));
|
const _STYLE: &str = manganis::mg!(file("./examples/assets/fileexplorer.css"));
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let files = use_ref(cx, Files::new);
|
let files = use_ref(cx, Files::new);
|
||||||
|
|||||||
Generated
+3240
File diff suppressed because it is too large.
Load diff
@@ -13,6 +13,7 @@ publish = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dioxus = { path = "../../packages/dioxus" }
|
dioxus = { path = "../../packages/dioxus" }
|
||||||
|
manganis = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
dioxus-desktop = { path = "../../packages/desktop" }
|
dioxus-desktop = { path = "../../packages/desktop" }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
const _STYLE: &str = mg!(file("./public/tailwind.css"));
|
const _STYLE: &str = manganis::mg!(file("./public/tailwind.css"));
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ fn main() {
|
|||||||
dioxus_desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
const _STYLE: &str = mg!(file("./examples/assets/todomvc.css"));
|
const _STYLE: &str = manganis::mg!(file("./examples/assets/todomvc.css"));
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum FilterState {
|
pub enum FilterState {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ impl Writer<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// multiline handlers bump everything down
|
// multiline handlers bump everything down
|
||||||
if attr_len > 1000 {
|
if attr_len > 1000 || self.out.indent.split_line_attributes() {
|
||||||
opt_level = ShortOptimization::NoOpt;
|
opt_level = ShortOptimization::NoOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ impl Writer<'_> {
|
|||||||
|
|
||||||
while let Some(field) = field_iter.next() {
|
while let Some(field) = field_iter.next() {
|
||||||
if !sameline {
|
if !sameline {
|
||||||
self.out.indented_tabbed_line()?;
|
self.out.indented_tabbed_line().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = &field.name;
|
let name = &field.name;
|
||||||
@@ -206,7 +206,7 @@ impl Writer<'_> {
|
|||||||
|
|
||||||
if let Some(exp) = manual_props {
|
if let Some(exp) = manual_props {
|
||||||
if !sameline {
|
if !sameline {
|
||||||
self.out.indented_tabbed_line()?;
|
self.out.indented_tabbed_line().unwrap();
|
||||||
}
|
}
|
||||||
self.write_manual_props(exp)?;
|
self.write_manual_props(exp)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ impl Writer<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// multiline handlers bump everything down
|
// multiline handlers bump everything down
|
||||||
if attr_len > 1000 {
|
if attr_len > 1000 || self.out.indent.split_line_attributes() {
|
||||||
opt_level = ShortOptimization::NoOpt;
|
opt_level = ShortOptimization::NoOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +262,6 @@ impl Writer<'_> {
|
|||||||
}
|
}
|
||||||
ElementAttrValue::EventTokens(tokens) => {
|
ElementAttrValue::EventTokens(tokens) => {
|
||||||
let out = self.retrieve_formatted_expr(tokens).to_string();
|
let out = self.retrieve_formatted_expr(tokens).to_string();
|
||||||
|
|
||||||
let mut lines = out.split('\n').peekable();
|
let mut lines = out.split('\n').peekable();
|
||||||
let first = lines.next().unwrap();
|
let first = lines.next().unwrap();
|
||||||
|
|
||||||
@@ -327,6 +326,10 @@ impl Writer<'_> {
|
|||||||
beginning.is_empty()
|
beginning.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty_children(&self, children: &[BodyNode]) -> bool {
|
||||||
|
children.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
// check if the children are short enough to be on the same line
|
// check if the children are short enough to be on the same line
|
||||||
// We don't have the notion of current line depth - each line tries to be < 80 total
|
// We don't have the notion of current line depth - each line tries to be < 80 total
|
||||||
// returns the total line length if it's short
|
// returns the total line length if it's short
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ pub enum IndentType {
|
|||||||
pub struct IndentOptions {
|
pub struct IndentOptions {
|
||||||
width: usize,
|
width: usize,
|
||||||
indent_string: String,
|
indent_string: String,
|
||||||
|
split_line_attributes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndentOptions {
|
impl IndentOptions {
|
||||||
pub fn new(typ: IndentType, width: usize) -> Self {
|
pub fn new(typ: IndentType, width: usize, split_line_attributes: bool) -> Self {
|
||||||
assert_ne!(width, 0, "Cannot have an indent width of 0");
|
assert_ne!(width, 0, "Cannot have an indent width of 0");
|
||||||
Self {
|
Self {
|
||||||
width,
|
width,
|
||||||
@@ -19,6 +20,7 @@ impl IndentOptions {
|
|||||||
IndentType::Tabs => "\t".into(),
|
IndentType::Tabs => "\t".into(),
|
||||||
IndentType::Spaces => " ".repeat(width),
|
IndentType::Spaces => " ".repeat(width),
|
||||||
},
|
},
|
||||||
|
split_line_attributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,11 +64,15 @@ impl IndentOptions {
|
|||||||
}
|
}
|
||||||
indent
|
indent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn split_line_attributes(&self) -> bool {
|
||||||
|
self.split_line_attributes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for IndentOptions {
|
impl Default for IndentOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(IndentType::Spaces, 4)
|
Self::new(IndentType::Spaces, 4, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,31 +83,31 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn count_indents() {
|
fn count_indents() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents("no indentation here!"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents("no indentation here!"),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents("\t\tv += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents("\t\tv += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents("\t\t v += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents("\t\t v += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 2).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 2, false).count_indents(" v += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,9 @@ pub fn write_block_out(body: CallBody) -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_body(buf: &mut Writer, body: &CallBody) {
|
fn write_body(buf: &mut Writer, body: &CallBody) {
|
||||||
if buf.is_short_children(&body.roots).is_some() {
|
let is_short = buf.is_short_children(&body.roots).is_some();
|
||||||
|
let is_empty = buf.is_empty_children(&body.roots);
|
||||||
|
if (is_short && !buf.out.indent.split_line_attributes()) || is_empty {
|
||||||
// write all the indents with spaces and commas between
|
// write all the indents with spaces and commas between
|
||||||
for idx in 0..body.roots.len() - 1 {
|
for idx in 0..body.roots.len() - 1 {
|
||||||
let ident = &body.roots[idx];
|
let ident = &body.roots[idx];
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ macro_rules! twoway {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4)));
|
twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4, false)));
|
||||||
twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4)));
|
twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4, false)));
|
||||||
|
|
||||||
twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4)));
|
twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4, false)));
|
||||||
twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4)));
|
twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4, false)));
|
||||||
|
|
||||||
twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4)));
|
twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4, false)));
|
||||||
twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4)));
|
twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4, false)));
|
||||||
@@ -76,7 +76,7 @@ toml_edit = "0.19.11"
|
|||||||
tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] }
|
tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] }
|
||||||
tauri-utils = "=1.5.*"
|
tauri-utils = "=1.5.*"
|
||||||
|
|
||||||
manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", features = ["webp", "html"] }
|
manganis-cli-support = { workspace = true, features = ["webp", "html"] }
|
||||||
|
|
||||||
dioxus-autofmt = { workspace = true }
|
dioxus-autofmt = { workspace = true }
|
||||||
dioxus-check = { workspace = true }
|
dioxus-check = { workspace = true }
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ cargo install --path . --debug
|
|||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
Use `dx create project-name` to initialize a new Dioxus project.
|
Use `dx create` to initialize a new Dioxus project.
|
||||||
It will be cloned from the [dioxus-template](https://github.com/DioxusLabs/dioxus-template) repository.
|
It will be cloned from the [dioxus-template](https://github.com/DioxusLabs/dioxus-template) repository.
|
||||||
|
|
||||||
Alternatively, you can specify the template path:
|
Alternatively, you can specify the template path:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
dx create hello --template gh:dioxuslabs/dioxus-template
|
dx create --template gh:dioxuslabs/dioxus-template
|
||||||
```
|
```
|
||||||
|
|
||||||
Run `dx --help` for a list of all the available commands.
|
Run `dx --help` for a list of all the available commands.
|
||||||
|
|||||||
@@ -22,23 +22,33 @@ pub struct Autoformat {
|
|||||||
/// Input file
|
/// Input file
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
pub file: Option<String>,
|
pub file: Option<String>,
|
||||||
|
|
||||||
|
/// Split attributes in lines or not
|
||||||
|
#[clap(short, long, default_value = "false")]
|
||||||
|
pub split_line_attributes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Autoformat {
|
impl Autoformat {
|
||||||
// Todo: autoformat the entire crate
|
// Todo: autoformat the entire crate
|
||||||
pub async fn autoformat(self) -> Result<()> {
|
pub async fn autoformat(self) -> Result<()> {
|
||||||
let Autoformat { check, raw, file } = self;
|
let Autoformat {
|
||||||
|
check,
|
||||||
|
raw,
|
||||||
|
file,
|
||||||
|
split_line_attributes,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
|
||||||
// Default to formatting the project
|
// Default to formatting the project
|
||||||
if raw.is_none() && file.is_none() {
|
if raw.is_none() && file.is_none() {
|
||||||
if let Err(e) = autoformat_project(check).await {
|
if let Err(e) = autoformat_project(check, split_line_attributes).await {
|
||||||
eprintln!("error formatting project: {}", e);
|
eprintln!("error formatting project: {}", e);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw) = raw {
|
if let Some(raw) = raw {
|
||||||
let indent = indentation_for(".")?;
|
let indent = indentation_for(".", self.split_line_attributes)?;
|
||||||
if let Some(inner) = dioxus_autofmt::fmt_block(&raw, 0, indent) {
|
if let Some(inner) = dioxus_autofmt::fmt_block(&raw, 0, indent) {
|
||||||
println!("{}", inner);
|
println!("{}", inner);
|
||||||
} else {
|
} else {
|
||||||
@@ -50,15 +60,15 @@ impl Autoformat {
|
|||||||
|
|
||||||
// Format single file
|
// Format single file
|
||||||
if let Some(file) = file {
|
if let Some(file) = file {
|
||||||
refactor_file(file)?;
|
refactor_file(file, split_line_attributes)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refactor_file(file: String) -> Result<(), Error> {
|
fn refactor_file(file: String, split_line_attributes: bool) -> Result<(), Error> {
|
||||||
let indent = indentation_for(".")?;
|
let indent = indentation_for(".", split_line_attributes)?;
|
||||||
let file_content = if file == "-" {
|
let file_content = if file == "-" {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
std::io::stdin().read_to_string(&mut contents)?;
|
std::io::stdin().read_to_string(&mut contents)?;
|
||||||
@@ -138,7 +148,7 @@ async fn format_file(
|
|||||||
/// Runs using Tokio for multithreading, so it should be really really fast
|
/// Runs using Tokio for multithreading, so it should be really really fast
|
||||||
///
|
///
|
||||||
/// Doesn't do mod-descending, so it will still try to format unreachable files. TODO.
|
/// Doesn't do mod-descending, so it will still try to format unreachable files. TODO.
|
||||||
async fn autoformat_project(check: bool) -> Result<()> {
|
async fn autoformat_project(check: bool, split_line_attributes: bool) -> Result<()> {
|
||||||
let crate_config = dioxus_cli_config::CrateConfig::new(None)?;
|
let crate_config = dioxus_cli_config::CrateConfig::new(None)?;
|
||||||
|
|
||||||
let files_to_format = get_project_files(&crate_config);
|
let files_to_format = get_project_files(&crate_config);
|
||||||
@@ -151,7 +161,7 @@ async fn autoformat_project(check: bool) -> Result<()> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let indent = indentation_for(&files_to_format[0])?;
|
let indent = indentation_for(&files_to_format[0], split_line_attributes)?;
|
||||||
|
|
||||||
let counts = files_to_format
|
let counts = files_to_format
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -185,7 +195,10 @@ async fn autoformat_project(check: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn indentation_for(file_or_dir: impl AsRef<Path>) -> Result<IndentOptions> {
|
fn indentation_for(
|
||||||
|
file_or_dir: impl AsRef<Path>,
|
||||||
|
split_line_attributes: bool,
|
||||||
|
) -> Result<IndentOptions> {
|
||||||
let out = std::process::Command::new("cargo")
|
let out = std::process::Command::new("cargo")
|
||||||
.args(["fmt", "--", "--print-config", "current"])
|
.args(["fmt", "--", "--print-config", "current"])
|
||||||
.arg(file_or_dir.as_ref())
|
.arg(file_or_dir.as_ref())
|
||||||
@@ -225,6 +238,7 @@ fn indentation_for(file_or_dir: impl AsRef<Path>) -> Result<IndentOptions> {
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
tab_spaces,
|
tab_spaces,
|
||||||
|
split_line_attributes,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,6 +287,7 @@ async fn test_auto_fmt() {
|
|||||||
check: false,
|
check: false,
|
||||||
raw: Some(test_rsx),
|
raw: Some(test_rsx),
|
||||||
file: None,
|
file: None,
|
||||||
|
split_line_attributes: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
fmt.autoformat().await.unwrap();
|
fmt.autoformat().await.unwrap();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::ScopeState;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -174,7 +175,14 @@ impl VirtualDom {
|
|||||||
scope.borrowed_props.borrow_mut().clear();
|
scope.borrowed_props.borrow_mut().clear();
|
||||||
|
|
||||||
// Now that all the references are gone, we can safely drop our own references in our listeners.
|
// Now that all the references are gone, we can safely drop our own references in our listeners.
|
||||||
let mut listeners = scope.attributes_to_drop_before_render.borrow_mut();
|
scope.drop_listeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScopeState {
|
||||||
|
/// Drop all listeners that were allocated in the bump allocator.
|
||||||
|
pub(crate) fn drop_listeners(&self) {
|
||||||
|
let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
||||||
listeners.drain(..).for_each(|listener| {
|
listeners.drain(..).for_each(|listener| {
|
||||||
let listener = unsafe { &*listener };
|
let listener = unsafe { &*listener };
|
||||||
if let AttributeValue::Listener(l) = &listener.value {
|
if let AttributeValue::Listener(l) = &listener.value {
|
||||||
|
|||||||
@@ -28,15 +28,14 @@ use crate::innerlude::*;
|
|||||||
#[allow(non_upper_case_globals, non_snake_case)]
|
#[allow(non_upper_case_globals, non_snake_case)]
|
||||||
pub fn Fragment<'a>(cx: Scope<'a, FragmentProps<'a>>) -> Element {
|
pub fn Fragment<'a>(cx: Scope<'a, FragmentProps<'a>>) -> Element {
|
||||||
let children = cx.props.0.as_ref()?;
|
let children = cx.props.0.as_ref()?;
|
||||||
Some(VNode {
|
Some(cx.vnode(
|
||||||
key: children.key,
|
children.parent.clone(),
|
||||||
parent: children.parent.clone(),
|
children.key,
|
||||||
stable_id: children.stable_id.clone(),
|
children.template.clone(),
|
||||||
template: children.template.clone(),
|
children.root_ids.clone(),
|
||||||
root_ids: children.root_ids.clone(),
|
children.dynamic_nodes,
|
||||||
dynamic_nodes: children.dynamic_nodes,
|
children.dynamic_attrs,
|
||||||
dynamic_attrs: children.dynamic_attrs,
|
))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FragmentProps<'a>(Element<'a>);
|
pub struct FragmentProps<'a>(Element<'a>);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use crate::{innerlude::VNode, ScopeState};
|
|||||||
///
|
///
|
||||||
/// ```rust, ignore
|
/// ```rust, ignore
|
||||||
/// LazyNodes::new(|f| {
|
/// LazyNodes::new(|f| {
|
||||||
/// static TEMPLATE: dioxus::core::Template = dioxus::core::Template {
|
/// static TEMPLATE: dioxus::core::Template = dioxus::core::Template {
|
||||||
/// name: "main.rs:5:5:20", // Source location of the template for hot reloading
|
/// name: "main.rs:5:5:20", // Source location of the template for hot reloading
|
||||||
/// roots: &[
|
/// roots: &[
|
||||||
/// dioxus::core::TemplateNode::Element {
|
/// dioxus::core::TemplateNode::Element {
|
||||||
@@ -37,19 +37,19 @@ use crate::{innerlude::VNode, ScopeState};
|
|||||||
/// node_paths: &[],
|
/// node_paths: &[],
|
||||||
/// attr_paths: &[],
|
/// attr_paths: &[],
|
||||||
/// };
|
/// };
|
||||||
/// dioxus::core::VNode {
|
/// f.vnode(
|
||||||
/// parent: None,
|
/// None,
|
||||||
/// key: None,
|
/// None,
|
||||||
/// template: std::cell::Cell::new(TEMPLATE),
|
/// std::cell::Cell::new(TEMPLATE),
|
||||||
/// root_ids: dioxus::core::exports::bumpalo::collections::Vec::with_capacity_in(
|
/// dioxus::core::exports::bumpalo::collections::Vec::with_capacity_in(
|
||||||
/// 1usize,
|
/// 1usize,
|
||||||
/// f.bump(),
|
/// f.bump(),
|
||||||
/// )
|
/// )
|
||||||
/// .into(),
|
/// .into(),
|
||||||
/// dynamic_nodes: f.bump().alloc([]),
|
/// f.bump().alloc([]),
|
||||||
/// dynamic_attrs: f.bump().alloc([]),
|
/// f.bump().alloc([]),
|
||||||
/// })
|
/// )
|
||||||
/// }
|
/// })
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Find more information about how to construct [`VNode`] at <https://dioxuslabs.com/learn/0.4/contributing/walkthrough_readme#the-rsx-macro>
|
/// Find more information about how to construct [`VNode`] at <https://dioxuslabs.com/learn/0.4/contributing/walkthrough_readme#the-rsx-macro>
|
||||||
|
|||||||
+19
-19
@@ -40,6 +40,7 @@ impl<'a> Default for RenderReturn<'a> {
|
|||||||
///
|
///
|
||||||
/// The dynamic parts of the template are stored separately from the static parts. This allows faster diffing by skipping
|
/// The dynamic parts of the template are stored separately from the static parts. This allows faster diffing by skipping
|
||||||
/// static parts of the template.
|
/// static parts of the template.
|
||||||
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct VNode<'a> {
|
pub struct VNode<'a> {
|
||||||
/// The key given to the root of this template.
|
/// The key given to the root of this template.
|
||||||
@@ -70,20 +71,19 @@ pub struct VNode<'a> {
|
|||||||
impl<'a> VNode<'a> {
|
impl<'a> VNode<'a> {
|
||||||
/// Create a template with no nodes that will be skipped over during diffing
|
/// Create a template with no nodes that will be skipped over during diffing
|
||||||
pub fn empty(cx: &'a ScopeState) -> Element<'a> {
|
pub fn empty(cx: &'a ScopeState) -> Element<'a> {
|
||||||
Some(VNode {
|
Some(cx.vnode(
|
||||||
key: None,
|
Cell::new(None),
|
||||||
parent: Default::default(),
|
None,
|
||||||
stable_id: Default::default(),
|
Cell::new(Template {
|
||||||
root_ids: RefCell::new(bumpalo::collections::Vec::new_in(cx.bump())),
|
|
||||||
dynamic_nodes: &[],
|
|
||||||
dynamic_attrs: &[],
|
|
||||||
template: Cell::new(Template {
|
|
||||||
name: "dioxus-empty",
|
name: "dioxus-empty",
|
||||||
roots: &[],
|
roots: &[],
|
||||||
node_paths: &[],
|
node_paths: &[],
|
||||||
attr_paths: &[],
|
attr_paths: &[],
|
||||||
}),
|
}),
|
||||||
})
|
RefCell::new(bumpalo::collections::Vec::new_in(cx.bump())),
|
||||||
|
&[],
|
||||||
|
&[],
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new VNode
|
/// Create a new VNode
|
||||||
@@ -820,16 +820,16 @@ impl<'b> IntoDynNode<'b> for Arguments<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
|
impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
|
||||||
fn into_dyn_node(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
|
fn into_dyn_node(self, cx: &'a ScopeState) -> DynamicNode<'a> {
|
||||||
DynamicNode::Fragment(_cx.bump().alloc([VNode {
|
let vnode = cx.vnode(
|
||||||
parent: self.parent.clone(),
|
self.parent.clone(),
|
||||||
stable_id: self.stable_id.clone(),
|
self.key,
|
||||||
template: self.template.clone(),
|
self.template.clone(),
|
||||||
root_ids: self.root_ids.clone(),
|
self.root_ids.clone(),
|
||||||
key: self.key,
|
self.dynamic_nodes,
|
||||||
dynamic_nodes: self.dynamic_nodes,
|
self.dynamic_attrs,
|
||||||
dynamic_attrs: self.dynamic_attrs,
|
);
|
||||||
}]))
|
DynamicNode::Fragment(cx.bump().alloc([vnode]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ impl Runtime {
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
/// # #[allow(non_snake_case)]
|
||||||
/// fn Component(cx: Scope<ComponentProps>) -> Element {
|
/// fn Component(cx: Scope<ComponentProps>) -> Element {
|
||||||
/// cx.use_hook(|| RuntimeGuard::new(cx.props.runtime.clone()));
|
/// cx.use_hook(|| RuntimeGuard::new(cx.props.runtime.clone()));
|
||||||
///
|
///
|
||||||
|
|||||||
+37
-10
@@ -2,13 +2,13 @@ use crate::{
|
|||||||
any_props::AnyProps,
|
any_props::AnyProps,
|
||||||
any_props::VProps,
|
any_props::VProps,
|
||||||
bump_frame::BumpFrame,
|
bump_frame::BumpFrame,
|
||||||
innerlude::{DynamicNode, EventHandler, VComponent, VNodeId, VText},
|
innerlude::{DynamicNode, ElementRef, EventHandler, VComponent, VNodeId, VText},
|
||||||
lazynodes::LazyNodes,
|
lazynodes::LazyNodes,
|
||||||
nodes::{IntoAttributeValue, IntoDynNode, RenderReturn},
|
nodes::{IntoAttributeValue, IntoDynNode, RenderReturn},
|
||||||
runtime::Runtime,
|
runtime::Runtime,
|
||||||
scope_context::ScopeContext,
|
scope_context::ScopeContext,
|
||||||
AnyValue, Attribute, AttributeType, AttributeValue, Element, Event, MountedAttribute,
|
AnyValue, Attribute, AttributeType, AttributeValue, Element, ElementId, Event,
|
||||||
Properties, TaskId,
|
MountedAttribute, Properties, TaskId, Template, VNode,
|
||||||
};
|
};
|
||||||
use bumpalo::{boxed::Box as BumpBox, Bump};
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
||||||
use std::{
|
use std::{
|
||||||
@@ -102,6 +102,7 @@ pub struct ScopeState {
|
|||||||
|
|
||||||
impl Drop for ScopeState {
|
impl Drop for ScopeState {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
self.drop_listeners();
|
||||||
self.runtime.remove_context(self.context_id);
|
self.runtime.remove_context(self.context_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,19 +346,37 @@ impl<'src> ScopeState {
|
|||||||
/// // Actually build the tree and allocate it
|
/// // Actually build the tree and allocate it
|
||||||
/// cx.render(lazy_tree)
|
/// cx.render(lazy_tree)
|
||||||
/// }
|
/// }
|
||||||
///```
|
/// ```
|
||||||
pub fn render(&'src self, rsx: LazyNodes<'src, '_>) -> Element<'src> {
|
pub fn render(&'src self, rsx: LazyNodes<'src, '_>) -> Element<'src> {
|
||||||
let element = rsx.call(self);
|
// Note: We can't do anything in this function related to safety because the user could always circumvent it by creating a VNode manually and return it without calling this function
|
||||||
|
Some(rsx.call(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a [`crate::VNode`] from the component parts
|
||||||
|
pub fn vnode(
|
||||||
|
&'src self,
|
||||||
|
parent: Cell<Option<ElementRef>>,
|
||||||
|
key: Option<&'src str>,
|
||||||
|
template: Cell<Template<'static>>,
|
||||||
|
root_ids: RefCell<bumpalo::collections::Vec<'src, ElementId>>,
|
||||||
|
dynamic_nodes: &'src [DynamicNode<'src>],
|
||||||
|
dynamic_attrs: &'src [MountedAttribute<'src>],
|
||||||
|
) -> VNode<'src> {
|
||||||
let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
||||||
for attr in element.dynamic_attrs {
|
for attr in dynamic_attrs {
|
||||||
attr.ty.for_each(|attr| {
|
let attrs = match attr.ty {
|
||||||
|
AttributeType::Single(ref attr) => std::slice::from_ref(attr),
|
||||||
|
AttributeType::Many(attrs) => attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
for attr in attrs {
|
||||||
match attr.value {
|
match attr.value {
|
||||||
// We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
|
// We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
|
||||||
AttributeValue::Listener(_) => {
|
AttributeValue::Listener(_) => {
|
||||||
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
||||||
listeners.push(unbounded);
|
listeners.push(unbounded);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to drop any values manually to make sure that their drop implementation is called before the next render
|
// We need to drop any values manually to make sure that their drop implementation is called before the next render
|
||||||
AttributeValue::Any(_) => {
|
AttributeValue::Any(_) => {
|
||||||
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
||||||
@@ -366,7 +385,7 @@ impl<'src> ScopeState {
|
|||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut props = self.borrowed_props.borrow_mut();
|
let mut props = self.borrowed_props.borrow_mut();
|
||||||
@@ -374,7 +393,7 @@ impl<'src> ScopeState {
|
|||||||
.previous_frame()
|
.previous_frame()
|
||||||
.props_to_drop_before_reset
|
.props_to_drop_before_reset
|
||||||
.borrow_mut();
|
.borrow_mut();
|
||||||
for node in element.dynamic_nodes {
|
for node in dynamic_nodes {
|
||||||
if let DynamicNode::Component(comp) = node {
|
if let DynamicNode::Component(comp) = node {
|
||||||
let unbounded = unsafe { std::mem::transmute(comp as *const VComponent) };
|
let unbounded = unsafe { std::mem::transmute(comp as *const VComponent) };
|
||||||
if !comp.static_props {
|
if !comp.static_props {
|
||||||
@@ -384,7 +403,15 @@ impl<'src> ScopeState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(element)
|
VNode {
|
||||||
|
stable_id: Default::default(),
|
||||||
|
key,
|
||||||
|
parent,
|
||||||
|
template,
|
||||||
|
root_ids,
|
||||||
|
dynamic_nodes,
|
||||||
|
dynamic_attrs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a dynamic text node using [`Arguments`] and the [`ScopeState`]'s internal [`Bump`] allocator
|
/// Create a dynamic text node using [`Arguments`] and the [`ScopeState`]'s internal [`Bump`] allocator
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use dioxus::prelude::Props;
|
use dioxus::prelude::Props;
|
||||||
use dioxus_core::{MountedAttribute, *};
|
use dioxus_core::{MountedAttribute, *};
|
||||||
use std::{cfg, collections::HashSet};
|
use std::{cell::Cell, cfg, collections::HashSet};
|
||||||
|
|
||||||
fn random_ns() -> Option<&'static str> {
|
fn random_ns() -> Option<&'static str> {
|
||||||
let namespace = rand::random::<u8>() % 2;
|
let namespace = rand::random::<u8>() % 2;
|
||||||
@@ -171,15 +171,16 @@ fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
|
|||||||
match rand::random::<u8>() % range {
|
match rand::random::<u8>() % range {
|
||||||
0 => DynamicNode::Placeholder(Default::default()),
|
0 => DynamicNode::Placeholder(Default::default()),
|
||||||
1 => cx.make_node((0..(rand::random::<u8>() % 5)).map(|_| {
|
1 => cx.make_node((0..(rand::random::<u8>() % 5)).map(|_| {
|
||||||
VNode::new(
|
cx.vnode(
|
||||||
None,
|
None.into(),
|
||||||
Template {
|
Default::default(),
|
||||||
|
Cell::new(Template {
|
||||||
name: concat!(file!(), ":", line!(), ":", column!(), ":0"),
|
name: concat!(file!(), ":", line!(), ":", column!(), ":0"),
|
||||||
roots: &[TemplateNode::Dynamic { id: 0 }],
|
roots: &[TemplateNode::Dynamic { id: 0 }],
|
||||||
node_paths: &[&[0]],
|
node_paths: &[&[0]],
|
||||||
attr_paths: &[],
|
attr_paths: &[],
|
||||||
},
|
}),
|
||||||
bumpalo::collections::Vec::new_in(cx.bump()),
|
bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||||
cx.bump().alloc([cx.component(
|
cx.bump().alloc([cx.component(
|
||||||
create_random_element,
|
create_random_element,
|
||||||
DepthProps { depth, root: false },
|
DepthProps { depth, root: false },
|
||||||
@@ -273,10 +274,12 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
|
|||||||
)
|
)
|
||||||
.into_boxed_str(),
|
.into_boxed_str(),
|
||||||
));
|
));
|
||||||
let node = VNode::new(
|
println!("{template:#?}");
|
||||||
|
let node = cx.vnode(
|
||||||
|
None.into(),
|
||||||
None,
|
None,
|
||||||
template,
|
Cell::new(template),
|
||||||
bumpalo::collections::Vec::new_in(cx.bump()),
|
bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||||
{
|
{
|
||||||
let dynamic_nodes: Vec<_> = dynamic_node_types
|
let dynamic_nodes: Vec<_> = dynamic_node_types
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -53,10 +53,7 @@ tao = { version = "0.24.0", features = ["rwh_05"] }
|
|||||||
|
|
||||||
[target.'cfg(any(target_os = "windows",target_os = "macos",target_os = "linux",target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
|
[target.'cfg(any(target_os = "windows",target_os = "macos",target_os = "linux",target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
|
||||||
# This is only for debug mode, and it appears mobile does not support some packages this uses
|
# This is only for debug mode, and it appears mobile does not support some packages this uses
|
||||||
manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", optional = true, features = [
|
manganis-cli-support = { workspace = true, optional = true, features = ["webp", "html"] }
|
||||||
"webp",
|
|
||||||
"html",
|
|
||||||
] }
|
|
||||||
rfd = "0.12"
|
rfd = "0.12"
|
||||||
global-hotkey = "0.4.1"
|
global-hotkey = "0.4.1"
|
||||||
muda = "0.11.3"
|
muda = "0.11.3"
|
||||||
@@ -76,7 +73,7 @@ fullscreen = ["wry/fullscreen"]
|
|||||||
transparent = ["wry/transparent"]
|
transparent = ["wry/transparent"]
|
||||||
devtools = ["wry/devtools"]
|
devtools = ["wry/devtools"]
|
||||||
hot-reload = ["dioxus-hot-reload"]
|
hot-reload = ["dioxus-hot-reload"]
|
||||||
asset-collect = ["manganis-cli-support"]
|
collect-assets = ["manganis-cli-support"]
|
||||||
gnu = []
|
gnu = []
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ impl<P: 'static> App<P> {
|
|||||||
pub fn new(cfg: Config, props: P, root: Component<P>) -> (EventLoop<UserWindowEvent>, Self) {
|
pub fn new(cfg: Config, props: P, root: Component<P>) -> (EventLoop<UserWindowEvent>, Self) {
|
||||||
let event_loop = EventLoopBuilder::<UserWindowEvent>::with_user_event().build();
|
let event_loop = EventLoopBuilder::<UserWindowEvent>::with_user_event().build();
|
||||||
|
|
||||||
let mut app = Self {
|
let app = Self {
|
||||||
root,
|
root,
|
||||||
window_behavior: cfg.last_window_close_behaviour,
|
window_behavior: cfg.last_window_close_behaviour,
|
||||||
is_visible_before_start: true,
|
is_visible_before_start: true,
|
||||||
@@ -109,7 +109,7 @@ impl<P: 'static> App<P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
pub fn connect_hotreload(&mut self) {
|
pub fn connect_hotreload(&self) {
|
||||||
dioxus_hot_reload::connect({
|
dioxus_hot_reload::connect({
|
||||||
let proxy = self.shared.proxy.clone();
|
let proxy = self.shared.proxy.clone();
|
||||||
move |template| {
|
move |template| {
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ pub fn launch_with_props_blocking<P: 'static>(root: Component<P>, props: P, cfg:
|
|||||||
EventData::Poll => app.poll_vdom(id),
|
EventData::Poll => app.poll_vdom(id),
|
||||||
EventData::NewWindow => app.handle_new_window(),
|
EventData::NewWindow => app.handle_new_window(),
|
||||||
EventData::CloseWindow => app.handle_close_msg(id),
|
EventData::CloseWindow => app.handle_close_msg(id),
|
||||||
|
#[cfg(feature = "hot-reload")]
|
||||||
EventData::HotReloadEvent(msg) => app.handle_hot_reload_msg(msg),
|
EventData::HotReloadEvent(msg) => app.handle_hot_reload_msg(msg),
|
||||||
EventData::Ipc(msg) => match msg.method() {
|
EventData::Ipc(msg) => match msg.method() {
|
||||||
IpcMethod::FileDialog => app.handle_file_dialog_msg(msg, id),
|
IpcMethod::FileDialog => app.handle_file_dialog_msg(msg, id),
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ fn Grid(cx: Scope<GridProps>) -> Element {
|
|||||||
let alpha = y as f32*100.0/size as f32 + counts.read()[x*size + y] as f32;
|
let alpha = y as f32*100.0/size as f32 + counts.read()[x*size + y] as f32;
|
||||||
let key = format!("{}-{}", x, y);
|
let key = format!("{}-{}", x, y);
|
||||||
rsx! {
|
rsx! {
|
||||||
Box{
|
Box {
|
||||||
x: x,
|
x: x,
|
||||||
y: y,
|
y: y,
|
||||||
alpha: 100.0,
|
alpha: 100.0,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ dioxus-html = { workspace = true, optional = true }
|
|||||||
dioxus-core-macro = { workspace = true, optional = true }
|
dioxus-core-macro = { workspace = true, optional = true }
|
||||||
dioxus-hooks = { workspace = true, optional = true }
|
dioxus-hooks = { workspace = true, optional = true }
|
||||||
dioxus-rsx = { workspace = true, optional = true }
|
dioxus-rsx = { workspace = true, optional = true }
|
||||||
manganis = { git = "https://github.com/DioxusLabs/collect-assets" }
|
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
dioxus-hot-reload = { workspace = true, optional = true }
|
dioxus-hot-reload = { workspace = true, optional = true }
|
||||||
@@ -37,8 +36,6 @@ criterion = "0.3.5"
|
|||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
tokio = { workspace = true, features = ["full"] }
|
tokio = { workspace = true, features = ["full"] }
|
||||||
# dioxus-edit-stream = { workspace = true }
|
|
||||||
|
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "jsframework"
|
name = "jsframework"
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ pub use dioxus_rsx as rsx;
|
|||||||
pub use dioxus_core_macro as core_macro;
|
pub use dioxus_core_macro as core_macro;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use manganis;
|
|
||||||
pub use manganis::mg;
|
|
||||||
|
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
pub use crate::hooks::*;
|
pub use crate::hooks::*;
|
||||||
|
|
||||||
|
|||||||
Generated
+6
-6
@@ -1654,9 +1654,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.1",
|
"version": "1.15.4",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||||
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
|
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -4973,9 +4973,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.15.1",
|
"version": "1.15.4",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||||
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
|
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fs-constants": {
|
"fs-constants": {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub fn format_rsx(raw: String, use_tabs: bool, indent_size: usize) -> String {
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
indent_size,
|
indent_size,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
block.unwrap()
|
block.unwrap()
|
||||||
@@ -32,6 +33,7 @@ pub fn format_selection(raw: String, use_tabs: bool, indent_size: usize) -> Stri
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
indent_size,
|
indent_size,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
block.unwrap()
|
block.unwrap()
|
||||||
@@ -67,6 +69,7 @@ pub fn format_file(contents: String, use_tabs: bool, indent_size: usize) -> Form
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
indent_size,
|
indent_size,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let out = dioxus_autofmt::apply_formats(&contents, _edits.clone());
|
let out = dioxus_autofmt::apply_formats(&contents, _edits.clone());
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ web-sys = { version = "0.3.61", features = ["Window", "Document", "Element", "Ht
|
|||||||
|
|
||||||
[target.'cfg(any(target_os = "windows",target_os = "macos",target_os = "linux",target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
|
[target.'cfg(any(target_os = "windows",target_os = "macos",target_os = "linux",target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
|
||||||
# This is only for debug mode, and it appears mobile does not support some packages this uses
|
# This is only for debug mode, and it appears mobile does not support some packages this uses
|
||||||
manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", features = ["webp", "html"] }
|
manganis-cli-support = { workspace = true, features = ["webp", "html"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["hot-reload"]
|
default = ["hot-reload"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::{any::Any, collections::HashMap};
|
use std::any::Any;
|
||||||
|
|
||||||
pub trait HasFileData: std::any::Any {
|
pub trait HasFileData: std::any::Any {
|
||||||
fn files(&self) -> Option<std::sync::Arc<dyn FileEngine>> {
|
fn files(&self) -> Option<std::sync::Arc<dyn FileEngine>> {
|
||||||
@@ -10,7 +10,7 @@ pub trait HasFileData: std::any::Any {
|
|||||||
/// A file engine that serializes files to bytes
|
/// A file engine that serializes files to bytes
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
|
||||||
pub struct SerializedFileEngine {
|
pub struct SerializedFileEngine {
|
||||||
pub files: HashMap<String, Vec<u8>>,
|
pub files: std::collections::HashMap<String, Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
use dioxus::prelude::Props;
|
use dioxus::prelude::Props;
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
use dioxus_native_core::prelude::*;
|
use dioxus_native_core::prelude::*;
|
||||||
@@ -178,15 +180,16 @@ fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
|
|||||||
match rand::random::<u8>() % range {
|
match rand::random::<u8>() % range {
|
||||||
0 => DynamicNode::Placeholder(Default::default()),
|
0 => DynamicNode::Placeholder(Default::default()),
|
||||||
1 => cx.make_node((0..(rand::random::<u8>() % 5)).map(|_| {
|
1 => cx.make_node((0..(rand::random::<u8>() % 5)).map(|_| {
|
||||||
VNode::new(
|
cx.vnode(
|
||||||
None,
|
None.into(),
|
||||||
Template {
|
Default::default(),
|
||||||
|
Cell::new(Template {
|
||||||
name: concat!(file!(), ":", line!(), ":", column!(), ":0"),
|
name: concat!(file!(), ":", line!(), ":", column!(), ":0"),
|
||||||
roots: &[TemplateNode::Dynamic { id: 0 }],
|
roots: &[TemplateNode::Dynamic { id: 0 }],
|
||||||
node_paths: &[&[0]],
|
node_paths: &[&[0]],
|
||||||
attr_paths: &[],
|
attr_paths: &[],
|
||||||
},
|
}),
|
||||||
dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()),
|
dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||||
cx.bump().alloc([cx.component(
|
cx.bump().alloc([cx.component(
|
||||||
create_random_element,
|
create_random_element,
|
||||||
DepthProps { depth, root: false },
|
DepthProps { depth, root: false },
|
||||||
@@ -204,20 +207,6 @@ fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_random_dynamic_mounted_attr(cx: &ScopeState) -> MountedAttribute {
|
|
||||||
match rand::random::<u8>() % 2 {
|
|
||||||
0 => MountedAttribute::from(
|
|
||||||
&*cx.bump().alloc(
|
|
||||||
(0..(rand::random::<u8>() % 3) as usize)
|
|
||||||
.map(|_| create_random_dynamic_attr(cx))
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
1 => MountedAttribute::from(create_random_dynamic_attr(cx)),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
|
fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
|
||||||
let value = match rand::random::<u8>() % 6 {
|
let value = match rand::random::<u8>() % 6 {
|
||||||
0 => AttributeValue::Text(Box::leak(
|
0 => AttributeValue::Text(Box::leak(
|
||||||
@@ -230,6 +219,7 @@ fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
|
|||||||
5 => AttributeValue::None,
|
5 => AttributeValue::None,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Attribute::new(
|
Attribute::new(
|
||||||
Box::leak(format!("attr{}", rand::random::<usize>()).into_boxed_str()),
|
Box::leak(format!("attr{}", rand::random::<usize>()).into_boxed_str()),
|
||||||
value,
|
value,
|
||||||
@@ -266,10 +256,11 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
|
|||||||
.into_boxed_str(),
|
.into_boxed_str(),
|
||||||
));
|
));
|
||||||
println!("{template:#?}");
|
println!("{template:#?}");
|
||||||
let node = VNode::new(
|
let node = cx.vnode(
|
||||||
|
None.into(),
|
||||||
None,
|
None,
|
||||||
template,
|
Cell::new(template),
|
||||||
dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()),
|
dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||||
{
|
{
|
||||||
let dynamic_nodes: Vec<_> = dynamic_node_types
|
let dynamic_nodes: Vec<_> = dynamic_node_types
|
||||||
.iter()
|
.iter()
|
||||||
@@ -287,7 +278,7 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
|
|||||||
cx.bump()
|
cx.bump()
|
||||||
.alloc(
|
.alloc(
|
||||||
(0..template.attr_paths.len())
|
(0..template.attr_paths.len())
|
||||||
.map(|_| create_random_dynamic_mounted_attr(cx))
|
.map(|_| create_random_dynamic_attr(cx).into())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
)
|
)
|
||||||
.as_slice(),
|
.as_slice(),
|
||||||
|
|||||||
@@ -254,10 +254,12 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
|
|||||||
node_paths: &[ #(#node_paths),* ],
|
node_paths: &[ #(#node_paths),* ],
|
||||||
attr_paths: &[ #(#attr_paths),* ],
|
attr_paths: &[ #(#attr_paths),* ],
|
||||||
};
|
};
|
||||||
::dioxus::core::VNode::new(
|
|
||||||
|
__cx.vnode(
|
||||||
|
None.into(),
|
||||||
#key_tokens,
|
#key_tokens,
|
||||||
TEMPLATE,
|
std::cell::Cell::new(TEMPLATE),
|
||||||
dioxus::core::exports::bumpalo::collections::Vec::with_capacity_in(#root_count, __cx.bump()),
|
dioxus::core::exports::bumpalo::collections::Vec::with_capacity_in(#root_count, __cx.bump()).into(),
|
||||||
__cx.bump().alloc([ #( #node_printer ),* ]),
|
__cx.bump().alloc([ #( #node_printer ),* ]),
|
||||||
__cx.bump().alloc([ #( #dyn_attr_printer ),* ]),
|
__cx.bump().alloc([ #( #dyn_attr_printer ),* ]),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
# Known quirks for browsers and their workarounds
|
|
||||||
|
|
||||||
- text merging (solved through comment nodes)
|
|
||||||
- cursor jumping to end on inputs (not yet solved, solved in React already)
|
|
||||||
- SVG attributes cannot be set (solved using the correct method)
|
|
||||||
- volatile components
|
|
||||||
Reference in new issue
Block a user