switch to a Document trait and introduce Script/Head/Style/Meta components (#2635)
* switch to a Document trait and introduce Script/Head/Style/Meta components * Fix desktop title * Insert special elements into the head during the inital SSR render * Make all head component attributes optional * hydrate head elements * improve the server streaming head warning * Document fullstack head hydration approach * deduplicate head elements by href * move Link into head::Link * document head components * add meta and title examples * Fix a few doc examples * fix formatting * Add title to playwright tests * serde is optional on web, but it is enabled by hydrate * remove leftover console log
This commit is contained in:
1 parent
a490a94ae5
commit
176e67e5b7
65 files changed
+1703
-495
No files matched your search
@@ -0,0 +1,108 @@
|
||||
// Handle communication between rust and evaluating javascript
|
||||
|
||||
export class Channel {
|
||||
pending: any[];
|
||||
waiting: ((data: any) => void)[];
|
||||
|
||||
constructor() {
|
||||
this.pending = [];
|
||||
this.waiting = [];
|
||||
}
|
||||
|
||||
send(data: any) {
|
||||
// If there's a waiting callback, call it
|
||||
if (this.waiting.length > 0) {
|
||||
this.waiting.shift()(data);
|
||||
return;
|
||||
}
|
||||
// Otherwise queue the data
|
||||
this.pending.push(data);
|
||||
}
|
||||
|
||||
async recv(): Promise<any> {
|
||||
return new Promise((resolve, _reject) => {
|
||||
// If data already exists, resolve immediately
|
||||
if (this.pending.length > 0) {
|
||||
resolve(this.pending.shift());
|
||||
return;
|
||||
}
|
||||
// Otherwise queue the resolve callback
|
||||
this.waiting.push(resolve);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class WeakDioxusChannel {
|
||||
inner: WeakRef<DioxusChannel>;
|
||||
|
||||
constructor(channel: DioxusChannel) {
|
||||
this.inner = new WeakRef(channel);
|
||||
}
|
||||
|
||||
// Send data from rust to javascript
|
||||
rustSend(data: any) {
|
||||
let channel = this.inner.deref();
|
||||
if (channel) {
|
||||
channel.rustSend(data);
|
||||
}
|
||||
}
|
||||
|
||||
// Receive data sent from javascript in rust
|
||||
async rustRecv(): Promise<any> {
|
||||
let channel = this.inner.deref();
|
||||
if (channel) {
|
||||
return await channel.rustRecv();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class DioxusChannel {
|
||||
// Return a weak reference to this channel
|
||||
weak(): WeakDioxusChannel {
|
||||
return new WeakDioxusChannel(this);
|
||||
}
|
||||
|
||||
// Send data from rust to javascript
|
||||
abstract rustSend(data: any): void;
|
||||
|
||||
// Receive data sent from javascript in rust
|
||||
abstract rustRecv(): Promise<any>;
|
||||
}
|
||||
|
||||
export class WebDioxusChannel extends DioxusChannel {
|
||||
js_to_rust: Channel;
|
||||
rust_to_js: Channel;
|
||||
owner: any;
|
||||
|
||||
constructor(owner: any) {
|
||||
super();
|
||||
this.owner = owner;
|
||||
this.js_to_rust = new Channel();
|
||||
this.rust_to_js = new Channel();
|
||||
}
|
||||
|
||||
// Return a weak reference to this channel
|
||||
weak(): WeakDioxusChannel {
|
||||
return new WeakDioxusChannel(this);
|
||||
}
|
||||
|
||||
// Receive message from Rust
|
||||
async recv() {
|
||||
return await this.rust_to_js.recv();
|
||||
}
|
||||
|
||||
// Send message to rust.
|
||||
send(data: any) {
|
||||
this.js_to_rust.send(data);
|
||||
}
|
||||
|
||||
// Send data from rust to javascript
|
||||
rustSend(data: any) {
|
||||
this.rust_to_js.send(data);
|
||||
}
|
||||
|
||||
// Receive data sent from javascript in rust
|
||||
async rustRecv(): Promise<any> {
|
||||
return await this.js_to_rust.recv();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user