forked from mirrors/gecko-dev
		
	 d990887177
			
		
	
	
		d990887177
		
	
	
	
	
		
			
			fixes #6651 Source-Repo: https://github.com/servo/servo Source-Revision: 8a6681ba70c4e8dc524aff7b8fbc3c71167e8745
		
			
				
	
	
		
			137 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| use dom::bindings::cell::DOMRefCell;
 | |
| use dom::bindings::js::{JS, Root};
 | |
| use dom::document::{Document, DocumentHelpers};
 | |
| use dom::node::NodeHelpers;
 | |
| use dom::window::Window;
 | |
| 
 | |
| use msg::constellation_msg::PipelineId;
 | |
| use std::cell::Cell;
 | |
| use std::rc::Rc;
 | |
| 
 | |
| /// Encapsulates a handle to a frame in a frame tree.
 | |
| #[derive(JSTraceable)]
 | |
| #[allow(unrooted_must_root)] // FIXME(#6687) this is wrong
 | |
| pub struct Page {
 | |
|     /// Pipeline id associated with this page.
 | |
|     id: PipelineId,
 | |
| 
 | |
|     /// The outermost frame containing the document and window.
 | |
|     frame: DOMRefCell<Option<Frame>>,
 | |
| 
 | |
|     /// Indicates if reflow is required when reloading.
 | |
|     needs_reflow: Cell<bool>,
 | |
| 
 | |
|     // Child Pages.
 | |
|     pub children: DOMRefCell<Vec<Rc<Page>>>,
 | |
| }
 | |
| 
 | |
| pub struct PageIterator {
 | |
|     stack: Vec<Rc<Page>>,
 | |
| }
 | |
| 
 | |
| pub trait IterablePage {
 | |
|     fn iter(&self) -> PageIterator;
 | |
|     fn find(&self, id: PipelineId) -> Option<Rc<Page>>;
 | |
| }
 | |
| 
 | |
| impl IterablePage for Rc<Page> {
 | |
|     fn iter(&self) -> PageIterator {
 | |
|         PageIterator {
 | |
|             stack: vec!(self.clone()),
 | |
|         }
 | |
|     }
 | |
|     fn find(&self, id: PipelineId) -> Option<Rc<Page>> {
 | |
|         if self.id == id { return Some(self.clone()); }
 | |
|         for page in self.children.borrow().iter() {
 | |
|             let found = page.find(id);
 | |
|             if found.is_some() { return found; }
 | |
|         }
 | |
|         None
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| impl Page {
 | |
|     pub fn new(id: PipelineId) -> Page {
 | |
|         Page {
 | |
|             id: id,
 | |
|             frame: DOMRefCell::new(None),
 | |
|             needs_reflow: Cell::new(true),
 | |
|             children: DOMRefCell::new(vec!()),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pub fn pipeline(&self) -> PipelineId {
 | |
|         self.id
 | |
|     }
 | |
| 
 | |
|     pub fn window(&self) -> Root<Window> {
 | |
|         self.frame.borrow().as_ref().unwrap().window.root()
 | |
|     }
 | |
| 
 | |
|     pub fn document(&self) -> Root<Document> {
 | |
|         self.frame.borrow().as_ref().unwrap().document.root()
 | |
|     }
 | |
| 
 | |
|     // must handle root case separately
 | |
|     pub fn remove(&self, id: PipelineId) -> Option<Rc<Page>> {
 | |
|         let remove_idx = {
 | |
|             self.children
 | |
|                 .borrow_mut()
 | |
|                 .iter_mut()
 | |
|                 .position(|page_tree| page_tree.id == id)
 | |
|         };
 | |
|         match remove_idx {
 | |
|             Some(idx) => Some(self.children.borrow_mut().remove(idx)),
 | |
|             None => {
 | |
|                 self.children
 | |
|                     .borrow_mut()
 | |
|                     .iter_mut()
 | |
|                     .filter_map(|page_tree| page_tree.remove(id))
 | |
|                     .next()
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Iterator for PageIterator {
 | |
|     type Item = Rc<Page>;
 | |
| 
 | |
|     fn next(&mut self) -> Option<Rc<Page>> {
 | |
|         match self.stack.pop() {
 | |
|             Some(next) => {
 | |
|                 for child in next.children.borrow().iter() {
 | |
|                     self.stack.push(child.clone());
 | |
|                 }
 | |
|                 Some(next)
 | |
|             },
 | |
|             None => None,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Page {
 | |
|     pub fn set_reflow_status(&self, status: bool) -> bool {
 | |
|         let old = self.needs_reflow.get();
 | |
|         self.needs_reflow.set(status);
 | |
|         old
 | |
|     }
 | |
| 
 | |
|     pub fn set_frame(&self, frame: Option<Frame>) {
 | |
|         *self.frame.borrow_mut() = frame;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Information for one frame in the browsing context.
 | |
| #[derive(JSTraceable)]
 | |
| #[must_root]
 | |
| pub struct Frame {
 | |
|     /// The document for this frame.
 | |
|     pub document: JS<Document>,
 | |
|     /// The window object for this frame.
 | |
|     pub window: JS<Window>,
 | |
| }
 |