-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom Elements: CustomElementRegistry #299
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use webcore::value::Reference; | ||
webapi::error::TypeError; | ||
|
||
use webapi::dom_exception::{ | ||
NotSupportedError, | ||
SyntaxError | ||
}; | ||
|
||
#[cfg(feature = "experimental_features_which_may_break_on_minor_version_bumps")] | ||
use webcore::promise::{Promise, TypedPromise}; | ||
|
||
/// The CustomElementRegistry interface provides methods for registering custom elements | ||
/// and querying registered elements. To get an instance of it, use the window.customElements property. | ||
/// | ||
/// [(JavaScript docs)](hhttps://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry) | ||
/// https://html.spec.whatwg.org/multipage/custom-elements.html#customelementregistry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Links to the specs should be in a normal comment, that is |
||
#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)] | ||
#[reference(instance_of = "CustomElementRegistry")] | ||
pub struct CustomElementRegistry(Reference); | ||
|
||
|
||
error_enum_boilerplate! { | ||
/// A enum of the exceptions that CustomElementRegistry.define() may throw | ||
DefineError, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A little more verbose name would be better here, I think. Maybe |
||
/// A TypeError | ||
TypeError | ||
/// A NotSupportedError | ||
NotSupportedError, | ||
/// A SyntaxError | ||
SyntaxError, | ||
} | ||
|
||
impl CustomElementRegistry { | ||
/// Defines a new custom element | ||
/// | ||
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define) | ||
/// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-define | ||
pub fn define( &self, name: &str, constructor: Any) -> Result<(), DefineError> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm.... we currently don't have a type which can represent a constructor. According to this a constructor can be detected with some tricks so I guess we technically could add one? You'd define such a type using the usual There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the check for constructors is more involved, because custom elements require actual ES6 classes (and they must have the appropriate I think this also ties into the ability to define JS classes in stdweb, and we don't currently have a thorough plan for that. I suppose we could create a simple There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Isn't the ES6 class syntax mostly a syntax sugar? I grabbed one of the examples off MDN of custom elements and I've modified the element definition to use the old-style of defining classes, and it looks like the example still works...? (At least in Firefox.) I wonder if that's just an accident? (Granted, I'm getting an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I haven't had the time to get back on this yet. But, AFAIK, ES6 is not just sugar though. It can be done without ES6 syntax - using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @koute No, it's not just sugar: the ability to extend host built-ins (like Array, Error, HTMLElement, etc.) doesn't work with ES5 classes, but it does with ES6 classes (which is why transpilers like Babel cannot extend those classes, since Babel compiles ES6 classes into ES5 classes). As @prasannavl said, there are some ways to workaround it with ES5 classes, but it's not simple or easy (which is why almost nobody does it). Could you post your code? When I tried using ES5 classes in Chrome it gave me errors when I called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't have in on hand anymore, however it really was just one of the examples picked at random with the class definition replaced with your garden variety old-style prototype-based JS class definition. So this begs the question - is it actually possible to detect that something is a genuine ES6 class? |
||
js!( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to use |
||
return @{self}.define(name, constructor); | ||
).try_into().unwrap() | ||
} | ||
|
||
/// Returns the constuctor for the named custom element, or undefined if the custom element is not defined. | ||
/// | ||
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get) | ||
/// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-get | ||
pub fn get( &self, name: &str ) -> Option<Constructor> { | ||
js!( return @{self}.get(name); ).try_into().unwrap() | ||
} | ||
|
||
/// Returns a promise that will be fulfilled when a custom element becomes defined with the given name. | ||
/// (If such a custom element is already defined, the returned promise is immediately fulfilled.) | ||
/// | ||
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/whenDefined) | ||
/// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-whendefined | ||
#[cfg(feature = "experimental_features_which_may_break_on_minor_version_bumps")] | ||
pub fn whenDefined( &self, name: &str ) -> TypedPromise<(), SyntaxError > { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be named in snake case, that is |
||
let promise: Promise = js!( return @{self}.whenDefined(name); ).try_into().unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this |
||
TypedPromise::new(promise) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're missing
use
here. (: