diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/storage.rs | 95 | ||||
-rw-r--r-- | components/script/dom/webidls/Storage.webidl | 5 | ||||
-rw-r--r-- | components/script/dom/webidls/Window.webidl | 7 | ||||
-rw-r--r-- | components/script/dom/window.rs | 16 | ||||
-rw-r--r-- | components/script/page.rs | 6 | ||||
-rw-r--r-- | components/script/script_task.rs | 6 |
6 files changed, 114 insertions, 21 deletions
diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index 1bbde8326df..8620afae38a 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -4,58 +4,117 @@ use dom::bindings::codegen::Bindings::StorageBinding; use dom::bindings::codegen::Bindings::StorageBinding::StorageMethods; -use dom::bindings::global::GlobalRef; +use dom::bindings::global::{GlobalRef, GlobalField}; use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; +use dom::bindings::error::Fallible; use servo_util::str::DOMString; +use servo_net::storage_task::StorageTask; +use servo_net::storage_task::StorageTaskMsg; +use std::comm::channel; +use url::Url; #[dom_struct] pub struct Storage { reflector_: Reflector, + global: GlobalField, } impl Storage { - fn new_inherited() -> Storage { + fn new_inherited(global: &GlobalRef) -> Storage { Storage { reflector_: Reflector::new(), + global: GlobalField::from_rooted(global), } } - pub fn new(global: GlobalRef) -> Temporary<Storage> { - reflect_dom_object(box Storage::new_inherited(), global, StorageBinding::Wrap) + pub fn new(global: &GlobalRef) -> Temporary<Storage> { + reflect_dom_object(box Storage::new_inherited(global), *global, StorageBinding::Wrap) } + + pub fn Constructor(global: &GlobalRef) -> Fallible<Temporary<Storage>> { + Ok(Storage::new(global)) + } + + fn get_url(&self) -> Url { + let global_root = self.global.root(); + let global_ref = global_root.root_ref(); + global_ref.get_url() + } + + fn get_storage_task(&self) -> StorageTask { + let global_root = self.global.root(); + let global_ref = global_root.root_ref(); + global_ref.as_window().storage_task() + } + } impl<'a> StorageMethods for JSRef<'a, Storage> { fn Length(self) -> u32 { - 0 + let (sender, receiver) = channel(); + + self.get_storage_task().send(StorageTaskMsg::Length(sender, self.get_url())); + receiver.recv() } fn Key(self, index: u32) -> Option<DOMString> { + let (sender, receiver) = channel(); - //Return null for out of range index - if index >= self.Length() { - return None; - } - - return None; + self.get_storage_task().send(StorageTaskMsg::Key(sender, self.get_url(), index)); + receiver.recv() } - fn GetItem(self, key: DOMString) -> Option<DOMString> { - if key.is_empty() { - return None; - } + fn GetItem(self, name: DOMString) -> Option<DOMString> { + let (sender, receiver) = channel(); - return None; + self.get_storage_task().send(StorageTaskMsg::GetItem(sender, self.get_url(), name)); + receiver.recv() } - fn NamedGetter(self, key: DOMString, found: &mut bool) -> Option<DOMString> { - let item = self.GetItem(key); + fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<DOMString> { + let item = self.GetItem(name); *found = item.is_some(); item } + fn SetItem(self, name: DOMString, value: DOMString) { + let (sender, receiver) = channel(); + + self.get_storage_task().send(StorageTaskMsg::SetItem(sender, self.get_url(), name, value)); + if receiver.recv() { + //TODO send notification + } + } + + fn NamedSetter(self, name: DOMString, value: DOMString) { + self.SetItem(name, value); + } + + fn NamedCreator(self, name: DOMString, value: DOMString) { + self.SetItem(name, value); + } + + fn RemoveItem(self, name: DOMString) { + let (sender, receiver) = channel(); + + self.get_storage_task().send(StorageTaskMsg::RemoveItem(sender, self.get_url(), name)); + if receiver.recv() { + //TODO send notification + } + } + + fn NamedDeleter(self, name: DOMString) { + self.RemoveItem(name); + } + fn Clear(self) { + let (sender, receiver) = channel(); + + self.get_storage_task().send(StorageTaskMsg::Clear(sender, self.get_url())); + if receiver.recv() { + //TODO send notification + } } } diff --git a/components/script/dom/webidls/Storage.webidl b/components/script/dom/webidls/Storage.webidl index c4d59c3bc4e..4a469c4da0e 100644 --- a/components/script/dom/webidls/Storage.webidl +++ b/components/script/dom/webidls/Storage.webidl @@ -16,10 +16,9 @@ interface Storage { getter DOMString? getItem(DOMString name); - //setter creator void setItem(DOMString name, DOMString value); + setter creator void setItem(DOMString name, DOMString value); - //deleter not supported yet - //deleter void removeItem(DOMString name); + deleter void removeItem(DOMString name); void clear(); }; diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl index 7a94be61973..f353e6b829e 100644 --- a/components/script/dom/webidls/Window.webidl +++ b/components/script/dom/webidls/Window.webidl @@ -127,3 +127,10 @@ partial interface Window { void gc(); }; Window implements OnErrorEventHandlerForWindow; + +// https://html.spec.whatwg.org/multipage/webstorage.html#dom-sessionstorage +[NoInterfaceObject] +interface WindowSessionStorage { + readonly attribute Storage sessionStorage; +}; +Window implements WindowSessionStorage; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index faa4dfffdfd..a6df60e92f0 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -20,6 +20,7 @@ use dom::location::Location; use dom::navigator::Navigator; use dom::performance::Performance; use dom::screen::Screen; +use dom::storage::Storage; use layout_interface::NoQuery; use page::Page; use script_task::{ExitWindowMsg, ScriptChan, TriggerLoadMsg, TriggerFragmentMsg}; @@ -30,6 +31,7 @@ use timers::{Interval, NonInterval, TimerId, TimerManager}; use servo_msg::compositor_msg::ScriptListener; use servo_msg::constellation_msg::LoadData; use servo_net::image_cache_task::ImageCacheTask; +use servo_net::storage_task::StorageTask; use servo_util::str::{DOMString,HTML_SPACE_CHARACTERS}; use js::jsapi::JS_EvaluateUCScript; @@ -62,6 +64,7 @@ pub struct Window { navigation_start: u64, navigation_start_precise: f64, screen: MutNullableJS<Screen>, + session_storage: MutNullableJS<Storage>, timers: TimerManager } @@ -106,6 +109,10 @@ impl Window { pub fn get_url(&self) -> Url { self.page().get_url() } + + pub fn storage_task(&self) -> StorageTask { + self.page().storage_task.clone() + } } // http://www.whatwg.org/html/#atob @@ -208,6 +215,14 @@ impl<'a> WindowMethods for JSRef<'a, Window> { self.location.get().unwrap() } + fn SessionStorage(self) -> Temporary<Storage> { + if self.session_storage.get().is_none() { + let session_storage = Storage::new(&global::Window(self)); + self.session_storage.assign(Some(session_storage)); + } + self.session_storage.get().unwrap() + } + fn Console(self) -> Temporary<Console> { if self.console.get().is_none() { let console = Console::new(global::Window(self)); @@ -412,6 +427,7 @@ impl Window { navigation_start: time::get_time().sec as u64, navigation_start_precise: time::precise_time_s(), screen: Default::default(), + session_storage: Default::default(), timers: TimerManager::new() }; diff --git a/components/script/page.rs b/components/script/page.rs index d0c8c3e0bcf..a8b15a0b3e1 100644 --- a/components/script/page.rs +++ b/components/script/page.rs @@ -26,6 +26,7 @@ use servo_msg::compositor_msg::ScriptListener; use servo_msg::constellation_msg::{ConstellationChan, WindowSizeData}; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_net::resource_task::ResourceTask; +use servo_net::storage_task::StorageTask; use servo_util::geometry::{Au, MAX_RECT}; use servo_util::geometry; use servo_util::str::DOMString; @@ -86,6 +87,9 @@ pub struct Page { /// Associated resource task for use by DOM objects like XMLHttpRequest pub resource_task: ResourceTask, + /// A handle for communicating messages to the storage task. + pub storage_task: StorageTask, + /// A handle for communicating messages to the constellation task. pub constellation_chan: ConstellationChan, @@ -137,6 +141,7 @@ impl Page { layout_chan: LayoutChan, window_size: WindowSizeData, resource_task: ResourceTask, + storage_task: StorageTask, constellation_chan: ConstellationChan, js_context: Rc<Cx>) -> Page { let js_info = JSPageInfo { @@ -165,6 +170,7 @@ impl Page { fragment_name: DOMRefCell::new(None), last_reflow_id: Cell::new(0), resource_task: resource_task, + storage_task: storage_task, constellation_chan: constellation_chan, children: DOMRefCell::new(vec!()), damaged: Cell::new(false), diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 31918de0be7..35d51589d85 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -55,6 +55,7 @@ use servo_msg::constellation_msg::{Released}; use servo_msg::constellation_msg; use servo_net::image_cache_task::ImageCacheTask; use servo_net::resource_task::ResourceTask; +use servo_net::storage_task::StorageTask; use servo_util::geometry::to_frac_px; use servo_util::smallvec::{SmallVec1, SmallVec}; use servo_util::task::spawn_named_with_send_on_failure; @@ -262,6 +263,7 @@ impl ScriptTaskFactory for ScriptTask { constellation_chan: ConstellationChan, failure_msg: Failure, resource_task: ResourceTask, + storage_task: StorageTask, image_cache_task: ImageCacheTask, devtools_chan: Option<DevtoolsControlChan>, window_size: WindowSizeData) @@ -279,6 +281,7 @@ impl ScriptTaskFactory for ScriptTask { control_port, constellation_chan, resource_task, + storage_task, image_cache_task, devtools_chan, window_size); @@ -310,6 +313,7 @@ impl ScriptTask { control_port: Receiver<ConstellationControlMsg>, constellation_chan: ConstellationChan, resource_task: ResourceTask, + storage_task: StorageTask, img_cache_task: ImageCacheTask, devtools_chan: Option<DevtoolsControlChan>, window_size: WindowSizeData) @@ -332,6 +336,7 @@ impl ScriptTask { let page = Page::new(id, None, layout_chan, window_size, resource_task.clone(), + storage_task, constellation_chan.clone(), js_context.clone()); @@ -652,6 +657,7 @@ impl ScriptTask { LayoutChan(layout_chan.downcast_ref::<Sender<layout_interface::Msg>>().unwrap().clone()), window_size, parent_page.resource_task.clone(), + parent_page.storage_task.clone(), self.constellation_chan.clone(), self.js_context.borrow().as_ref().unwrap().clone()) }; |