mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-23 13:12:14 +00:00
Merge pull request #914 from alexcrichton/rename-polyfill
Rename `polyfill` to `vendor_prefix`
This commit is contained in:
commit
9c085dc0f5
@ -144,7 +144,7 @@ pub struct ImportType {
|
|||||||
pub doc_comment: Option<String>,
|
pub doc_comment: Option<String>,
|
||||||
pub instanceof_shim: String,
|
pub instanceof_shim: String,
|
||||||
pub extends: Vec<Ident>,
|
pub extends: Vec<Ident>,
|
||||||
pub polyfills: Vec<Ident>,
|
pub vendor_prefixes: Vec<Ident>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||||
@ -479,7 +479,7 @@ impl ImportType {
|
|||||||
shared::ImportType {
|
shared::ImportType {
|
||||||
name: self.js_name.clone(),
|
name: self.js_name.clone(),
|
||||||
instanceof_shim: self.instanceof_shim.clone(),
|
instanceof_shim: self.instanceof_shim.clone(),
|
||||||
polyfills: self.polyfills.iter().map(|s| s.to_string()).collect(),
|
vendor_prefixes: self.vendor_prefixes.iter().map(|s| s.to_string()).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ struct ClassField {
|
|||||||
pub struct SubContext<'a, 'b: 'a> {
|
pub struct SubContext<'a, 'b: 'a> {
|
||||||
pub program: &'a shared::Program,
|
pub program: &'a shared::Program,
|
||||||
pub cx: &'a mut Context<'b>,
|
pub cx: &'a mut Context<'b>,
|
||||||
pub polyfills: HashMap<String, Vec<String>>,
|
pub vendor_prefixes: HashMap<String, Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const INITIAL_SLAB_VALUES: &[&str] = &["undefined", "null", "true", "false"];
|
const INITIAL_SLAB_VALUES: &[&str] = &["undefined", "null", "true", "false"];
|
||||||
@ -1769,7 +1769,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
}
|
}
|
||||||
for f in self.program.imports.iter() {
|
for f in self.program.imports.iter() {
|
||||||
if let shared::ImportKind::Type(ty) = &f.kind {
|
if let shared::ImportKind::Type(ty) = &f.kind {
|
||||||
self.register_polyfills(ty);
|
self.register_vendor_prefix(ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for f in self.program.imports.iter() {
|
for f in self.program.imports.iter() {
|
||||||
@ -2147,17 +2147,17 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
self.cx.typescript.push_str("}\n");
|
self.cx.typescript.push_str("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_polyfills(
|
fn register_vendor_prefix(
|
||||||
&mut self,
|
&mut self,
|
||||||
info: &shared::ImportType,
|
info: &shared::ImportType,
|
||||||
) {
|
) {
|
||||||
if info.polyfills.len() == 0 {
|
if info.vendor_prefixes.len() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.polyfills
|
self.vendor_prefixes
|
||||||
.entry(info.name.to_string())
|
.entry(info.name.to_string())
|
||||||
.or_insert(Vec::new())
|
.or_insert(Vec::new())
|
||||||
.extend(info.polyfills.iter().cloned());
|
.extend(info.vendor_prefixes.iter().cloned());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_name(&mut self, import: &shared::Import, item: &str) -> Result<String, Error> {
|
fn import_name(&mut self, import: &shared::Import, item: &str) -> Result<String, Error> {
|
||||||
@ -2173,20 +2173,20 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar to `--no-modules`, only allow polyfills basically for web
|
// Similar to `--no-modules`, only allow vendor prefixes basically for web
|
||||||
// apis, shouldn't be necessary for things like npm packages or other
|
// apis, shouldn't be necessary for things like npm packages or other
|
||||||
// imported items.
|
// imported items.
|
||||||
let polyfills = self.polyfills.get(item);
|
let vendor_prefixes = self.vendor_prefixes.get(item);
|
||||||
if let Some(polyfills) = polyfills {
|
if let Some(vendor_prefixes) = vendor_prefixes {
|
||||||
assert!(polyfills.len() > 0);
|
assert!(vendor_prefixes.len() > 0);
|
||||||
|
|
||||||
if let Some(module) = &import.module {
|
if let Some(module) = &import.module {
|
||||||
bail!(
|
bail!(
|
||||||
"import of `{}` from `{}` has a polyfill of `{}` listed, but
|
"import of `{}` from `{}` has a polyfill of `{}` listed, but
|
||||||
polyfills aren't supported when importing from modules",
|
vendor prefixes aren't supported when importing from modules",
|
||||||
item,
|
item,
|
||||||
module,
|
module,
|
||||||
&polyfills[0],
|
&vendor_prefixes[0],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if let Some(ns) = &import.js_namespace {
|
if let Some(ns) = &import.js_namespace {
|
||||||
@ -2239,25 +2239,31 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
name
|
name
|
||||||
} else if let Some(polyfills) = polyfills {
|
} else if let Some(vendor_prefixes) = vendor_prefixes {
|
||||||
imports_post.push_str("const l");
|
imports_post.push_str("const l");
|
||||||
imports_post.push_str(&name);
|
imports_post.push_str(&name);
|
||||||
imports_post.push_str(" = ");
|
imports_post.push_str(" = ");
|
||||||
switch(imports_post, &name, polyfills);
|
switch(imports_post, &name, "", vendor_prefixes);
|
||||||
imports_post.push_str(";\n");
|
imports_post.push_str(";\n");
|
||||||
|
|
||||||
fn switch(dst: &mut String, name: &str, left: &[String]) {
|
fn switch(dst: &mut String, name: &str, prefix: &str, left: &[String]) {
|
||||||
if left.len() == 0 {
|
if left.len() == 0 {
|
||||||
|
dst.push_str(prefix);
|
||||||
return dst.push_str(name);
|
return dst.push_str(name);
|
||||||
}
|
}
|
||||||
dst.push_str("(typeof ");
|
dst.push_str("(typeof ");
|
||||||
|
dst.push_str(prefix);
|
||||||
dst.push_str(name);
|
dst.push_str(name);
|
||||||
dst.push_str(" == 'undefined' ? ");
|
dst.push_str(" == 'undefined' ? ");
|
||||||
match left.len() {
|
match left.len() {
|
||||||
1 => dst.push_str(&left[0]),
|
1 => {
|
||||||
_ => switch(dst, &left[0], &left[1..]),
|
dst.push_str(&left[0]);
|
||||||
|
dst.push_str(name);
|
||||||
|
}
|
||||||
|
_ => switch(dst, name, &left[0], &left[1..]),
|
||||||
}
|
}
|
||||||
dst.push_str(" : ");
|
dst.push_str(" : ");
|
||||||
|
dst.push_str(prefix);
|
||||||
dst.push_str(name);
|
dst.push_str(name);
|
||||||
dst.push_str(")");
|
dst.push_str(")");
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ impl Bindgen {
|
|||||||
js::SubContext {
|
js::SubContext {
|
||||||
program,
|
program,
|
||||||
cx: &mut cx,
|
cx: &mut cx,
|
||||||
polyfills: Default::default(),
|
vendor_prefixes: Default::default(),
|
||||||
}.generate()?;
|
}.generate()?;
|
||||||
}
|
}
|
||||||
cx.finalize(stem)?
|
cx.finalize(stem)?
|
||||||
|
@ -185,9 +185,9 @@ impl BindgenAttrs {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn polyfills(&self) -> impl Iterator<Item = &Ident> {
|
fn vendor_prefixes(&self) -> impl Iterator<Item = &Ident> {
|
||||||
self.attrs.iter().filter_map(|a| match a {
|
self.attrs.iter().filter_map(|a| match a {
|
||||||
BindgenAttr::Polyfill(s) => Some(s),
|
BindgenAttr::VendorPrefix(s) => Some(s),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ pub enum BindgenAttr {
|
|||||||
JsName(String, Span),
|
JsName(String, Span),
|
||||||
JsClass(String),
|
JsClass(String),
|
||||||
Extends(Ident),
|
Extends(Ident),
|
||||||
Polyfill(Ident),
|
VendorPrefix(Ident),
|
||||||
Variadic,
|
Variadic,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,9 +294,9 @@ impl Parse for BindgenAttr {
|
|||||||
input.parse::<Token![=]>()?;
|
input.parse::<Token![=]>()?;
|
||||||
return Ok(BindgenAttr::Extends(input.parse::<AnyIdent>()?.0));
|
return Ok(BindgenAttr::Extends(input.parse::<AnyIdent>()?.0));
|
||||||
}
|
}
|
||||||
if attr == "polyfill" {
|
if attr == "vendor_prefix" {
|
||||||
input.parse::<Token![=]>()?;
|
input.parse::<Token![=]>()?;
|
||||||
return Ok(BindgenAttr::Polyfill(input.parse::<AnyIdent>()?.0));
|
return Ok(BindgenAttr::VendorPrefix(input.parse::<AnyIdent>()?.0));
|
||||||
}
|
}
|
||||||
if attr == "module" {
|
if attr == "module" {
|
||||||
input.parse::<Token![=]>()?;
|
input.parse::<Token![=]>()?;
|
||||||
@ -568,7 +568,7 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemType {
|
|||||||
rust_name: self.ident,
|
rust_name: self.ident,
|
||||||
js_name,
|
js_name,
|
||||||
extends: attrs.extends().cloned().collect(),
|
extends: attrs.extends().cloned().collect(),
|
||||||
polyfills: attrs.polyfills().cloned().collect(),
|
vendor_prefixes: attrs.vendor_prefixes().cloned().collect(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ pub struct ImportStatic {
|
|||||||
pub struct ImportType {
|
pub struct ImportType {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub instanceof_shim: String,
|
pub instanceof_shim: String,
|
||||||
pub polyfills: Vec<String>,
|
pub vendor_prefixes: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
|
@ -500,13 +500,13 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
doc_comment: None,
|
doc_comment: None,
|
||||||
instanceof_shim: format!("__widl_instanceof_{}", name),
|
instanceof_shim: format!("__widl_instanceof_{}", name),
|
||||||
extends: Vec::new(),
|
extends: Vec::new(),
|
||||||
polyfills: Vec::new(),
|
vendor_prefixes: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// whitelist a few names that have known polyfills
|
// whitelist a few names that have known polyfills
|
||||||
match name {
|
match name {
|
||||||
"AudioContext" => {
|
"AudioContext" => {
|
||||||
import_type.polyfills.push(Ident::new("webkitAudioContext", Span::call_site()));
|
import_type.vendor_prefixes.push(Ident::new("webkit", Span::call_site()));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
|
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
|
||||||
- [`structural`](./reference/attributes/on-js-imports/structural.md)
|
- [`structural`](./reference/attributes/on-js-imports/structural.md)
|
||||||
- [`variadic`](./reference/attributes/on-js-imports/variadic.md)
|
- [`variadic`](./reference/attributes/on-js-imports/variadic.md)
|
||||||
- [`polyfill`](./reference/attributes/on-js-imports/polyfill.md)
|
- [`vendor_prefix`](./reference/attributes/on-js-imports/vendor_prefix.md)
|
||||||
- [On Rust Exports](./reference/attributes/on-rust-exports/index.md)
|
- [On Rust Exports](./reference/attributes/on-rust-exports/index.md)
|
||||||
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
||||||
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
# Polyfilling APIs
|
|
||||||
|
|
||||||
In JS new APIs often have polyfills via different names in various contexts. For
|
|
||||||
example the `AudioContext` API is known as `webkitAudioContext` in Safari at the
|
|
||||||
time of this writing. The `polyfill` attribute indicates these alternative
|
|
||||||
names.
|
|
||||||
|
|
||||||
For example to use `AudioContext` you might do:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[wasm_bindgen]
|
|
||||||
extern {
|
|
||||||
#[wasm_bindgen(polyfill = webkitAudioContext)]
|
|
||||||
type AudioContext;
|
|
||||||
|
|
||||||
// methods on `AudioContext` ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Whenever `AudioContext` is used it'll use `AudioContext` if the global namespace
|
|
||||||
defines it or alternatively it'll fall back to `webkitAudioContext`.
|
|
||||||
|
|
||||||
Note that `polyfill` cannot be used with `module = "..."` or `js_namespace =
|
|
||||||
...`, so it's basically limited to web-platform APIs today.
|
|
@ -0,0 +1,24 @@
|
|||||||
|
# Vendor-prefixed APIs
|
||||||
|
|
||||||
|
On the web new APIs often have vendor prefixes while they're in an experimental
|
||||||
|
state. For example the `AudioContext` API is known as `webkitAudioContext` in
|
||||||
|
Safari at the time of this writing. The `vendor_prefix` attribute indicates
|
||||||
|
these alternative names, which are used if the normal name isn't defined.
|
||||||
|
|
||||||
|
For example to use `AudioContext` you might do:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
#[wasm_bindgen(vendor_prefix = webkit)]
|
||||||
|
type AudioContext;
|
||||||
|
|
||||||
|
// methods on `AudioContext` ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Whenever `AudioContext` is used it'll use `AudioContext` if the global namespace
|
||||||
|
defines it or alternatively it'll fall back to `webkitAudioContext`.
|
||||||
|
|
||||||
|
Note that `vendor_prefix` cannot be used with `module = "..."` or
|
||||||
|
`js_namespace = ...`, so it's basically limited to web-platform APIs today.
|
@ -26,7 +26,6 @@ pub mod math;
|
|||||||
pub mod node;
|
pub mod node;
|
||||||
pub mod option;
|
pub mod option;
|
||||||
pub mod optional_primitives;
|
pub mod optional_primitives;
|
||||||
pub mod polyfill;
|
|
||||||
pub mod rethrow;
|
pub mod rethrow;
|
||||||
pub mod simple;
|
pub mod simple;
|
||||||
pub mod slice;
|
pub mod slice;
|
||||||
@ -34,3 +33,4 @@ pub mod structural;
|
|||||||
pub mod u64;
|
pub mod u64;
|
||||||
pub mod validate_prt;
|
pub mod validate_prt;
|
||||||
pub mod variadic;
|
pub mod variadic;
|
||||||
|
pub mod vendor_prefix;
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
exports.import_me = function() {};
|
|
||||||
|
|
||||||
global.PolyfillBar = class {
|
|
||||||
foo() { return 123; }
|
|
||||||
};
|
|
@ -1,40 +0,0 @@
|
|||||||
use wasm_bindgen::prelude::*;
|
|
||||||
use wasm_bindgen_test::*;
|
|
||||||
|
|
||||||
#[wasm_bindgen(module = "tests/wasm/polyfill.js")]
|
|
||||||
extern "C" {
|
|
||||||
fn import_me();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
extern "C" {
|
|
||||||
#[wasm_bindgen(polyfill = PolyfillBar)]
|
|
||||||
type PolyfillFoo;
|
|
||||||
#[wasm_bindgen(constructor)]
|
|
||||||
fn new() -> PolyfillFoo;
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
fn foo(this: &PolyfillFoo) -> u32;
|
|
||||||
|
|
||||||
#[wasm_bindgen(polyfill = PolyfillBaz1, polyfill = PolyfillBar)]
|
|
||||||
type PolyfillFoo2;
|
|
||||||
#[wasm_bindgen(constructor)]
|
|
||||||
fn new() -> PolyfillFoo2;
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
fn foo(this: &PolyfillFoo2) -> u32;
|
|
||||||
|
|
||||||
#[wasm_bindgen(polyfill = PolyfillBaz1, polyfill = PolyfillBar, polyfill = PolyfillBaz2)]
|
|
||||||
type PolyfillFoo3;
|
|
||||||
#[wasm_bindgen(constructor)]
|
|
||||||
fn new() -> PolyfillFoo3;
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
fn foo(this: &PolyfillFoo3) -> u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
|
||||||
pub fn polyfill_works() {
|
|
||||||
import_me();
|
|
||||||
|
|
||||||
assert_eq!(PolyfillFoo::new().foo(), 123);
|
|
||||||
assert_eq!(PolyfillFoo2::new().foo(), 123);
|
|
||||||
assert_eq!(PolyfillFoo3::new().foo(), 123);
|
|
||||||
}
|
|
11
tests/wasm/vendor_prefix.js
Normal file
11
tests/wasm/vendor_prefix.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
exports.import_me = function() {};
|
||||||
|
|
||||||
|
global.webkitMySpecialApi = class {
|
||||||
|
foo() { return 123; }
|
||||||
|
};
|
||||||
|
global.MySpecialApi2 = class {
|
||||||
|
foo() { return 124; }
|
||||||
|
};
|
||||||
|
global.bMySpecialApi3 = class {
|
||||||
|
foo() { return 125; }
|
||||||
|
};
|
40
tests/wasm/vendor_prefix.rs
Normal file
40
tests/wasm/vendor_prefix.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
use wasm_bindgen_test::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "tests/wasm/vendor_prefix.js")]
|
||||||
|
extern "C" {
|
||||||
|
fn import_me();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern "C" {
|
||||||
|
#[wasm_bindgen(vendor_prefix = webkit)]
|
||||||
|
type MySpecialApi;
|
||||||
|
#[wasm_bindgen(constructor)]
|
||||||
|
fn new() -> MySpecialApi;
|
||||||
|
#[wasm_bindgen(method)]
|
||||||
|
fn foo(this: &MySpecialApi) -> u32;
|
||||||
|
|
||||||
|
#[wasm_bindgen(vendor_prefix = webkit)]
|
||||||
|
type MySpecialApi2;
|
||||||
|
#[wasm_bindgen(constructor)]
|
||||||
|
fn new() -> MySpecialApi2;
|
||||||
|
#[wasm_bindgen(method)]
|
||||||
|
fn foo(this: &MySpecialApi2) -> u32;
|
||||||
|
|
||||||
|
#[wasm_bindgen(vendor_prefix = a, vendor_prefix = b)]
|
||||||
|
type MySpecialApi3;
|
||||||
|
#[wasm_bindgen(constructor)]
|
||||||
|
fn new() -> MySpecialApi3;
|
||||||
|
#[wasm_bindgen(method)]
|
||||||
|
fn foo(this: &MySpecialApi3) -> u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
pub fn polyfill_works() {
|
||||||
|
import_me();
|
||||||
|
|
||||||
|
assert_eq!(MySpecialApi::new().foo(), 123);
|
||||||
|
assert_eq!(MySpecialApi2::new().foo(), 124);
|
||||||
|
assert_eq!(MySpecialApi3::new().foo(), 125);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user