@@ -39,9 +39,9 @@ use servo_url::ServoUrl;
3939use std:: mem;
4040use std:: sync:: atomic:: AtomicBool ;
4141use std:: sync:: Mutex ;
42+ use style:: global_style_data:: STYLE_THREAD_POOL ;
4243use style:: media_queries:: MediaList ;
4344use style:: parser:: ParserContext ;
44- use style:: global_style_data:: STYLE_THREAD_POOL ;
4545use style:: shared_lock:: { Locked , SharedRwLock } ;
4646use style:: stylesheets:: import_rule:: ImportSheet ;
4747use style:: stylesheets:: StylesheetLoader as StyleStylesheetLoader ;
@@ -209,64 +209,63 @@ impl StylesheetLoadContext {
209209 None => return self . parse_sync ( status) ,
210210 } ;
211211
212- let metadata = match self . metadata . take ( ) {
213- Some ( meta) => meta,
214- None => return ,
215- } ;
216- let is_css = metadata. content_type . map_or ( false , |ct| {
217- let mime: Mime = ct. into_inner ( ) . into ( ) ;
218- mime. type_ ( ) == mime:: TEXT && mime. subtype ( ) == mime:: CSS
219- } ) ;
220- let data = if is_css {
221- mem:: replace ( & mut self . data , vec ! [ ] )
222- } else {
223- vec ! [ ]
224- } ;
212+ let elem = self . elem . root ( ) ;
213+ let document = self . document . root ( ) ;
225214
226- // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
227- let environment_encoding = UTF_8 ;
228- let final_url = metadata. final_url ;
229- // FIXME: Revisit once consensus is reached at:
230- // https://github.com/whatwg/html/issues/1142
231- let successful = metadata. status . map_or ( false , |( code, _) | code == 200 ) ;
232- let charset = metadata. charset ;
215+ if status. is_ok ( ) {
216+ let metadata = match self . metadata . take ( ) {
217+ Some ( meta) => meta,
218+ None => return ,
219+ } ;
220+ let is_css = metadata. content_type . map_or ( false , |ct| {
221+ let mime: Mime = ct. into_inner ( ) . into ( ) ;
222+ mime. type_ ( ) == mime:: TEXT && mime. subtype ( ) == mime:: CSS
223+ } ) ;
224+ let data = if is_css {
225+ mem:: replace ( & mut self . data , vec ! [ ] )
226+ } else {
227+ vec ! [ ]
228+ } ;
233229
234- let document = self . document . root ( ) ;
235- let pipeline_id = document. window ( ) . pipeline_id ( ) ;
236- let shared_lock = document. style_shared_lock ( ) . clone ( ) ;
237- let quirks_mode = document. quirks_mode ( ) ;
230+ // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
231+ let environment_encoding = UTF_8 ;
232+ let final_url = metadata. final_url ;
233+ // FIXME: Revisit once consensus is reached at:
234+ // https://github.com/whatwg/html/issues/1142
235+ let successful = metadata. status . map_or ( false , |( code, _) | code == 200 ) ;
236+ let charset = metadata. charset ;
238237
239- let trusted_elem = self . elem . clone ( ) ;
240- let elem = self . elem . root ( ) ;
241- let script_chan = window_from_node ( & * elem ) . main_thread_script_chan ( ) . clone ( ) ;
238+ let pipeline_id = document . window ( ) . pipeline_id ( ) ;
239+ let shared_lock = document . style_shared_lock ( ) . clone ( ) ;
240+ let quirks_mode = document . quirks_mode ( ) ;
242241
243- let origin_clean = self . origin_clean ;
244- let url = self . url . clone ( ) ;
242+ let trusted_elem = self . elem . clone ( ) ;
243+ let script_chan = window_from_node ( & * elem ) . main_thread_script_chan ( ) . clone ( ) ;
245244
246- let loader = ThreadSafeStylesheetLoader {
247- elem : trusted_elem. clone ( ) ,
248- script_chan : script_chan. clone ( ) ,
249- pipeline_id : pipeline_id,
250- } ;
245+ let origin_clean = self . origin_clean ;
246+ let url = self . url . clone ( ) ;
251247
252- let status_ok = status. is_ok ( ) ;
248+ let loader = ThreadSafeStylesheetLoader {
249+ elem : trusted_elem. clone ( ) ,
250+ script_chan : script_chan. clone ( ) ,
251+ pipeline_id : pipeline_id,
252+ } ;
253253
254- // Unroot document and move that into the thread. TODO(mandreyel):
255- // Should we move a rooted or an unrooted document into the thread?
256- let document = self . document . clone ( ) ;
257- let request_generation_id = self . request_generation_id ;
254+ // Unroot document and move that into the thread. TODO(mandreyel):
255+ // Should we move a rooted or an unrooted document into the thread?
256+ let document = self . document . clone ( ) ;
257+ let request_generation_id = self . request_generation_id ;
258258
259- // Can't clone `MediaList` or move out of `self`, so manually move or
260- // clone sheet source as appropriate.
261- let mut source = match self . source {
262- StylesheetSource :: LinkElement ( ref mut media) => {
263- StylesheetSource :: LinkElement ( Some ( media. take ( ) . unwrap ( ) ) )
264- } ,
265- StylesheetSource :: Import ( ref mut sheet) => StylesheetSource :: Import ( sheet. clone ( ) ) ,
266- } ;
259+ // Can't clone `MediaList` or move out of `self`, so manually move or
260+ // clone sheet source as appropriate.
261+ let mut source = match self . source {
262+ StylesheetSource :: LinkElement ( ref mut media) => {
263+ StylesheetSource :: LinkElement ( Some ( media. take ( ) . unwrap ( ) ) )
264+ } ,
265+ StylesheetSource :: Import ( ref mut sheet) => StylesheetSource :: Import ( sheet. clone ( ) ) ,
266+ } ;
267267
268- thread_pool. spawn ( move || {
269- if status_ok {
268+ thread_pool. spawn ( move || {
270269 let protocol_encoding_label = charset. as_ref ( ) . map ( |s| & * * s) ;
271270 let sheet = match source {
272271 StylesheetSource :: LinkElement ( ref mut media) => {
@@ -306,7 +305,6 @@ impl StylesheetLoadContext {
306305 ScriptThreadEventCategory :: StylesheetLoad ,
307306 Box :: new ( FinishAsyncStylesheetLoadTask {
308307 successful,
309- invalidate_stylesheets : true ,
310308 origin_clean,
311309 top_level_stylesheet : sheet,
312310 elem : trusted_elem,
@@ -317,28 +315,30 @@ impl StylesheetLoadContext {
317315 pipeline_id,
318316 TaskSourceName :: Networking ,
319317 ) ) ) ;
320- } else {
321- // Even if we didn't manage to parse the sheet, we still need to
322- // send a message to the event loop to tell the document that
323- // the load has finished.
324- // TODO(mandreyel): What to do with errors?
325- let _ = script_chan. send ( Msg :: Common ( CommonScriptMsg :: Task (
326- ScriptThreadEventCategory :: StylesheetLoad ,
327- Box :: new ( FinishAsyncStylesheetLoadTask {
328- successful,
329- invalidate_stylesheets : false ,
330- origin_clean,
331- top_level_stylesheet : None ,
332- elem : trusted_elem,
333- document,
334- url,
335- request_generation_id : None ,
336- } ) ,
337- pipeline_id,
338- TaskSourceName :: Networking ,
339- ) ) ) ;
318+ } ) ;
319+ } else {
320+ // The load was not successful, let document know.
321+ let owner = elem
322+ . upcast :: < Element > ( )
323+ . as_stylesheet_owner ( )
324+ . expect ( "Stylesheet not loaded by <style> or <link> element!" ) ;
325+ owner. set_origin_clean ( self . origin_clean ) ;
326+ if owner. parser_inserted ( ) {
327+ document. decrement_script_blocking_stylesheet_count ( ) ;
340328 }
341- } ) ;
329+
330+ document. finish_load ( LoadType :: Stylesheet ( self . url . clone ( ) ) ) ;
331+
332+ let successful = false ;
333+ if let Some ( any_failed) = owner. load_finished ( successful) {
334+ let event = if any_failed {
335+ atom ! ( "error" )
336+ } else {
337+ atom ! ( "load" )
338+ } ;
339+ elem. upcast :: < EventTarget > ( ) . fire_event ( event) ;
340+ }
341+ }
342342 }
343343}
344344
@@ -580,24 +580,22 @@ impl TaskOnce for ImportStylesheetTask {
580580}
581581
582582/// A stylesheet may be parsed on a thread pool rather than its document's event
583- /// loop. Setting the parsed stylesheet on the HTML element and the document
584- /// needs to be done on the event loop, thus when the thread parsing the sheet
585- /// is done it enqueues this task on the script thread's task queue that's
586- /// managing the document.
583+ /// loop. However, setting the parsed stylesheet on the HTML element and the
584+ /// document needs to be done on the event loop, thus when the thread parsing
585+ /// the sheet is done it enqueues this task on the script thread's task queue
586+ /// that's managing the document.
587587///
588588/// This task is used for both top-level as well as nested stylesheet loads. For
589589/// top-level sheets the `top_level_stylesheet` field must be set, but parsing
590- /// an imported sheet returns an empty sheet wrapped in an Arc in an
591- /// `ImportRule` (which is inserted in its parent's rule list), and after an
592- /// async fetch and parse, the empty stylesheet is set through the Arc
593- /// reference.
590+ /// an imported sheet (in loader's `request_stylesheet`) returns an empty sheet
591+ /// wrapped in an Arc in an `ImportRule` (which is inserted in its parent's rule
592+ /// list), and after an async fetch and parse, the empty stylesheet is set
593+ /// through the Arc reference.
594+ ///
595+ /// This task is only enqueued on the event loop if the load was successful.
594596struct FinishAsyncStylesheetLoadTask {
595597 /// Used to tell the document whether the load has concluded successfully.
596598 successful : bool ,
597- /// Whether document's current stylesheet needs to be invalidated. This is
598- /// necessary if a new top-level stylesheet or an import sheet has been
599- /// successfully parsed.
600- invalidate_stylesheets : bool ,
601599 origin_clean : bool ,
602600 /// If this was a top-level stylesheet load, the parsed stylesheet is placed
603601 /// here.
@@ -640,11 +638,7 @@ impl TaskOnce for FinishAsyncStylesheetLoadTask {
640638 }
641639 }
642640
643- // We also need to invalidate a document's stylesheets if this was an
644- // import rule load, not just in the case of top-level sheet loads.
645- if self . invalidate_stylesheets {
646- document. invalidate_stylesheets ( ) ;
647- }
641+ document. invalidate_stylesheets ( ) ;
648642
649643 let owner = elem
650644 . upcast :: < Element > ( )
0 commit comments