Clean up the resource selection algorithm a bit

This commit is contained in:
Anthony Ramine 2017-09-15 03:31:53 +02:00
parent e4cd6be831
commit 5352697558

View file

@ -286,44 +286,61 @@ impl HTMLMediaElement {
// https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm // https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm
fn invoke_resource_selection_algorithm(&self) { fn invoke_resource_selection_algorithm(&self) {
// Step 1 // Step 1.
self.network_state.set(NetworkState::NoSource); self.network_state.set(NetworkState::NoSource);
// TODO step 2 (show poster) // Step 2.
// TODO step 3 (delay load event) // FIXME(nox): Set show poster flag to true.
// Step 4 // Step 3.
// FIXME(nox): Set the delaying-the-load-event flag to true.
// Step 4.
// If the resource selection mode in the synchronous section is
// "attribute", the URL of the resource to fetch is relative to the
// media element's node document when the src attribute was last
// changed, which is why we need to pass the base URL in the task
// right here.
let doc = document_from_node(self); let doc = document_from_node(self);
let task = MediaElementMicrotask::ResourceSelectionTask { let task = MediaElementMicrotask::ResourceSelectionTask {
elem: Root::from_ref(self), elem: Root::from_ref(self),
base_url: doc.base_url() base_url: doc.base_url()
}; };
// FIXME(nox): This will later call the resource_selection_algorith_sync
// method from below, if microtasks were trait objects, we would be able
// to put the code directly in this method, without the boilerplate
// indirections.
ScriptThread::await_stable_state(Microtask::MediaElement(task)); ScriptThread::await_stable_state(Microtask::MediaElement(task));
} }
// https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm // https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm
#[allow(unreachable_code)] // FIXME(nox): Why does this need to be passed the base URL?
fn resource_selection_algorithm_sync(&self, base_url: ServoUrl) { fn resource_selection_algorithm_sync(&self, base_url: ServoUrl) {
// TODO step 5 (populate pending text tracks) // Step 5.
// FIXME(nox): Maybe populate the list of pending text tracks.
// Step 6 // Step 6.
let mode = if false { enum Mode {
// TODO media provider object // FIXME(nox): Support media object provider.
ResourceSelectionMode::Object #[allow(dead_code)]
} else if let Some(attr) = self.upcast::<Element>().get_attribute(&ns!(), &local_name!("src")) { Object,
ResourceSelectionMode::Attribute(attr.Value().to_string()) Attribute(String),
} else if false { // TODO: when implementing this remove #[allow(unreachable_code)] above. // FIXME(nox): Support source element child.
// TODO <source> child #[allow(dead_code)]
ResourceSelectionMode::Children(panic!()) Children(Root<HTMLSourceElement>),
}
let mode = if let Some(attr) = self.upcast::<Element>().get_attribute(&ns!(), &local_name!("src")) {
Mode::Attribute(attr.Value().into())
} else { } else {
self.network_state.set(NetworkState::Empty); self.network_state.set(NetworkState::Empty);
return; return;
}; };
// Step 7 // Step 7.
self.network_state.set(NetworkState::Loading); self.network_state.set(NetworkState::Loading);
// Step 8 // Step 8.
let window = window_from_node(self); let window = window_from_node(self);
window.dom_manipulation_task_source().queue_simple_event( window.dom_manipulation_task_source().queue_simple_event(
self.upcast(), self.upcast(),
@ -331,40 +348,50 @@ impl HTMLMediaElement {
&window, &window,
); );
// Step 9 // Step 9.
match mode { match mode {
ResourceSelectionMode::Object => { // Step 9.obj.
// Step 1 Mode::Object => {
// Step 9.obj.1.
*self.current_src.borrow_mut() = "".to_owned(); *self.current_src.borrow_mut() = "".to_owned();
// Step 4 // Step 9.obj.2.
self.resource_fetch_algorithm(Resource::Object); // FIXME(nox): The rest of the steps should be ran in parallel.
}
ResourceSelectionMode::Attribute(src) => { // Step 9.obj.3.
// Step 1 // Note that the resource fetch algorithm itself takes care
// of the cleanup in case of failure itself.
// FIXME(nox): Pass the assigned media provider here.
self.resource_fetch_algorithm(Resource::Object);
},
Mode::Attribute(src) => {
// Step 9.attr.1.
if src.is_empty() { if src.is_empty() {
self.queue_dedicated_media_source_failure_steps(); self.queue_dedicated_media_source_failure_steps();
return; return;
} }
// Step 2 // Step 9.attr.2.
let absolute_url = base_url.join(&src).map_err(|_| ()); let url_record = match base_url.join(&src) {
Ok(url) => url,
// Step 3 Err(_) => {
if let Ok(url) = absolute_url {
*self.current_src.borrow_mut() = url.as_str().into();
// Step 4
self.resource_fetch_algorithm(Resource::Url(url));
} else {
self.queue_dedicated_media_source_failure_steps(); self.queue_dedicated_media_source_failure_steps();
return;
} }
} };
ResourceSelectionMode::Children(_child) => { // Step 9.attr.3.
// TODO *self.current_src.borrow_mut() = url_record.as_str().into();
// Step 9.attr.4.
// Note that the resource fetch algorithm itself takes care
// of the cleanup in case of failure itself.
self.resource_fetch_algorithm(Resource::Url(url_record));
},
Mode::Children(_source) => {
// Step 9.children.
self.queue_dedicated_media_source_failure_steps() self.queue_dedicated_media_source_failure_steps()
} },
} }
} }
@ -723,12 +750,6 @@ impl MicrotaskRunnable for MediaElementMicrotask {
} }
} }
enum ResourceSelectionMode {
Object,
Attribute(String),
Children(Root<HTMLSourceElement>),
}
enum Resource { enum Resource {
Object, Object,
Url(ServoUrl), Url(ServoUrl),