Initial import from AFP.

This commit is contained in:
Achim D. Brucker 2020-12-19 15:09:58 +00:00
commit f36cbcc496
22 changed files with 16506 additions and 0 deletions

14
Shadow_DOM/ROOT Normal file
View File

@ -0,0 +1,14 @@
chapter AFP
session "Shadow_DOM" (AFP) = "Core_DOM" +
options [timeout = 3600]
directories
classes
monads
tests
theories
Shadow_DOM
Shadow_DOM_Tests
document_files
"root.tex"
"root.bib"

10508
Shadow_DOM/Shadow_DOM.thy Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
section\<open>Shadow DOM Tests\<close>
theory Shadow_DOM_Tests
imports
"tests/slots"
"tests/slots_fallback"
"tests/Shadow_DOM_Document_adoptNode"
"tests/Shadow_DOM_Document_getElementById"
"tests/Shadow_DOM_Node_insertBefore"
"tests/Shadow_DOM_Node_removeChild"
begin
end

View File

@ -0,0 +1,460 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************\***)
section \<open>The Shadow DOM Data Model\<close>
theory ShadowRootClass
imports
Core_DOM.ShadowRootPointer
Core_DOM.DocumentClass
begin
subsection \<open>ShadowRoot\<close>
datatype shadow_root_mode = Open | Closed
record ('node_ptr, 'element_ptr, 'character_data_ptr) RShadowRoot = RObject +
nothing :: unit
mode :: shadow_root_mode
child_nodes :: "('node_ptr, 'element_ptr, 'character_data_ptr) node_ptr list"
type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot) ShadowRoot
= "('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot option) RShadowRoot_scheme"
register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot) ShadowRoot"
type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object, 'Node,
'Element, 'CharacterData, 'Document,
'ShadowRoot) Object
= "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, ('node_ptr, 'element_ptr,
'character_data_ptr, 'ShadowRoot option)
RShadowRoot_ext + 'Object, 'Node, 'Element, 'CharacterData, 'Document) Object"
register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object,
'Node, 'Element, 'CharacterData,
'Document, 'ShadowRoot) Object"
type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
'shadow_root_ptr, 'Object, 'Node,
'Element, 'CharacterData, 'Document, 'ShadowRoot) heap
= "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr, 'shadow_root_ptr,
('node_ptr, 'element_ptr,
'character_data_ptr, 'ShadowRoot option) RShadowRoot_ext + 'Object, 'Node, 'Element,
'CharacterData, 'Document) heap"
register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
'shadow_root_ptr, 'Object,
'Node, 'Element, 'CharacterData, 'Document, 'ShadowRoot) heap"
type_synonym "heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l" = "(unit, unit, unit, unit, unit, unit, unit, unit, unit, unit, unit, unit) heap"
definition shadow_root_ptr_kinds :: "(_) heap \<Rightarrow> (_) shadow_root_ptr fset"
where
"shadow_root_ptr_kinds heap =
the |`| (cast |`| (ffilter is_shadow_root_ptr_kind (object_ptr_kinds heap)))"
lemma shadow_root_ptr_kinds_simp [simp]:
"shadow_root_ptr_kinds (Heap (fmupd (cast shadow_root_ptr) shadow_root (the_heap h))) =
{|shadow_root_ptr|} |\<union>| shadow_root_ptr_kinds h"
apply(auto simp add: shadow_root_ptr_kinds_def)[1]
by force
definition shadow_root_ptrs :: "(_) heap \<Rightarrow> (_) shadow_root_ptr fset"
where
"shadow_root_ptrs heap = ffilter is_shadow_root_ptr (shadow_root_ptr_kinds heap)"
definition cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) Object \<Rightarrow> (_) ShadowRoot option"
where
"cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t obj = (case RObject.more obj of
Inr (Inr (Inl shadow_root)) \<Rightarrow> Some (RObject.extend (RObject.truncate obj) shadow_root)
| _ \<Rightarrow> None)"
adhoc_overloading cast cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
definition cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:: "(_) ShadowRoot \<Rightarrow> (_) Object"
where
"cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t shadow_root =
(RObject.extend (RObject.truncate shadow_root) (Inr (Inr (Inl (RObject.more shadow_root)))))"
adhoc_overloading cast cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
definition is_shadow_root_kind :: "(_) Object \<Rightarrow> bool"
where
"is_shadow_root_kind ptr \<longleftrightarrow> cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr \<noteq> None"
lemma shadow_root_ptr_kinds_heap_upd [simp]:
"shadow_root_ptr_kinds (Heap (fmupd (cast shadow_root_ptr) shadow_root (the_heap h))) =
{|shadow_root_ptr|} |\<union>| shadow_root_ptr_kinds h"
apply(auto simp add: shadow_root_ptr_kinds_def)[1]
by force
lemma shadow_root_ptr_kinds_commutes [simp]:
"cast shadow_root_ptr |\<in>| object_ptr_kinds h \<longleftrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
apply(auto simp add: object_ptr_kinds_def shadow_root_ptr_kinds_def)[1]
by (metis (no_types, lifting) shadow_root_ptr_casts_commute2 shadow_root_ptr_shadow_root_ptr_cast
ffmember_filter fimage_eqI
fset.map_comp option.sel)
definition get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) shadow_root_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) ShadowRoot option"
where
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Option.bind (get (cast shadow_root_ptr) h) cast"
adhoc_overloading get get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
locale l_type_wf_def\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
begin
definition a_type_wf :: "(_) heap \<Rightarrow> bool"
where
"a_type_wf h = (DocumentClass.type_wf h \<and> (\<forall>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h).
get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h \<noteq> None))"
end
global_interpretation l_type_wf_def\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t defines type_wf = a_type_wf .
lemmas type_wf_defs = a_type_wf_def
locale l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = l_type_wf type_wf for type_wf :: "((_) heap \<Rightarrow> bool)" +
assumes type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t: "type_wf h \<Longrightarrow> ShadowRootClass.type_wf h"
sublocale l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t \<subseteq> l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
apply(unfold_locales)
by (metis (full_types) ShadowRootClass.type_wf_def a_type_wf_def l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_axioms
l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma type_wf_implies_previous: "type_wf h \<Longrightarrow> DocumentClass.type_wf h"
by(simp add: type_wf_defs)
locale l_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas = l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
begin
sublocale l_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas by unfold_locales
lemma get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf:
assumes "type_wf h"
shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h \<longleftrightarrow> get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h \<noteq> None"
using l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_axioms assms
apply(simp add: type_wf_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
by (metis is_none_bind is_none_simps(1) is_none_simps(2) local.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf notin_fset
shadow_root_ptr_kinds_commutes)
end
global_interpretation l_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas type_wf by unfold_locales
definition put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) shadow_root_ptr \<Rightarrow> (_) ShadowRoot \<Rightarrow> (_) heap \<Rightarrow> (_) heap"
where
"put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root = put (cast shadow_root_ptr) (cast shadow_root)"
adhoc_overloading put put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
lemma put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap:
assumes "put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h = h'"
shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h'"
using assms
unfolding put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
by (metis shadow_root_ptr_kinds_commutes put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ptr_in_heap)
lemma put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_put_ptrs:
assumes "put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h = h'"
shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast shadow_root_ptr|}"
using assms
by (simp add: put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_put_ptrs)
lemma cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_inject [simp]: "cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x = cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t y \<longleftrightarrow> x = y"
apply(simp add: cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def)
by (metis (full_types) RObject.surjective old.unit.exhaust)
lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_none [simp]:
"cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t obj = None \<longleftrightarrow> \<not> (\<exists>shadow_root. cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t shadow_root = obj)"
apply(auto simp add: cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def
split: sum.splits)[1]
by (metis (full_types) RObject.select_convs(2) RObject.surjective old.unit.exhaust)
lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_some [simp]:
"cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t obj = Some shadow_root \<longleftrightarrow> cast shadow_root = obj"
by(auto simp add: cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def split: sum.splits)
lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_inv [simp]: "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t (cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t shadow_root) = Some shadow_root"
by simp
lemma cast_shadow_root_not_node [simp]:
"cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t shadow_root \<noteq> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node"
"cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node \<noteq> cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t shadow_root"
by(auto simp add: cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def)
lemma get_shadow_root_ptr_simp1 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h) = Some shadow_root"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma get_shadow_root_ptr_simp2 [simp]:
"shadow_root_ptr \<noteq> shadow_root_ptr'
\<Longrightarrow> get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' shadow_root h) =
get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma get_shadow_root_ptr_simp3 [simp]:
"get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma get_shadow_root_ptr_simp4 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma get_shadow_root_ptr_simp5 [simp]:
"get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h"
by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma get_shadow_root_ptr_simp6 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma get_shadow_root_ptr_simp7 [simp]:
"get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma get_shadow_root_ptr_simp8 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
using assms
by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
using assms
by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def)
lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
using assms
by(auto simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
abbreviation "create_shadow_root_obj mode_arg child_nodes_arg
\<equiv> \<lparr> RObject.nothing = (), RShadowRoot.nothing = (), mode = mode_arg,
RShadowRoot.child_nodes = child_nodes_arg, \<dots> = None \<rparr>"
definition new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_)heap \<Rightarrow> ((_) shadow_root_ptr \<times> (_) heap)"
where
"new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (let new_shadow_root_ptr =
shadow_root_ptr.Ref (Suc (fMax (shadow_root_ptr.the_ref |`| (shadow_root_ptrs h)))) in
(new_shadow_root_ptr, put new_shadow_root_ptr (create_shadow_root_obj Open []) h))"
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "new_shadow_root_ptr |\<in>| shadow_root_ptr_kinds h'"
using assms
unfolding new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def
using put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap by blast
lemma new_shadow_root_ptr_new:
"shadow_root_ptr.Ref (Suc (fMax (finsert 0 (shadow_root_ptr.the_ref |`| shadow_root_ptrs h)))) |\<notin>|
shadow_root_ptrs h"
by (metis Suc_n_not_le_n shadow_root_ptr.sel(1) fMax_ge fimage_finsert finsertI1 finsertI2 set_finsert)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_not_in_heap:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "new_shadow_root_ptr |\<notin>| shadow_root_ptr_kinds h"
using assms
unfolding new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
by (metis Pair_inject shadow_root_ptrs_def fMax_finsert fempty_iff ffmember_filter
fimage_is_fempty is_shadow_root_ptr_ref max_0L new_shadow_root_ptr_new)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_new_ptr:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
using assms
by (metis Pair_inject new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_put_ptrs)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_is_shadow_root_ptr:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "is_shadow_root_ptr new_shadow_root_ptr"
using assms
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t [simp]:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
assumes "ptr \<noteq> cast new_shadow_root_ptr"
shows "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h'"
using assms
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e [simp]:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h'"
using assms
apply(simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
using assms
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a [simp]:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h'"
using assms
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
shows "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
using assms
apply(simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
assumes "ptr \<noteq> new_shadow_root_ptr"
shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
using assms
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
locale l_known_ptr\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
begin
definition a_known_ptr :: "(_) object_ptr \<Rightarrow> bool"
where
"a_known_ptr ptr = (known_ptr ptr \<or> is_shadow_root_ptr ptr)"
lemma known_ptr_not_shadow_root_ptr: "a_known_ptr ptr \<Longrightarrow> \<not>is_shadow_root_ptr ptr \<Longrightarrow> known_ptr ptr"
by(simp add: a_known_ptr_def)
lemma known_ptr_new_shadow_root_ptr: "a_known_ptr ptr \<Longrightarrow> \<not>known_ptr ptr \<Longrightarrow> is_shadow_root_ptr ptr"
using l_known_ptr\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t.known_ptr_not_shadow_root_ptr by blast
end
global_interpretation l_known_ptr\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t defines known_ptr = a_known_ptr .
lemmas known_ptr_defs = a_known_ptr_def
locale l_known_ptrs\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
begin
definition a_known_ptrs :: "(_) heap \<Rightarrow> bool"
where
"a_known_ptrs h = (\<forall>ptr \<in> fset (object_ptr_kinds h). known_ptr ptr)"
lemma known_ptrs_known_ptr: "a_known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptr ptr"
apply(simp add: a_known_ptrs_def)
using notin_fset by fastforce
lemma known_ptrs_preserved:
"object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> a_known_ptrs h = a_known_ptrs h'"
by(auto simp add: a_known_ptrs_def)
lemma known_ptrs_subset:
"object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
by (simp add: less_eq_fset.rep_eq local.a_known_ptrs_def subsetD)
lemma known_ptrs_new_ptr:
"object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
by(simp add: a_known_ptrs_def)
end
global_interpretation l_known_ptrs\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t known_ptr defines known_ptrs = a_known_ptrs .
lemmas known_ptrs_defs = a_known_ptrs_def
lemma known_ptrs_is_l_known_ptrs [instances]: "l_known_ptrs known_ptr known_ptrs"
using known_ptrs_known_ptr known_ptrs_preserved l_known_ptrs_def known_ptrs_subset
known_ptrs_new_ptr
by blast
lemma shadow_root_get_put_1 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h) = Some shadow_root"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma shadow_root_different_get_put [simp]:
"shadow_root_ptr \<noteq> shadow_root_ptr' \<Longrightarrow>
get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' shadow_root h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma shadow_root_get_put_2 [simp]:
"get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma shadow_root_get_put_3 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t element_ptr (put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t element_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma shadow_root_get_put_4 [simp]:
"get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h"
by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma shadow_root_get_put_5 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t character_data_ptr (put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a shadow_root_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t character_data_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma shadow_root_get_put_6 [simp]:
"get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma shadow_root_get_put_7 [simp]:
"get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document_ptr (put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document_ptr h"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma known_ptrs_implies: "DocumentClass.known_ptrs h \<Longrightarrow> ShadowRootClass.known_ptrs h"
by(auto simp add: DocumentClass.known_ptrs_defs DocumentClass.known_ptr_defs
ShadowRootClass.known_ptrs_defs ShadowRootClass.known_ptr_defs)
definition delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) shadow_root_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) heap option" where
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr = delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast shadow_root_ptr)"
lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_pointer_removed:
assumes "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = Some h'"
shows "ptr |\<notin>| shadow_root_ptr_kinds h'"
using assms
by(auto simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_removed delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def shadow_root_ptr_kinds_def
split: if_splits)
lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_pointer_ptr_in_heap:
assumes "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = Some h'"
shows "ptr |\<in>| shadow_root_ptr_kinds h"
using assms
apply(auto simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_ptr_in_heap delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def split: if_splits)[1]
using delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_ptr_in_heap
by fastforce
lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok:
assumes "ptr |\<in>| shadow_root_ptr_kinds h"
shows "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h \<noteq> None"
using assms
by (simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ok delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemma shadow_root_delete_get_1 [simp]:
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h' = None"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
lemma shadow_root_different_delete_get [simp]:
"shadow_root_ptr \<noteq> shadow_root_ptr' \<Longrightarrow> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' h = Some h' \<Longrightarrow>
get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h' = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
lemma shadow_root_delete_get_2 [simp]:
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> object_ptr \<noteq> cast shadow_root_ptr \<Longrightarrow>
get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr h' = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr h"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
lemma shadow_root_delete_get_3 [simp]:
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h' = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h"
by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
lemma shadow_root_delete_get_4 [simp]:
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h' = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
by(simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
lemma shadow_root_delete_get_5 [simp]:
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow>
get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h' = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h"
by(simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
lemma shadow_root_delete_get_6 [simp]:
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h' = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
by(simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
lemma shadow_root_delete_get_7 [simp]:
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> shadow_root_ptr' \<noteq> shadow_root_ptr \<Longrightarrow>
get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' h' = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' h"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
end

View File

@ -0,0 +1,518 @@
@STRING{j-fac = "Formal Aspects of Computing" }
@STRING{pub-springer={Springer-Verlag} }
@STRING{pub-springer:adr={Heidelberg} }
@STRING{s-lncs = "Lecture Notes in Computer Science" }
@Book{ nipkow.ea:isabelle:2002,
author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel},
title = {Isabelle/HOL---A Proof Assistant for Higher-Order Logic},
publisher = pub-springer,
address = pub-springer:adr,
series = s-lncs,
volume = 2283,
doi = {10.1007/3-540-45949-9},
abstract = {This book is a self-contained introduction to interactive proof in higher-order logic (HOL), using
the proof assistant Isabelle2002. It is a tutorial for potential users rather than a monograph for
researchers. The book has three parts.
1. Elementary Techniques shows how to model functional programs in higher-order logic. Early examples
involve lists and the natural numbers. Most proofs are two steps long, consisting of induction on a
chosen variable followed by the auto tactic. But even this elementary part covers such advanced topics
as nested and mutual recursion. 2. Logic and Sets presents a collection of lower-level tactics that
you can use to apply rules selectively. It also describes Isabelle/HOL's treatment of sets, functions
and relations and explains how to define sets inductively. One of the examples concerns the theory of
model checking, and another is drawn from a classic textbook on formal languages. 3. Advanced Material
describes a variety of other topics. Among these are the real numbers, records and overloading.
Advanced techniques are described involving induction and recursion. A whole chapter is devoted to an
extended example: the verification of a security protocol. },
year = 2002,
acknowledgement={brucker, 2007-02-19},
bibkey = {nipkow.ea:isabelle:2002}
}
@Misc{ dom-specification,
year = 2016,
month = {DOM Living Standard -- Last Updated 20 October 2016},
day = 20,
url = {https://dom.spec.whatwg.org/},
organization = {Web Hypertext Application Technology Working Group (WHATWG)},
note = {An archived copy of the version from 20 October 2016 is available at
\url{https://git.logicalhacking.com/BrowserSecurity/fDOM-idl/}.}
}
@InProceedings{ brucker.ea:core-dom:2018,
author = {Achim D. Brucker and Michael Herzberg},
title = {A Formal Semantics of the Core {DOM} in {Isabelle/HOL}},
booktitle = {Proceedings of the Web Programming, Design, Analysis, And Implementation (WPDAI) track at WWW 2018},
location = {Lyon, France},
url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-fdom-2018},
year = 2018,
abstract = {At its core, the Document Object Model (DOM) defines a tree-like data structure for representing
documents in general and HTML documents in particular. It forms the heart of any rendering engine of
modern web browsers. Formalizing the key concepts of the DOM is a pre-requisite for the formal
reasoning over client-side JavaScript programs as well as for the analysis of security concepts in
modern web browsers. In this paper, we present a formalization of the core DOM, with focus on the
node-tree and the operations defined on node-trees, in Isabelle/HOL. We use the formalization to
verify the functional correctness of the most important functions defined in the DOM standard.
Moreover, our formalization is (1) extensible, i.e., can be extended without the need of re-proving
already proven properties and (2) executable, i.e., we can generate executable code from our
specification. },
keywords = {Document Object Model, DOM, Formal Semantics, Isabelle/HOL},
classification= {conference},
areas = {formal methods, software},
public = {yes}
}
@Article{ klein:operating:2009,
author = {Gerwin Klein},
title = {Operating System Verification --- An Overview},
journal = {S\={a}dhan\={a}},
publisher = pub-springer,
year = 2009,
volume = 34,
number = 1,
month = feb,
pages = {27--69},
abstract = {This paper gives a high-level introduction to the topic of formal, interactive, machine-checked
software verification in general, and the verification of operating systems code in particular. We
survey the state of the art, the advantages and limitations of machine-checked code proofs, and
describe two specific ongoing larger-scale verification projects in more detail.}
}
@InProceedings{ gardner.ea:securing:2009,
author = {Ryan W. Gardner and Sujata Garera and Matthew W. Pagano and Matthew Green and Aviel D. Rubin},
title = {Securing medical records on smart phones},
booktitle = {ACM workshop on Security and privacy in medical and home-care systems (SPIMACS)},
year = 2009,
isbn = {978-1-60558-790-5},
pages = {31--40},
location = {Chicago, Illinois, USA},
doi = {10.1145/1655084.1655090},
address = pub-acm:adr,
publisher = pub-acm,
abstract = {There is an inherent conflict between the desire to maintain privacy of one's medical records and the
need to make those records available during an emergency. To satisfy both objectives, we introduce a
flexible architecture for the secure storage of medical records on smart phones. In our system, a
person can view her records at any time, and emergency medical personnel can view the records as long
as the person is present (even if she is unconscious). Our solution allows for efficient revocation of
access rights and is robust against adversaries who can access the phone's storage offline.}
}
@InProceedings{ raad.ea:dom:2016,
author = {Azalea Raad and Jos{\'{e}} Fragoso Santos and Philippa Gardner},
title = {{DOM:} Specification and Client Reasoning},
booktitle = {Programming Languages and Systems - 14th Asian Symposium, {APLAS} 2016, Hanoi, Vietnam, November
21-23, 2016, Proceedings},
pages = {401--422},
year = 2016,
crossref = {igarashi:programming:2016},
doi = {10.1007/978-3-319-47958-3_21},
abstract = {We present an axiomatic specification of a key fragment of DOM using structural separation logic.
This specification allows us to develop modular reasoning about client programs that call the DOM.}
}
@InProceedings{ bohannon.ea:featherweight:2010,
author = {Aaron Bohannon and Benjamin C. Pierce},
title = {Featherweight {F}irefox: {F}ormalizing the Core of a Web Browser},
booktitle = {Usenix Conference on Web Application Development (WebApps)},
year = 2010,
month = jun,
url = {http://www.cis.upenn.edu/~bohannon/browser-model/},
abstract = {We offer a formal specification of the core functionality of a web browser in the form of a
small-step operational semantics. The specification accurately models the asyn- chronous nature of web
browsers and covers the basic as- pects of windows, DOM trees, cookies, HTTP requests and responses,
user input, and a minimal scripting lan- guage with first-class functions, dynamic evaluation, and
AJAX requests. No security enforcement mechanisms are included{\^a}instead, the model is intended to
serve as a basis for formalizing and experimenting with different security policies and mechanisms. We
survey the most interesting design choices and discuss how our model re- lates to real web browsers.}
}
@Proceedings{ joyce.ea:higher:1994,
editor = {Jeffrey J. Joyce and Carl-Johan H. Seger},
title = {Higher Order Logic Theorem Proving and Its Applications (HUG)},
booktitle = {Higher Order Logic Theorem Proving and Its Applications (HUG)},
publisher = pub-springer,
address = pub-springer:adr,
series = s-lncs,
abstract = {Theorem proving based techniques for formal hardware verification have been evolving constantly and
researchers are getting able to reason about more complex issues than it was possible or practically
feasible in the past. It is often the case that a model of a system is built in a formal logic and
then reasoning about this model is carried out in the logic. Concern is growing on how to consistently
interface a model built in a formal logic with an informal CAD environment. Researchers have been
investigating how to define the formal semantics of hardware description languages so that one can
formally reason about models informally dealt with in a CAD environment. At the University of
Cambridge, the embedding of hardware description languages in a logic is classified in two categories:
deep embedding and shallow embedding. In this paper we argue that there are degrees of formality in
shallow embedding a language in a logic. The choice of the degree of formality is a trade-off between
the security of the embedding and the amount and complexity of the proof effort in the logic. We also
argue that the design of a language could consider this verifiability issue. There are choices in the
design of a language that can make it easier to improve the degree of formality, without implying
serious drawbacks for the CAD environment.},
volume = 780,
year = 1994,
doi = {10.1007/3-540-57826-9},
isbn = {3-540-57826-9},
acknowledgement={brucker, 2007-02-19}
}
@Misc{ whatwg:dom:2017,
key = {whatwg},
author = {{WHATWG}},
url = {https://dom.spec.whatwg.org/commit-snapshots/6253e53af2fbfaa6d25ad09fd54280d8083b2a97/},
month = mar,
year = 2017,
day = 24,
title = {{DOM} -- Living Standard},
note = {Last Updated 24 {March} 2017},
institution = {WHATWG}
}
@Misc{ whatwg:html:2017,
key = {whatwg},
author = {{WHATWG}},
url = {https://html.spec.whatwg.org/},
month = apr,
year = 2017,
day = 13,
title = {{HTML} -- Living Standard},
note = {Last Updated 13 {April} 2017},
institution = {WHATWG}
}
@Misc{ w3c:dom:2015,
key = {w3c},
author = {{W3C}},
url = {https://www.w3.org/TR/dom/},
month = nov,
year = 2015,
day = 19,
title = {{W3C} {DOM4}},
institution = {W3C}
}
@Proceedings{ igarashi:programming:2016,
editor = {Atsushi Igarashi},
title = {Programming Languages and Systems - 14th Asian Symposium, {APLAS} 2016, Hanoi, Vietnam, November
21-23, 2016, Proceedings},
series = {Lecture Notes in Computer Science},
volume = 10017,
year = 2016,
doi = {10.1007/978-3-319-47958-3},
isbn = {978-3-319-47957-6}
}
@InProceedings{ gardner.ea:dom:2008,
author = {Philippa Gardner and Gareth Smith and Mark J. Wheelhouse and Uri Zarfaty},
title = {{DOM:} Towards a Formal Specification},
booktitle = {{PLAN-X} 2008, Programming Language Technologies for XML, An {ACM} {SIGPLAN} Workshop colocated with
{POPL} 2008, San Francisco, California, USA, January 9, 2008},
year = 2008,
crossref = {plan-x:2008},
url = {http://gemo.futurs.inria.fr/events/PLANX2008/papers/p18.pdf},
abstract = {The W3C Document Object Model (DOM) specifies an XML up- date library. DOM is written in English, and
is therefore not compo- sitional and not complete. We provide a first step towards a compo- sitional
specification of DOM. Unlike DOM, we are able to work with a minimal set of commands and obtain a
complete reason- ing for straight-line code. Our work transfers O{\^a}Hearn, Reynolds and Yang{\^a}s
local Hoare reasoning for analysing heaps to XML, viewing XML as an in-place memory store as does DOM.
In par- ticular, we apply recent work by Calcagno, Gardner and Zarfaty on local Hoare reasoning about
a simple tree-update language to DOM, showing that our reasoning scales to DOM. Our reasoning not only
formally specifies a significant subset of DOM Core Level 1, but can also be used to verify e.g.
invariant properties of simple Javascript programs.}
}
@InProceedings{ jang.ea:establishing:2012,
author = {Dongseok Jang and Zachary Tatlock and Sorin Lerner},
title = {Establishing Browser Security Guarantees through Formal Shim Verification},
booktitle = {Proceedings of the 21th {USENIX} Security Symposium, Bellevue, WA, USA, August 8-10, 2012},
pages = {113--128},
year = 2012,
crossref = {kohno:proceedings:2012},
url = {https://www.usenix.org/conference/usenixsecurity12/technical-sessions/presentation/jang},
abstract = { Web browsers mediate access to valuable private data in domains ranging from health care to banking.
Despite this critical role, attackers routinely exploit browser vulnerabilities to exfiltrate private
data and take over the un- derlying system. We present Q UARK , a browser whose kernel has been
implemented and verified in Coq. We give a specification of our kernel, show that the implementation
satisfies the specification, and finally show that the specification implies several security
properties, including tab non-interference, cookie integrity and confidentiality, and address bar
integrity. }
}
@Proceedings{ kohno:proceedings:2012,
editor = {Tadayoshi Kohno},
title = {Proceedings of the 21th {USENIX} Security Symposium, Bellevue, WA, USA, August 8-10, 2012},
publisher = {{USENIX} Association},
year = 2012,
timestamp = {Thu, 15 May 2014 09:12:27 +0200}
}
@Proceedings{ plan-x:2008,
title = {{PLAN-X} 2008, Programming Language Technologies for XML, An {ACM} {SIGPLAN} Workshop colocated with
{POPL} 2008, San Francisco, California, USA, January 9, 2008},
year = 2008,
timestamp = {Fri, 18 Jan 2008 13:01:04 +0100}
}
@Article{ brucker.ea:extensible:2008-b,
abstract = {We present an extensible encoding of object-oriented data models into HOL. Our encoding is supported
by a datatype package that leverages the use of the shallow embedding technique to object-oriented
specification and programming languages. The package incrementally compiles an object-oriented data
model, i.e., a class model, to a theory containing object-universes, constructors, accessor functions,
coercions (casts) between dynamic and static types, characteristic sets, and co-inductive class
invariants. The package is conservative, i.e., all properties are derived entirely from constant
definitions, including the constraints over object structures. As an application, we use the package
for an object-oriented core-language called IMP++, for which we formally prove the correctness of a
Hoare-Logic with respect to a denotational semantics.},
address = {Heidelberg},
author = {Achim D. Brucker and Burkhart Wolff},
doi = {10.1007/s10817-008-9108-3},
issn = {0168-7433},
issue = 3,
journal = {Journal of Automated Reasoning},
keywords = {object-oriented data models, HOL, theorem proving, verification},
language = {USenglish},
pages = {219--249},
pdf = {https://www.brucker.ch/bibliography/download/2008/brucker.ea-extensible-2008-b.pdf},
publisher = {Springer-Verlag},
title = {An Extensible Encoding of Object-oriented Data Models in HOL},
url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-extensible-2008-b},
volume = 41,
year = 2008
}
@PhDThesis{ brucker:interactive:2007,
abstract = {We present a semantic framework for object-oriented specification languages. We develop this
framework as a conservative shallow embedding in Isabelle/HOL. Using only conservative extensions
guarantees by construction the consistency of our formalization. Moreover, we show how our framework
can be used to build an interactive proof environment, called HOL-OCL, for object-oriented
specifications in general and for UML/OCL in particular.\\\\Our main contributions are an extensible
encoding of object-oriented data structures in HOL, a datatype package for object-oriented
specifications, and the development of several equational and tableaux calculi for object-oriented
specifications. Further, we show that our formal framework can be the basis of a formal
machine-checked semantics for OCL that is compliant to the OCL 2.0 standard.},
abstract_de = {In dieser Arbeit wird ein semantisches Rahmenwerk f{\"u}r objektorientierte Spezifikationen
vorgestellt. Das Rahmenwerk ist als konservative, flache Einbettung in Isabelle/HOL realisiert. Durch
die Beschr{\"a}nkung auf konservative Erweiterungen kann die logische Konsistenz der Einbettung
garantiert werden. Das semantische Rahmenwerk wird verwendet, um das interaktives Beweissystem HOL-OCL
f{\"u}r objektorientierte Spezifikationen im Allgemeinen und insbesondere f{\"u}r UML/OCL zu
entwickeln.\\\\Die Hauptbeitr{\"a}ge dieser Arbeit sind die Entwicklung einer erweiterbaren Kodierung
objektorientierter Datenstrukturen in HOL, ein Datentyp-Paket f{\"u}r objektorientierte
Spezifikationen und die Entwicklung verschiedener Kalk{\"u}le f{\"u}r objektorientierte
Spezifikationen. Zudem zeigen wir, wie das formale Rahmenwerk verwendet werden kann, um eine formale,
maschinell gepr{\"u}fte Semantik f{\"u}r OCL anzugeben, die konform zum Standard f{\"u}r OCL 2.0 ist.},
author = {Achim D. Brucker},
keywords = {OCL, UML, formal semantics, theorem proving, Isabelle, HOL-OCL},
month = {mar},
note = {ETH Dissertation No. 17097.},
pdf = {https://www.brucker.ch/bibliography/download/2007/brucker-interactive-2007.pdf},
school = {ETH Zurich},
title = {An Interactive Proof Environment for Object-oriented Specifications},
url = {https://www.brucker.ch/bibliography/abstract/brucker-interactive-2007},
year = 2007
}
@InCollection{ brucker.ea:standard-compliance-testing:2018,
talk = {talk:brucker.ea:standard-compliance-testing:2018},
abstract = {Most popular technologies are based on informal or semiformal standards that lack a rigid formal
semantics. Typical examples include web technologies such as the DOM or HTML, which are defined by the
Web Hypertext Application Technology Working Group (WHATWG) and the World Wide Web Consortium (W3C).
While there might be API specifications and test cases meant to assert the compliance of a certain
implementation, the actual standard is rarely accompanied by a formal model that would lend itself
for, e.g., verifying the security or safety properties of real systems.
Even when such a formalization of a standard exists, two important questions arise: first, to what
extend does the formal model comply to the standard and, second, to what extend does the
implementation comply to the formal model and the assumptions made during the verification? In this
paper, we present an approach that brings all three involved artifacts - the (semi-)formal standard,
the formalization of the standard, and the implementations - closer together by combining
verification, symbolic execution, and specification based testing.},
keywords = {standard compliance, compliance tests, DOM},
location = {Toulouse, France},
author = {Achim D. Brucker and Michael Herzberg},
booktitle = {{TAP} 2018: Tests And Proofs},
language = {USenglish},
publisher = pub-springer,
address = pub-springer:adr,
series = s-lncs,
number = 10889,
editor = {Cathrine Dubois and Burkhart Wolff},
title = {Formalizing (Web) Standards: An Application of Test and Proof},
categories = {holtestgen, websecurity},
classification= {conference},
areas = {formal methods, software engineering},
public = {yes},
year = 2018,
doi = {10.1007/978-3-319-92994-1_9},
pages = {159--166},
isbn = {978-3-642-38915-3},
pdf = {http://www.brucker.ch/bibliography/download/2018/brucker.ea-standard-compliance-testing-2018.pdf},
url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-standard-compliance-testing-2018}
}
@InCollection{ brucker.ea:interactive:2005,
keywords = {symbolic test case generations, black box testing, white box testing, theorem proving, interactive
testing},
abstract = {HOL-TestGen is a test environment for specification-based unit testing build upon the proof assistant
Isabelle/HOL\@. While there is considerable skepticism with regard to interactive theorem provers in
testing communities, we argue that they are a natural choice for (automated) symbolic computations
underlying systematic tests. This holds in particular for the development on non-trivial formal test
plans of complex software, where some parts of the overall activity require inherently guidance by a
test engineer. In this paper, we present the underlying methods for both black box and white box
testing in interactive unit test scenarios. HOL-TestGen can also be understood as a unifying technical
and conceptual framework for presenting and investigating the variety of unit test techniques in a
logically consistent way. },
location = {Edinburgh},
author = {Achim D. Brucker and Burkhart Wolff},
booktitle = {Formal Approaches to Testing of Software},
language = {USenglish},
publisher = pub-springer,
address = pub-springer:adr,
series = s-lncs,
number = 3997,
doi = {10.1007/11759744_7},
isbn = {3-540-25109-X},
editor = {Wolfgang Grieskamp and Carsten Weise},
pdf = {http://www.brucker.ch/bibliography/download/2005/brucker.ea-interactive-2005.pdf},
project = {CSFMDOS},
title = {Interactive Testing using {HOL}-{TestGen}},
classification= {workshop},
areas = {formal methods, software},
categories = {holtestgen},
year = 2005,
public = {yes},
url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-interactive-2005}
}
@Article{ brucker.ea:theorem-prover:2012,
author = {Achim D. Brucker and Burkhart Wolff},
journal = j-fac,
publisher = pub-springer,
address = pub-springer:adr,
language = {USenglish},
categories = {holtestgen},
title = {On Theorem Prover-based Testing},
year = 2013,
issn = {0934-5043},
pages = {683--721},
volume = 25,
number = 5,
classification= {journal},
areas = {formal methods, software},
public = {yes},
doi = {10.1007/s00165-012-0222-y},
keywords = {test case generation, domain partitioning, test sequence, theorem proving, HOL-TestGen},
abstract = {HOL-TestGen is a specification and test case generation environment extending the interactive theorem
prover Isabelle/HOL. As such, HOL-TestGen allows for an integrated workflow supporting interactive
theorem proving, test case generation, and test data generation.
The HOL-TestGen method is two-staged: first, the original formula is partitioned into test cases by
transformation into a normal form called test theorem. Second, the test cases are analyzed for ground
instances (the test data) satisfying the constraints of the test cases. Particular emphasis is put on
the control of explicit test-hypotheses which can be proven over concrete programs.
Due to the generality of the underlying framework, our system can be used for black-box unit,
sequence, reactive sequence and white-box test scenarios. Although based on particularly clean
theoretical foundations, the system can be applied for substantial case-studies. },
pdf = {http://www.brucker.ch/bibliography/download/2012/brucker.ea-theorem-prover-2012.pdf},
url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-theorem-prover-2012}
}
@Article{ brucker.ea:afp-core-dom:2018,
abstract = {In this AFP entry, we formalize the core of the Document Object Model (DOM). At its core, the DOM
defines a tree-like data structure for representing documents in general and HTML documents in
particular. It is the heart of any modern web browser. Formalizing the key concepts of the DOM is a
prerequisite for the formal reasoning over client-side JavaScript programs and for the analysis of
security concepts in modern web browsers. We present a formalization of the core DOM, with focus on
the node-tree and the operations defined on node-trees, in Isabelle/HOL. We use the formalization to
verify the functional correctness of the most important functions defined in the DOM standard.
Moreover, our formalization is 1) extensible, i.e., can be extended without the need of re-proving
already proven properties and 2) executable, i.e., we can generate executable code from our
specification.},
author = {Achim D. Brucker and Michael Herzberg},
date = {2018-12-26},
file = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-outline-2018.pdf},
filelabel = {Outline},
issn = {2150-914x},
journal = {Archive of Formal Proofs},
month = {dec},
note = {\url{http://www.isa-afp.org/entries/Core_DOM.html}, Formal proof development},
pdf = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-2018.pdf},
title = {The Core {DOM}},
url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-afp-core-dom-2018-a},
year = 2018
}
@InCollection{ brucker.ea:web-components:2019,
abstract = {The trend towards ever more complex client-side web applications is unstoppable. Compared to
traditional software development, client-side web development lacks a well-established component
model, i.e., a method for easily and safely reusing already developed functionality. To address this
issue, the web community started to adopt shadow trees as part of the Document Object Model (DOM):
shadow trees allow developers to "partition" a DOM instance into parts that should be safely
separated, e.g., code modifying one part should not, unintentionally, affect other parts of the
DOM.\\\\While shadow trees provide the technical basis for defining web components, the DOM standard
neither defines the concept of web components nor specifies the safety properties that web components
should guarantee. Consequently, the standard also does not discuss how or even if the methods for
modifying the DOM respect component boundaries. In this paper, we present a formally verified model of
web components and define safety properties which ensure that different web components can only
interact with each other using well-defined interfaces. Moreover, our verification of the application
programming interface (API) of the DOM revealed numerous invariants that implementations of the DOM
API need to preserve to ensure the integrity of components.},
address = {Heidelberg},
author = {Achim D. Brucker and Michael Herzberg},
booktitle = {Formal Aspects of Component Software (FACS)},
doi = {10.1007/978-3-030-40914-2_3},
editor = {Sung-Shik Jongmans and Farhad Arbab},
isbn = {3-540-25109-X},
keywords = {Web Component, Shadow Tree, DOM, Isabelle/HOL},
language = {USenglish},
location = {Amsterdam, The Netherlands},
number = 12018,
pdf = {https://www.brucker.ch/bibliography/download/2019/brucker.ea-web-components-2019.pdf},
publisher = {Springer-Verlag},
series = {Lecture Notes in Computer Science},
title = {A Formally Verified Model of Web Components},
url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-web-components-2019},
year = 2020
}
@Article{ brucker.ea:afp-dom-components:2020,
author = {Achim D. Brucker and Michael Herzberg},
title = {A Formalization of Web Components},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
date = {2020-09-28},
note = {\url{http://www.isa-afp.org/entries/DOM_Components.html}, Formal proof development},
issn = {2150-914x},
public = {yes},
classification= {formal},
categories = {websecurity},
pdf = {download/2020/brucker.ea-afp-dom-components-2020.pdf},
filelabel = {Outline},
file = {download/2020/brucker.ea-afp-dom-components-outline-2020.pdf},
areas = {formal methods, security, software engineering}
}
@Article{ brucker.ea:afp-dom-components:2020-a,
author = {Achim D. Brucker and Michael Herzberg},
title = {A Formalization of Web Components},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
date = {2020-09-28},
note = {\url{http://www.isa-afp.org/entries/DOM_Components.html}, Formal proof development},
issn = {2150-914x},
public = {yes},
classification= {formal},
categories = {websecurity},
pdf = {download/2020/brucker.ea-afp-dom-components-2020.pdf},
filelabel = {Outline},
file = {download/2020/brucker.ea-afp-dom-components-outline-2020.pdf},
areas = {formal methods, security, software engineering}
}
@PhdThesis{herzberg:web-components:2020,
author = {Michael Herzberg},
title = {Formal Foundations for Provably Safe Web Components},
school = {The University of Sheffield},
year = {2020}
}

View File

@ -0,0 +1,216 @@
\documentclass[10pt,DIV16,a4paper,abstract=true,twoside=semi,openright]
{scrreprt}
\usepackage[USenglish]{babel}
\usepackage[numbers, sort&compress]{natbib}
\usepackage{isabelle,isabellesym}
\usepackage{booktabs}
\usepackage{paralist}
\usepackage{graphicx}
\usepackage{amssymb}
\usepackage{xspace}
\usepackage{xcolor}
\usepackage{listings}
\lstloadlanguages{HTML}
\usepackage[]{mathtools}
\usepackage[pdfpagelabels, pageanchor=false, plainpages=false]{hyperref}
\lstdefinestyle{html}{language=XML,
basicstyle=\ttfamily,
commentstyle=\itshape,
keywordstyle=\color{blue},
ndkeywordstyle=\color{blue},
}
\lstdefinestyle{displayhtml}{style=html,
floatplacement={tbp},
captionpos=b,
framexleftmargin=0pt,
basicstyle=\ttfamily\scriptsize,
backgroundcolor=\color{black!2},
frame=lines,
}
\lstnewenvironment{html}[1][]{\lstset{style=displayhtml, #1}}{}
\def\inlinehtml{\lstinline[style=html, columns=fullflexible]}
\pagestyle{headings}
\isabellestyle{default}
\setcounter{tocdepth}{1}
\newcommand{\ie}{i.\,e.\xspace}
\newcommand{\eg}{e.\,g.\xspace}
\newcommand{\thy}{\isabellecontext}
\renewcommand{\isamarkupsection}[1]{%
\begingroup%
\def\isacharunderscore{\textunderscore}%
\section{#1 (\thy)}%
\endgroup%
}
\title{Shadow DOM\\\medskip \Large
A Formal Model of the Document Object Model \emph{with Shadow Roots}}%
\author{%
\href{https://www.brucker.ch/}{Achim~D.~Brucker}\footnotemark[1]
\and
\href{https://www.michael-herzberg.de/}{Michael Herzberg}\footnotemark[2]
}
\publishers{
\footnotemark[1]~Department of Computer Science, University of Exeter, Exeter, UK\texorpdfstring{\\}{, }
\texttt{a.brucker@exeter.ac.uk}\\[2em]
%
\footnotemark[2]~ Department of Computer Science, The University of Sheffield, Sheffield, UK\texorpdfstring{\\}{, }
\texttt{msherzberg1@sheffield.ac.uk}
}
\begin{document}
\maketitle
\begin{abstract}
\begin{quote}
In this AFP entry, we extend our formalization of the core DOM
(AFP entry \href{https://www.isa-afp.org/entries/Core_DOM.html}
{Core\_DOM}) with \emph{Shadow Roots}. Shadow roots are a recent
proposal of the web community to support a component-based
development approach for client-side web applications.
Shadow roots are a significant extension to the DOM standard
and, as web standards are condemned to be backward compatible,
such extensions often result in complex specification that may
contain unwanted subtleties that can be detected by a
formalization.
Our Isabelle/HOL formalization is, in the sense of
object-orientation, an extension of our formalization of the
core DOM and enjoys the same basic properties, i.e., it is
\begin{inparaenum}
\item \emph{extensible}, i.e., can be extended without the need of
re-proving already proven properties and
\item \emph{executable}, i.e., we can generate executable code
from our specification.
\end{inparaenum}
We exploit the executability to show that our formalization
complies to the official standard of the W3C, respectively,
the WHATWG.
\bigskip
\noindent{\textbf{Keywords:}}
Document Object Model, DOM, Shadow Root, Web Component, Formal
Semantics, Isabelle/HOL
\end{quote}
\end{abstract}
\tableofcontents
\cleardoublepage
\chapter{Introduction}
In a world in which more and more applications are offered as services
on the internet, web browsers start to take on a similarly central
role in our daily IT infrastructure as operating systems. Thus, web
browsers should be developed as rigidly and formally as operating
systems. While formal methods are a well-established technique in the
development of operating systems (see,
\eg,~\citet{klein:operating:2009} for an overview of formal
verification of operating systems), there are few proposals for
improving the development of web browsers using formal
approaches~\cite{gardner.ea:dom:2008,raad.ea:dom:2016,jang.ea:establishing:2012,bohannon.ea:featherweight:2010}.
In~\cite{brucker.ea:afp-core-dom:2018}, we formalized the core of the
Document Object Model (DOM) in Isabelle/HOL\@. The
DOM~\cite{whatwg:dom:2017,w3c:dom:2015} is \emph{the} central data
structure of all modern web browsers. In this work, we extend the
formalization presented in~\cite{brucker.ea:afp-core-dom:2018} with
support for \emph{shadow trees}. Shadow trees are a recent addition to
the DOM standard~\cite{whatwg:dom:2017} that promise support for web
components. As we will see, this promise is not fully achieved and,
for example, the DOM standard itself does not formally define what a
component should be. In this work, we focus on a standard compliant
representation of the DOM with shadow
trees. As~\cite{brucker.ea:afp-core-dom:2018}, our formalization has
the following properties:
\begin{itemize}
\item It provides a \emph{consistency guarantee.} Since all
definitions in our formal semantics are conservative and all rules
are derived, the logical consistency of the DOM node-tree is reduced
to the consistency of HOL.
\item It serves as a \emph{technical basis for a proof system.} Based
on the derived rules and specific setup of proof tactics over
node-trees, our formalization provides a generic proof environment
for the verification of programs manipulating node-trees.
\item It is \emph{executable}, which allows to validate its compliance
to the standard by evaluating the compliance test suite on the
formal model and
\item It is \emph{extensible} in the sense
of~\cite{brucker.ea:extensible:2008-b,brucker:interactive:2007},
\ie, properties proven over the core DOM do not need to be re-proven
for object-oriented extensions such as the HTML document model.
\end{itemize}
In this AFP entry, we limit ourselves to the faithful formalization of
the DOM. As the DOM standard does not formally define web components,
we address the question of formally defining web components and
discussing their safety properties
elsewhere~\cite{brucker.ea:afp-dom-components:2020,brucker.ea:web-components:2019}.
The rest of this document is automatically generated from the
formalization in Isabelle/HOL, i.e., all content is checked by
Isabelle (we refer readers interested in a more high-level presentation
and additional explanations to~\cite{herzberg:web-components:2020,brucker.ea:web-components:2019}.
The structure follows the theory dependencies
(see \autoref{fig:session-graph}): first, we
formalize the DOM with Shadow Roots (\autoref{cha:dom}) and then
formalize we the relevant compliance test cases in
\autoref{cha:tests}.
\begin{figure}
\centering
\includegraphics[height=.9\textheight]{session_graph}
\caption{The Dependency Graph of the Isabelle Theories.\label{fig:session-graph}}
\end{figure}
\clearpage
\chapter{The Shadow DOM}
\label{cha:dom}
In this chapter, we introduce the formalization of the core DOM
\emph{with Shadow Roots}, i.e., the most important algorithms for
querying or modifying the Shadow DOM, as defined in the standard.
\input{ShadowRootClass.tex}
\input{ShadowRootMonad.tex}
\input{Shadow_DOM.tex}
\chapter{Test Suite}
\label{cha:tests}
In this chapter, we present the formalized compliance test cases for
the core DOM. As our formalization is executable, we can
(symbolically) execute the test cases on top of our model. Executing
these test cases successfully shows that our model is compliant to the
official DOM standard. As future work, we plan to generate test cases
from our formal model (e.g.,
using~\cite{brucker.ea:interactive:2005,brucker.ea:theorem-prover:2012})
to improve the quality of the official compliance test suite. For more
details on the relation of test and proof in the context of web
standards, we refer the reader to
\cite{brucker.ea:standard-compliance-testing:2018}.
\input{Shadow_DOM_BaseTest.tex}
\input{slots.tex}
\input{slots_fallback.tex}
\input{Shadow_DOM_Document_adoptNode.tex}
\input{Shadow_DOM_Document_getElementById.tex}
\input{Shadow_DOM_Node_insertBefore.tex}
\input{Shadow_DOM_Node_removeChild.tex}
\input{Shadow_DOM_Tests.tex}
{\small
\bibliographystyle{abbrvnat}
\bibliography{root}
}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

View File

@ -0,0 +1,711 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
section\<open>Shadow Root Monad\<close>
theory ShadowRootMonad
imports
"Core_DOM.DocumentMonad"
"../classes/ShadowRootClass"
begin
type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document, 'ShadowRoot, 'result) dom_prog
= "((_) heap, exception, 'result) prog"
register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document, 'ShadowRoot, 'result) dom_prog"
global_interpretation l_ptr_kinds_M shadow_root_ptr_kinds defines shadow_root_ptr_kinds_M = a_ptr_kinds_M .
lemmas shadow_root_ptr_kinds_M_defs = a_ptr_kinds_M_def
lemma shadow_root_ptr_kinds_M_eq:
assumes "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
shows "|h \<turnstile> shadow_root_ptr_kinds_M|\<^sub>r = |h' \<turnstile> shadow_root_ptr_kinds_M|\<^sub>r"
using assms
by(auto simp add: shadow_root_ptr_kinds_M_defs object_ptr_kinds_M_defs shadow_root_ptr_kinds_def)
global_interpretation l_dummy defines get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = "l_get_M.a_get_M get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t" .
lemma get_M_is_l_get_M: "l_get_M get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t type_wf shadow_root_ptr_kinds"
apply(simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf l_get_M_def)
by (metis ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf ObjectClass.type_wf_defs bind_eq_None_conv
shadow_root_ptr_kinds_commutes get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def option.simps(3))
lemmas get_M_defs = get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def[unfolded l_get_M.a_get_M_def[OF get_M_is_l_get_M]]
adhoc_overloading get_M get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
locale l_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas = l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
begin
sublocale l_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas by unfold_locales
interpretation l_get_M get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t type_wf shadow_root_ptr_kinds
apply(unfold_locales)
apply (simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf local.type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t)
by (meson ShadowRootMonad.get_M_is_l_get_M l_get_M_def)
lemmas get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok = get_M_ok[folded get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def]
lemmas get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap = get_M_ptr_in_heap[folded get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def]
end
global_interpretation l_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas type_wf by unfold_locales
global_interpretation l_put_M type_wf shadow_root_ptr_kinds get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t rewrites
"a_get_M = get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t" defines put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = a_put_M
apply (simp add: get_M_is_l_get_M l_put_M_def)
by (simp add: get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
lemmas put_M_defs = a_put_M_def
adhoc_overloading put_M put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
locale l_put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas = l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
begin
sublocale l_put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas by unfold_locales
interpretation l_put_M type_wf shadow_root_ptr_kinds get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
apply(unfold_locales)
apply (simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf local.type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t)
by (meson ShadowRootMonad.get_M_is_l_get_M l_get_M_def)
lemmas put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok = put_M_ok[folded put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def]
end
global_interpretation l_put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas type_wf by unfold_locales
lemma shadow_root_put_get [simp]: "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> (\<And>x. getter (setter (\<lambda>_. v) x) = v)
\<Longrightarrow> h' \<turnstile> get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter \<rightarrow>\<^sub>r v"
by(auto simp add: put_M_defs get_M_defs split: option.splits)
lemma get_M_Mshadow_root_preserved1 [simp]:
"shadow_root_ptr \<noteq> shadow_root_ptr'
\<Longrightarrow> h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
lemma shadow_root_put_get_preserved [simp]:
"h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> (\<And>x. getter (setter (\<lambda>_. v) x) = getter x)
\<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
apply(cases "shadow_root_ptr = shadow_root_ptr'")
by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved2 [simp]:
"h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
by(auto simp add: put_M_defs get_M_defs NodeMonad.get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved3 [simp]:
"cast shadow_root_ptr \<noteq> object_ptr
\<Longrightarrow> h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
by(auto simp add: put_M_defs get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def ObjectMonad.get_M_defs
preserved_def split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved4 [simp]:
"h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
\<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
apply(cases "cast shadow_root_ptr \<noteq> object_ptr")[1]
by(auto simp add: put_M_defs get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
ObjectMonad.get_M_defs preserved_def
split: option.splits bind_splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved5 [simp]:
"cast shadow_root_ptr \<noteq> object_ptr
\<Longrightarrow> h \<turnstile> put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
by(auto simp add: ObjectMonad.put_M_defs get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def ObjectMonad.get_M_defs
preserved_def split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved6 [simp]:
"h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter) h h'"
by(auto simp add: put_M_defs ElementMonad.get_M_defs preserved_def
split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved7 [simp]:
"h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
by(auto simp add: ElementMonad.put_M_defs get_M_defs preserved_def
split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved8 [simp]:
"h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter) h h'"
by(auto simp add: put_M_defs CharacterDataMonad.get_M_defs preserved_def
split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved9 [simp]:
"h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
\<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
by(auto simp add: CharacterDataMonad.put_M_defs get_M_defs preserved_def
split: option.splits dest: get_heap_E)
lemma get_M_Mshadow_root_preserved10 [simp]:
"(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
\<Longrightarrow> h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
apply(cases "cast shadow_root_ptr = object_ptr")
by(auto simp add: put_M_defs get_M_defs ObjectMonad.get_M_defs NodeMonad.get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def bind_eq_Some_conv
split: option.splits)
lemma new_element_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
"h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
by(auto simp add: new_element_def get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_character_data_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
"h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
by(auto simp add: new_character_data_def get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_document_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
"h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
by(auto simp add: new_document_def get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
definition delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M :: "(_) shadow_root_ptr \<Rightarrow> (_, unit) dom_prog" where
"delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr = do {
h \<leftarrow> get_heap;
(case delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h of
Some h \<Rightarrow> return_heap h |
None \<Rightarrow> error HierarchyRequestError)
}"
adhoc_overloading delete_M delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M
lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ok [simp]:
assumes "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
shows "h \<turnstile> ok (delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr)"
using assms
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: prod.splits)
lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_in_heap:
assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
using assms
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap:
assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
shows "shadow_root_ptr |\<notin>| shadow_root_ptr_kinds h'"
using assms
apply(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)[1]
by (metis comp_apply fmdom_notI fmdrop_lookup heap.sel object_ptr_kinds_def shadow_root_ptr_kinds_commutes)
lemma delete_shadow_root_pointers:
assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
shows "object_ptr_kinds h = object_ptr_kinds h' |\<union>| {|cast shadow_root_ptr|}"
using assms
apply(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def split: option.splits)[1]
apply (metis (no_types, lifting) ObjectClass.a_type_wf_def ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_pointer_ptr_in_heap fmlookup_drop get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def heap.sel option.sel
shadow_root_ptr_kinds_commutes)
using delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_pointer_ptr_in_heap apply blast
by (metis (no_types, lifting) ObjectClass.a_type_wf_def ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_pointer_ptr_in_heap fmlookup_drop get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def heap.sel option.sel
shadow_root_ptr_kinds_commutes)
lemma delete_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
ptr \<noteq> cast shadow_root_ptr \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def ObjectMonad.get_M_defs preserved_def
split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
lemma delete_shadow_root_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr getter) h h'"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def NodeMonad.get_M_defs ObjectMonad.get_M_defs
preserved_def split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
lemma delete_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def ElementMonad.get_M_defs NodeMonad.get_M_defs
ObjectMonad.get_M_defs preserved_def split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
lemma delete_shadow_root_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr getter) h h'"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def CharacterDataMonad.get_M_defs
NodeMonad.get_M_defs ObjectMonad.get_M_defs preserved_def split: prod.splits option.splits if_splits
elim!: bind_returns_heap_E)
lemma delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def DocumentMonad.get_M_defs ObjectMonad.get_M_defs
preserved_def split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
lemma delete_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
shadow_root_ptr \<noteq> shadow_root_ptr' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get_M_defs ObjectMonad.get_M_defs
preserved_def split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
lemma shadow_root_put_get_1 [simp]: "shadow_root_ptr \<noteq> shadow_root_ptr' \<Longrightarrow>
h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
lemma shadow_root_put_get_2 [simp]: "(\<And>x. getter (setter (\<lambda>_. v) x) = getter x) \<Longrightarrow>
h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
by (cases "shadow_root_ptr = shadow_root_ptr'") (auto simp add: put_M_defs get_M_defs preserved_def
split: option.splits dest: get_heap_E)
lemma shadow_root_put_get_3 [simp]: "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter) h h'"
by(auto simp add: put_M_defs ElementMonad.get_M_defs preserved_def split: option.splits
dest: get_heap_E)
lemma shadow_root_put_get_4 [simp]: "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
by(auto simp add: ElementMonad.put_M_defs get_M_defs preserved_def split: option.splits
dest: get_heap_E)
lemma shadow_root_put_get_5 [simp]: "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter) h h'"
by(auto simp add: put_M_defs CharacterDataMonad.get_M_defs preserved_def split: option.splits
dest: get_heap_E)
lemma shadow_root_put_get_6 [simp]: "h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
by(auto simp add: CharacterDataMonad.put_M_defs get_M_defs preserved_def split: option.splits
dest: get_heap_E)
lemma shadow_root_put_get_7 [simp]: "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
by(auto simp add: put_M_defs DocumentMonad.get_M_defs preserved_def split: option.splits
dest: get_heap_E)
lemma shadow_root_put_get_8 [simp]: "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow>
preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
by(auto simp add: DocumentMonad.put_M_defs get_M_defs preserved_def split: option.splits
dest: get_heap_E)
lemma shadow_root_put_get_9 [simp]: "(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x)) \<Longrightarrow>
h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
by (cases "cast shadow_root_ptr = object_ptr") (auto simp add: put_M_defs get_M_defs
ObjectMonad.get_M_defs NodeMonad.get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def bind_eq_Some_conv split: option.splits)
subsection \<open>new\_M\<close>
definition new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M :: "(_, (_) shadow_root_ptr) dom_prog"
where
"new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M = do {
h \<leftarrow> get_heap;
(new_ptr, h') \<leftarrow> return (new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h);
return_heap h';
return new_ptr
}"
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ok [simp]:
"h \<turnstile> ok new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M"
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def split: prod.splits)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_in_heap:
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
and "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
shows "new_shadow_root_ptr |\<in>| shadow_root_ptr_kinds h'"
using assms
unfolding new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap is_OK_returns_result_I
elim!: bind_returns_result_E bind_returns_heap_E)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap:
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
and "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
shows "new_shadow_root_ptr |\<notin>| shadow_root_ptr_kinds h"
using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_not_in_heap
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_new_ptr:
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
and "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_new_ptr
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_is_shadow_root_ptr:
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
shows "is_shadow_root_ptr new_shadow_root_ptr"
using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_is_shadow_root_ptr
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def elim!: bind_returns_result_E split: prod.splits)
lemma new_shadow_root_mode:
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
shows "h' \<turnstile> get_M new_shadow_root_ptr mode \<rightarrow>\<^sub>r Open"
using assms
by(auto simp add: get_M_defs new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def
split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_shadow_root_children:
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
shows "h' \<turnstile> get_M new_shadow_root_ptr child_nodes \<rightarrow>\<^sub>r []"
using assms
by(auto simp add: get_M_defs new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def
split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:
"h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
\<Longrightarrow> ptr \<noteq> cast new_shadow_root_ptr \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def ObjectMonad.get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_shadow_root_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e:
"h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
\<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr getter) h h'"
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def NodeMonad.get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
"h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
\<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def ElementMonad.get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_shadow_root_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a:
"h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
\<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr getter) h h'"
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def CharacterDataMonad.get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
"h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
\<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
\<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def DocumentMonad.get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
lemma new_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
"h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
\<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> ptr \<noteq> new_shadow_root_ptr
\<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def get_M_defs preserved_def
split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
subsection \<open>modified heaps\<close>
lemma shadow_root_get_put_1 [simp]: "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) = (if ptr = cast shadow_root_ptr
then cast obj else get shadow_root_ptr h)"
by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def split: option.splits Option.bind_splits)
lemma shadow_root_ptr_kinds_new[simp]: "shadow_root_ptr_kinds (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) = shadow_root_ptr_kinds h |\<union>|
(if is_shadow_root_ptr_kind ptr then {|the (cast ptr)|} else {||})"
by(auto simp add: shadow_root_ptr_kinds_def split: option.splits)
lemma type_wf_put_I:
assumes "type_wf h"
assumes "DocumentClass.type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
assumes "is_shadow_root_ptr_kind ptr \<Longrightarrow> is_shadow_root_kind obj"
shows "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
using assms
by(auto simp add: type_wf_defs is_shadow_root_kind_def split: option.splits)
lemma type_wf_put_ptr_not_in_heap_E:
assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
assumes "ptr |\<notin>| object_ptr_kinds h"
shows "type_wf h"
using assms
by(auto simp add: type_wf_defs elim!: DocumentMonad.type_wf_put_ptr_not_in_heap_E
split: option.splits if_splits)
lemma type_wf_put_ptr_in_heap_E:
assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
assumes "ptr |\<in>| object_ptr_kinds h"
assumes "DocumentClass.type_wf h"
assumes "is_shadow_root_ptr_kind ptr \<Longrightarrow> is_shadow_root_kind (the (get ptr h))"
shows "type_wf h"
using assms
apply(auto simp add: type_wf_defs elim!: DocumentMonad.type_wf_put_ptr_in_heap_E
split: option.splits if_splits)[1]
by (metis (no_types, hide_lams) ObjectClass.a_type_wf_def ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf
bind.bind_lunit finite_set_in get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def is_shadow_root_kind_def option.exhaust_sel)
subsection \<open>type\_wf\<close>
lemma new_element_type_wf_preserved [simp]:
assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
obtain new_element_ptr where "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
using assms
by (meson is_OK_returns_heap_I is_OK_returns_result_E)
with assms have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
using new_element_new_ptr by auto
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by auto
with assms show ?thesis
by(auto simp add: ElementMonad.new_element_def type_wf_defs Let_def elim!: bind_returns_heap_E
split: prod.splits)
qed
lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_tag_name_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M element_ptr tag_name_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
qed
lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_child_nodes_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M element_ptr RElement.child_nodes_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
qed
lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_attrs_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M element_ptr attrs_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
qed
lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_shadow_root_opt_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M element_ptr shadow_root_opt_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
qed
lemma new_character_data_type_wf_preserved [simp]:
assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
obtain new_character_data_ptr where "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr"
using assms
by (meson is_OK_returns_heap_I is_OK_returns_result_E)
with assms have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
using new_character_data_new_ptr by auto
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by auto
with assms show ?thesis
by(auto simp add: CharacterDataMonad.new_character_data_def type_wf_defs Let_def
elim!: bind_returns_heap_E split: prod.splits)
qed
lemma put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_val_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M character_data_ptr val_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: CharacterDataMonad.put_M_defs type_wf_defs)
qed
lemma new_document_type_wf_preserved [simp]:
assumes "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
obtain new_document_ptr where "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
using assms
by (meson is_OK_returns_heap_I is_OK_returns_result_E)
with assms have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_document_ptr|}"
using new_document_new_ptr by auto
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by auto
with assms show ?thesis
by(auto simp add: DocumentMonad.new_document_def type_wf_defs Let_def elim!: bind_returns_heap_E
split: prod.splits)
qed
lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_doctype_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M document_ptr doctype_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: DocumentMonad.put_M_defs type_wf_defs)
qed
lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_document_element_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M document_ptr document_element_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: DocumentMonad.put_M_defs type_wf_defs)
qed
lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_disconnected_nodes_type_wf_preserved [simp]:
assumes "h \<turnstile> put_M document_ptr disconnected_nodes_update v \<rightarrow>\<^sub>h h'"
shows "type_wf h = type_wf h'"
proof -
have "object_ptr_kinds h = object_ptr_kinds h'"
using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
unfolding shadow_root_ptr_kinds_def by simp
with assms show ?thesis
by(auto simp add: DocumentMonad.put_M_defs type_wf_defs)
qed
lemma put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_mode_type_wf_preserved [simp]:
"h \<turnstile> put_M shadow_root_ptr mode_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
by(auto simp add: get_M_defs is_shadow_root_kind_def type_wf_defs ElementClass.type_wf_defs
NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
CharacterDataClass.type_wf_defs DocumentClass.type_wf_defs put_M_defs
put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
dest!: get_heap_E
elim!: bind_returns_heap_E2
intro!: type_wf_put_I DocumentMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
split: option.splits)
lemma put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_child_nodes_type_wf_preserved [simp]:
"h \<turnstile> put_M shadow_root_ptr RShadowRoot.child_nodes_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
by(auto simp add: get_M_defs is_shadow_root_kind_def type_wf_defs ElementClass.type_wf_defs
NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
CharacterDataClass.type_wf_defs DocumentClass.type_wf_defs put_M_defs
put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
dest!: get_heap_E
elim!: bind_returns_heap_E2
intro!: type_wf_put_I DocumentMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
split: option.splits)
lemma shadow_root_ptr_kinds_small:
assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
shows "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
by(simp add: shadow_root_ptr_kinds_def preserved_def object_ptr_kinds_preserved_small[OF assms])
lemma shadow_root_ptr_kinds_preserved:
assumes "writes SW setter h h'"
assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow>
(\<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h')"
shows "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
using writes_small_big[OF assms]
apply(simp add: reflp_def transp_def preserved_def shadow_root_ptr_kinds_def)
by (metis assms object_ptr_kinds_preserved)
lemma new_shadow_root_known_ptr:
assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
shows "known_ptr (cast new_shadow_root_ptr)"
using assms
apply(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def a_known_ptr_def
elim!: bind_returns_result_E2 split: prod.splits)[1]
using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_is_shadow_root_ptr by blast
lemma new_shadow_root_type_wf_preserved [simp]: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
apply(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ShadowRootClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ShadowRootClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
ShadowRootClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e ShadowRootClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
is_node_ptr_kind_none new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_not_in_heap
elim!: bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
intro!: type_wf_put_I DocumentMonad.type_wf_put_I ElementMonad.type_wf_put_I
CharacterDataMonad.type_wf_put_I
NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
split: if_splits)[1]
by(auto simp add: type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
CharacterDataClass.type_wf_defs
NodeClass.type_wf_defs ObjectClass.type_wf_defs is_shadow_root_kind_def is_document_kind_def
split: option.splits)[1]
locale l_new_shadow_root = l_type_wf +
assumes new_shadow_root_types_preserved: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
lemma new_shadow_root_is_l_new_shadow_root [instances]: "l_new_shadow_root type_wf"
using l_new_shadow_root.intro new_shadow_root_type_wf_preserved
by blast
lemma type_wf_preserved_small:
assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
assumes "\<And>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
assumes "\<And>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
assumes "\<And>character_data_ptr. preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr RCharacterData.nothing) h h'"
assumes "\<And>document_ptr. preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr RDocument.nothing) h h'"
assumes "\<And>shadow_root_ptr. preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr RShadowRoot.nothing) h h'"
shows "type_wf h = type_wf h'"
using type_wf_preserved_small[OF assms(1) assms(2) assms(3) assms(4) assms(5)]
allI[OF assms(6), of id, simplified] shadow_root_ptr_kinds_small[OF assms(1)]
apply(auto simp add: type_wf_defs preserved_def get_M_defs shadow_root_ptr_kinds_small[OF assms(1)]
split: option.splits)[1]
apply(force)
apply(force)
done
lemma new_element_is_l_new_element [instances]:
"l_new_element type_wf"
using l_new_element.intro new_element_type_wf_preserved
by blast
lemma new_character_data_is_l_new_character_data [instances]:
"l_new_character_data type_wf"
using l_new_character_data.intro new_character_data_type_wf_preserved
by blast
lemma new_document_is_l_new_document [instances]:
"l_new_document type_wf"
using l_new_document.intro new_document_type_wf_preserved
by blast
lemma type_wf_preserved:
assumes "writes SW setter h h'"
assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
\<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
\<forall>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
\<forall>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
\<forall>character_data_ptr. preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr RCharacterData.nothing) h h'"
assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
\<forall>document_ptr. preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr RDocument.nothing) h h'"
assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
\<forall>shadow_root_ptr. preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr RShadowRoot.nothing) h h'"
shows "type_wf h = type_wf h'"
proof -
have "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
using assms type_wf_preserved_small by fast
with assms(1) assms(2) show ?thesis
apply(rule writes_small_big)
by(auto simp add: reflp_def transp_def)
qed
lemma type_wf_drop: "type_wf h \<Longrightarrow> type_wf (Heap (fmdrop ptr (the_heap h)))"
apply(auto simp add: type_wf_defs)[1]
using type_wf_drop
apply blast
by (metis (no_types, lifting) DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ElementClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf
ElementMonad.type_wf_drop fmember.rep_eq fmlookup_drop get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
object_ptr_kinds_code5 shadow_root_ptr_kinds_commutes)
lemma delete_shadow_root_type_wf_preserved [simp]:
assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
assumes "type_wf h"
shows "type_wf h'"
using assms
using type_wf_drop
by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
end

View File

@ -0,0 +1,36 @@
<!doctype html>
<meta charset=utf-8>
<title>Document.adoptNode</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-adoptnode">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<x<>x</x<>
<script>
test(function() {
var y = document.getElementsByTagName("x<")[0]
var child = y.firstChild
assert_equals(y.parentNode, document.body)
assert_equals(y.ownerDocument, document)
assert_equals(document.adoptNode(y), y)
assert_equals(y.parentNode, null)
assert_equals(y.firstChild, child)
assert_equals(y.ownerDocument, document)
assert_equals(child.ownerDocument, document)
var doc = document.implementation.createDocument(null, null, null)
assert_equals(doc.adoptNode(y), y)
assert_equals(y.parentNode, null)
assert_equals(y.firstChild, child)
assert_equals(y.ownerDocument, doc)
assert_equals(child.ownerDocument, doc)
}, "Adopting an Element called 'x<' should work.")
test(function() {
var x = document.createElement(":good:times:")
assert_equals(document.adoptNode(x), x);
var doc = document.implementation.createDocument(null, null, null)
assert_equals(doc.adoptNode(x), x)
assert_equals(x.parentNode, null)
assert_equals(x.ownerDocument, doc)
}, "Adopting an Element called ':good:times:' should work.")
</script>

View File

@ -0,0 +1,251 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Document.getElementById</title>
<link rel="author" title="Tetsuharu OHZEKI" href="mailto:saneyuki.snyk@gmail.com">
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-getelementbyid">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<div id="log"></div>
<div id=""></div>
<div id="test1"></div>
<div id="test5" data-name="1st">
<p id="test5" data-name="2nd">P</p>
<input id="test5" type="submit" value="Submit" data-name="3rd">
</div>
<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>
<script>
test(function() {
var gBody = document.body;
var TEST_ID = "test2";
var test = document.createElement("div");
test.setAttribute("id", TEST_ID);
gBody.appendChild(test);
// test: appended element
var result = document.getElementById(TEST_ID);
assert_not_equals(result, null, "should not be null.");
assert_equals(result.tagName, "div", "should have appended element's tag name");
// test: removed element
gBody.removeChild(test);
var removed = document.getElementById(TEST_ID);
// `document.getElementById()` returns `null` if there is none.
// https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
assert_equals(removed, null, "should not get removed element.");
}, "Document.getElementById with a script-inserted element");
test(function() {
var gBody = document.body;
// setup fixtures.
var TEST_ID = "test3";
var test = document.createElement("div");
test.setAttribute("id", TEST_ID);
gBody.appendChild(test);
// update id
var UPDATED_ID = "test3-updated";
test.setAttribute("id", UPDATED_ID);
var e = document.getElementById(UPDATED_ID);
assert_equals(e, test, "should get the element with id.");
var old = document.getElementById(TEST_ID);
assert_equals(old, null, "shouldn't get the element by the old id.");
// remove id.
test.removeAttribute("id");
var e2 = document.getElementById(UPDATED_ID);
assert_equals(e2, null, "should return null when the passed id is none in document.");
}, "update `id` attribute via setAttribute/removeAttribute");
test(function() {
var TEST_ID = "test4-should-not-exist";
var e = document.createElement('div');
e.setAttribute("id", TEST_ID);
assert_equals(document.getElementById(TEST_ID), null, "should be null");
document.body.appendChild(e);
assert_equals(document.getElementById(TEST_ID), e, "should be the appended element");
}, "Ensure that the id attribute only affects elements present in a document");
test(function() {
var gBody = document.body;
// the method should return the 1st element.
var TEST_ID = "test5";
var target = document.getElementById(TEST_ID);
assert_not_equals(target, null, "should not be null");
assert_equals(target.getAttribute("data-name"), "1st", "should return the 1st");
// even if after the new element was appended.
var element4 = document.createElement("div");
element4.setAttribute("id", TEST_ID);
element4.setAttribute("data-name", "4th");
gBody.appendChild(element4);
var target2 = document.getElementById(TEST_ID);
assert_not_equals(target2, null, "should not be null");
assert_equals(target2.getAttribute("data-name"), "1st", "should be the 1st");
// should return the next element after removed the subtree including the 1st element.
target2.parentNode.removeChild(target2);
var target3 = document.getElementById(TEST_ID);
assert_not_equals(target3, null, "should not be null");
assert_equals(target3.getAttribute("data-name"), "4th", "should be the 4th");
}, "in tree order, within the context object's tree");
test(function() {
var TEST_ID = "test6";
var s = document.createElement("div");
s.setAttribute("id", TEST_ID);
// append to Element, not Document.
document.createElement("div").appendChild(s);
assert_equals(document.getElementById(TEST_ID), null, "should be null");
}, "Modern browsers optimize this method with using internal id cache. This test checks that their optimization should effect only append to `Document`, not append to `Node`.");
test(function() {
var gBody = document.body;
var TEST_ID = "test7"
var element = document.createElement("div");
element.setAttribute("id", TEST_ID);
gBody.appendChild(element);
var target = document.getElementById(TEST_ID);
assert_equals(target, element, "should return the element before changing the value");
element.setAttribute("id", TEST_ID + "-updated");
var target2 = document.getElementById(TEST_ID);
assert_equals(target2, null, "should return null after updated id via Attr.value");
var target3 = document.getElementById(TEST_ID + "-updated");
assert_equals(target3, element, "should be equal to the updated element.");
}, "changing attribute's value via `Attr` gotten from `Element.attribute`.");
test(function() {
var gBody = document.body;
// setup fixtures.
var TEST_ID = "test12";
var test = document.createElement("div");
test.setAttribute("id", TEST_ID);
gBody.appendChild(test);
// update id
var UPDATED_ID = TEST_ID + "-updated";
test.setAttribute("id", UPDATED_ID);
var e = document.getElementById(UPDATED_ID);
assert_equals(e, test, "should get the element with id.");
var old = document.getElementById(TEST_ID);
assert_equals(old, null, "shouldn't get the element by the old id.");
// remove id.
test.setAttribute("id", "");
var e2 = document.getElementById(UPDATED_ID);
assert_equals(e2, null, "should return null when the passed id is none in document.");
}, "update `id` attribute via element.id");
test(function() {
var gBody = document.body;
var TEST_ID = "test13";
// create fixture
var container = document.createElement("div");
container.setAttribute("id", TEST_ID + "-fixture");
gBody.appendChild(container);
var element1 = document.createElement("div");
element1.setAttribute("id", TEST_ID);
var element2 = document.createElement("div");
element2.setAttribute("id", TEST_ID);
var element3 = document.createElement("div");
element3.setAttribute("id", TEST_ID);
var element4 = document.createElement("div");
element4.setAttribute("id", TEST_ID);
// append element: 2 -> 4 -> 3 -> 1
container.appendChild(element2);
container.appendChild(element4);
container.insertBefore(element3, element4);
container.insertBefore(element1, element2);
var test = document.getElementById(TEST_ID);
assert_equals(test, element1, "should return 1st element");
container.removeChild(element1);
test = document.getElementById(TEST_ID);
assert_equals(test, element2, "should return 2nd element");
container.removeChild(element2);
test = document.getElementById(TEST_ID);
assert_equals(test, element3, "should return 3rd element");
container.removeChild(element3);
test = document.getElementById(TEST_ID);
assert_equals(test, element4, "should return 4th element");
container.removeChild(element4);
}, "where insertion order and tree order don't match");
test(function() {
var gBody = document.body;
var TEST_ID = "test14";
var a = document.createElement("a");
var b = document.createElement("b");
a.appendChild(b);
b.setAttribute("id", TEST_ID);
assert_equals(document.getElementById(TEST_ID), null);
gBody.appendChild(a);
assert_equals(document.getElementById(TEST_ID), b);
}, "Inserting an id by inserting its parent node");
test(function () {
var TEST_ID = "test15"
var outer = document.getElementById("outer");
var middle = document.getElementById("middle");
var inner = document.getElementById("inner");
outer.removeChild(middle);
var new_el = document.createElement("h1");
new_el.setAttribute("id", "heading");
inner.appendChild(new_el);
// the new element is not part of the document since
// "middle" element was removed previously
assert_equals(document.getElementById("heading"), null);
}, "Document.getElementById must not return nodes not present in document");
// TODO:
// id attribute in a namespace
// TODO:
// SVG + MathML elements with id attributes
</script>
</body>
</html>

View File

@ -0,0 +1,288 @@
<!DOCTYPE html>
<title>Node.insertBefore</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<div id="log"></div>
</body>
<script>
test(function() {
var node = document.createTextNode("Foo");
assert_throws("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(document.createTextNode("fail"), null) })
}, "Calling insertBefore an a leaf node Text must throw HIERARCHY_REQUEST_ERR.")
test(function() {
// Step 2.
assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.body, document.getElementById("log")) })
assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.documentElement, document.getElementById("log")) })
}, "Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY_REQUEST_ERR.")
// Step 3.
test(function() {
var a = document.createElement("div");
var b = document.createElement("div");
var c = document.createElement("div");
assert_throws("NotFoundError", function() {
a.insertBefore(b, c);
});
}, "Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError.")
// Step 4.1.
test(function() {
var doc = document.implementation.createHTMLDocument("title");
var doc2 = document.implementation.createHTMLDocument("title2");
assert_throws("HierarchyRequestError", function() {
doc.insertBefore(doc2, doc.documentElement);
});
assert_throws("HierarchyRequestError", function() {
doc.insertBefore(doc.createTextNode("text"), doc.documentElement);
});
}, "If the context node is a document, inserting a document or text node should throw a HierarchyRequestError.")
//
// // Step 4.2.1.
// test(function() {
// var doc = document.implementation.createHTMLDocument("title");
// doc.removeChild(doc.documentElement);
//
// var df = doc.createDocumentFragment();
// df.appendChild(doc.createElement("a"));
// df.appendChild(doc.createElement("b"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, null);
// });
//
// df = doc.createDocumentFragment();
// df.appendChild(doc.createTextNode("text"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, null);
// });
//
// df = doc.createDocumentFragment();
// df.appendChild(doc.createComment("comment"));
// df.appendChild(doc.createTextNode("text"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, null);
// });
// }, "If the context node is a document, appending a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
// test(function() {
// var doc = document.implementation.createHTMLDocument("title");
// doc.removeChild(doc.documentElement);
//
// var df = doc.createDocumentFragment();
// df.appendChild(doc.createElement("a"));
// df.appendChild(doc.createElement("b"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, doc.firstChild);
// });
//
// df = doc.createDocumentFragment();
// df.appendChild(doc.createTextNode("text"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, doc.firstChild);
// });
//
// df = doc.createDocumentFragment();
// df.appendChild(doc.createComment("comment"));
// df.appendChild(doc.createTextNode("text"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, doc.firstChild);
// });
// }, "If the context node is a document, inserting a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
//
// // Step 4.2.2.
// test(function() {
// // The context node has an element child.
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.appendChild(doc.createComment("foo"));
// assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
//
// var df = doc.createDocumentFragment();
// df.appendChild(doc.createElement("a"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, doc.doctype);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, doc.documentElement);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, comment);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, null);
// });
// }, "If the context node is a document, inserting a DocumentFragment with an element if there already is an element child should throw a HierarchyRequestError.")
// test(function() {
// // /child/ is a doctype.
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
// doc.removeChild(doc.documentElement);
// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
//
// var df = doc.createDocumentFragment();
// df.appendChild(doc.createElement("a"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, doc.doctype);
// });
// }, "If the context node is a document and a doctype is following the reference child, inserting a DocumentFragment with an element should throw a HierarchyRequestError.")
// test(function() {
// // /child/ is not null and a doctype is following /child/.
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
// doc.removeChild(doc.documentElement);
// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
//
// var df = doc.createDocumentFragment();
// df.appendChild(doc.createElement("a"));
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(df, comment);
// });
// }, "If the context node is a document, inserting a DocumentFragment with an element before the doctype should throw a HierarchyRequestError.")
//
// // Step 4.3.
// test(function() {
// // The context node has an element child.
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.appendChild(doc.createComment("foo"));
// assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
//
// var a = doc.createElement("a");
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(a, doc.doctype);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(a, doc.documentElement);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(a, comment);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(a, null);
// });
// }, "If the context node is a document, inserting an element if there already is an element child should throw a HierarchyRequestError.")
// test(function() {
// // /child/ is a doctype.
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
// doc.removeChild(doc.documentElement);
// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
//
// var a = doc.createElement("a");
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(a, doc.doctype);
// });
// }, "If the context node is a document, inserting an element before the doctype should throw a HierarchyRequestError.")
// test(function() {
// // /child/ is not null and a doctype is following /child/.
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
// doc.removeChild(doc.documentElement);
// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
//
// var a = doc.createElement("a");
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(a, comment);
// });
// }, "If the context node is a document and a doctype is following the reference child, inserting an element should throw a HierarchyRequestError.")
//
// // Step 4.4.
// test(function() {
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
// assert_array_equals(doc.childNodes, [comment, doc.doctype, doc.documentElement]);
//
// var doctype = document.implementation.createDocumentType("html", "", "");
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(doctype, comment);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(doctype, doc.doctype);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(doctype, doc.documentElement);
// });
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(doctype, null);
// });
// }, "If the context node is a document, inserting a doctype if there already is a doctype child should throw a HierarchyRequestError.")
// test(function() {
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.appendChild(doc.createComment("foo"));
// doc.removeChild(doc.doctype);
// assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
//
// var doctype = document.implementation.createDocumentType("html", "", "");
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(doctype, comment);
// });
// }, "If the context node is a document, inserting a doctype after the document element should throw a HierarchyRequestError.")
// test(function() {
// var doc = document.implementation.createHTMLDocument("title");
// var comment = doc.appendChild(doc.createComment("foo"));
// doc.removeChild(doc.doctype);
// assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
//
// var doctype = document.implementation.createDocumentType("html", "", "");
// assert_throws("HierarchyRequestError", function() {
// doc.insertBefore(doctype, null);
// });
// }, "If the context node is a document with and element child, appending a doctype should throw a HierarchyRequestError.")
//
// // Step 5.
// test(function() {
// var df = document.createDocumentFragment();
// var a = df.appendChild(document.createElement("a"));
//
// var doc = document.implementation.createHTMLDocument("title");
// assert_throws("HierarchyRequestError", function() {
// df.insertBefore(doc, a);
// });
// assert_throws("HierarchyRequestError", function() {
// df.insertBefore(doc, null);
// });
//
// var doctype = document.implementation.createDocumentType("html", "", "");
// assert_throws("HierarchyRequestError", function() {
// df.insertBefore(doctype, a);
// });
// assert_throws("HierarchyRequestError", function() {
// df.insertBefore(doctype, null);
// });
// }, "If the context node is a DocumentFragment, inserting a document or a doctype should throw a HierarchyRequestError.")
// test(function() {
// var el = document.createElement("div");
// var a = el.appendChild(document.createElement("a"));
//
// var doc = document.implementation.createHTMLDocument("title");
// assert_throws("HierarchyRequestError", function() {
// el.insertBefore(doc, a);
// });
// assert_throws("HierarchyRequestError", function() {
// el.insertBefore(doc, null);
// });
//
// var doctype = document.implementation.createDocumentType("html", "", "");
// assert_throws("HierarchyRequestError", function() {
// el.insertBefore(doctype, a);
// });
// assert_throws("HierarchyRequestError", function() {
// el.insertBefore(doctype, null);
// });
// }, "If the context node is an element, inserting a document or a doctype should throw a HierarchyRequestError.")
//
// Step 7.
test(function() {
var a = document.createElement("div");
var b = document.createElement("div");
var c = document.createElement("div");
a.appendChild(b);
a.appendChild(c);
assert_array_equals(a.childNodes, [b, c]);
assert_equals(a.insertBefore(b, b), b);
assert_array_equals(a.childNodes, [b, c]);
assert_equals(a.insertBefore(c, c), c);
assert_array_equals(a.childNodes, [b, c]);
}, "Inserting a node before itself should not move the node");
</script>

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<title>Node.removeChild</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="creators.js"></script>
<body>
<div id="log"></div>
</body>
<iframe src=about:blank></iframe>
<script>
test(function() {
var doc = document;
var s = doc.createElement("div");
assert_equals(s.ownerDocument, doc)
assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
assert_equals(s.ownerDocument, doc)
}, "Passing a detached Element to removeChild should not affect it.")
test(function() {
var doc = document;
var s = doc.createElement("div");
doc.documentElement.appendChild(s)
assert_equals(s.ownerDocument, doc)
assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
assert_equals(s.ownerDocument, doc)
}, "Passing a non-detached Element to removeChild should not affect it.")
test(function() {
var doc = document;
var s = doc.createElement("div");
doc.body.appendChild(s)
assert_equals(s.ownerDocument, doc)
assert_throws("NOT_FOUND_ERR", function() { s.removeChild(doc) })
}, "Calling removeChild on an Element with no children should throw NOT_FOUND_ERR.")
test(function() {
var doc = document.implementation.createHTMLDocument("");
var s = doc.createElement("div");
assert_equals(s.ownerDocument, doc)
assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
assert_equals(s.ownerDocument, doc)
}, "Passing a detached Element to removeChild should not affect it.")
test(function() {
var doc = document.implementation.createHTMLDocument("");
var s = doc.createElement("div");
doc.documentElement.appendChild(s)
assert_equals(s.ownerDocument, doc)
assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
assert_equals(s.ownerDocument, doc)
}, "Passing a non-detached Element to removeChild should not affect it.")
test(function() {
var doc = document.implementation.createHTMLDocument("");
var s = doc.createElement("div");
doc.body.appendChild(s)
assert_equals(s.ownerDocument, doc)
assert_throws("NOT_FOUND_ERR", function() { s.removeChild(doc) })
}, "Calling removeChild on an Element with no children should throw NOT_FOUND_ERR.")
test(function() {
assert_throws(new TypeError(), function() { document.body.removeChild(null) })
//assert_throws(new TypeError(), function() { document.body.removeChild({'a':'b'}) })
}, "Passing a value that is not a Node reference to removeChild should throw TypeError.")
</script>

View File

@ -0,0 +1,373 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
section\<open>Shadow DOM Base Tests\<close>
theory Shadow_DOM_BaseTest
imports
"../Shadow_DOM"
begin
definition "assert_throws e p = do {
h \<leftarrow> get_heap;
(if (h \<turnstile> p \<rightarrow>\<^sub>e e) then return () else error AssertException)
}"
notation assert_throws ("assert'_throws'(_, _')")
definition "test p h \<longleftrightarrow> h \<turnstile> ok p"
definition field_access :: "(string \<Rightarrow> (_, (_) object_ptr option) dom_prog) \<Rightarrow> string \<Rightarrow>
(_, (_) object_ptr option) dom_prog" (infix "." 80)
where
"field_access m field = m field"
definition assert_equals :: "'a \<Rightarrow> 'a \<Rightarrow> (_, unit) dom_prog"
where
"assert_equals l r = (if l = r then return () else error AssertException)"
definition assert_equals_with_message :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> (_, unit) dom_prog"
where
"assert_equals_with_message l r _ = (if l = r then return () else error AssertException)"
notation assert_equals ("assert'_equals'(_, _')")
notation assert_equals_with_message ("assert'_equals'(_, _, _')")
notation assert_equals ("assert'_array'_equals'(_, _')")
notation assert_equals_with_message ("assert'_array'_equals'(_, _, _')")
definition assert_not_equals :: "'a \<Rightarrow> 'a \<Rightarrow> (_, unit) dom_prog"
where
"assert_not_equals l r = (if l \<noteq> r then return () else error AssertException)"
definition assert_not_equals_with_message :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> (_, unit) dom_prog"
where
"assert_not_equals_with_message l r _ = (if l \<noteq> r then return () else error AssertException)"
notation assert_not_equals ("assert'_not'_equals'(_, _')")
notation assert_not_equals_with_message ("assert'_not'_equals'(_, _, _')")
notation assert_not_equals ("assert'_array'_not'_equals'(_, _')")
notation assert_not_equals_with_message ("assert'_array'_not'_equals'(_, _, _')")
(* TODO: why don't the code equations of noop work here? *)
definition removeWhiteSpaceOnlyTextNodes :: "((_) object_ptr option) \<Rightarrow> (_, unit) dom_prog"
where
"removeWhiteSpaceOnlyTextNodes _ = return ()"
subsection \<open>Making the functions under test compatible with untyped languages such as JavaScript\<close>
fun set_attribute_with_null :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> attr_value \<Rightarrow> (_, unit) dom_prog"
where
"set_attribute_with_null (Some ptr) k v = (case cast ptr of
Some element_ptr \<Rightarrow> set_attribute element_ptr k (Some v))"
fun set_attribute_with_null2 :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> attr_value option \<Rightarrow> (_, unit) dom_prog"
where
"set_attribute_with_null2 (Some ptr) k v = (case cast ptr of
Some element_ptr \<Rightarrow> set_attribute element_ptr k v)"
notation set_attribute_with_null ("_ . setAttribute'(_, _')")
notation set_attribute_with_null2 ("_ . setAttribute'(_, _')")
fun get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null :: "((_) object_ptr option) \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
where
"get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null (Some ptr) = do {
children \<leftarrow> get_child_nodes ptr;
return (map (Some \<circ> cast) children)
}"
notation get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null ("_ . childNodes")
fun create_element_with_null :: "((_) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"create_element_with_null (Some owner_document_obj) tag = (case cast owner_document_obj of
Some owner_document \<Rightarrow> do {
element_ptr \<leftarrow> create_element owner_document tag;
return (Some (cast element_ptr))})"
notation create_element_with_null ("_ . createElement'(_')")
fun create_character_data_with_null :: "((_) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"create_character_data_with_null (Some owner_document_obj) tag = (case cast owner_document_obj of
Some owner_document \<Rightarrow> do {
character_data_ptr \<leftarrow> create_character_data owner_document tag;
return (Some (cast character_data_ptr))})"
notation create_character_data_with_null ("_ . createTextNode'(_')")
definition create_document_with_null :: "string \<Rightarrow> (_, ((_::linorder) object_ptr option)) dom_prog"
where
"create_document_with_null title = do {
new_document_ptr \<leftarrow> create_document;
html \<leftarrow> create_element new_document_ptr ''html'';
append_child (cast new_document_ptr) (cast html);
heap \<leftarrow> create_element new_document_ptr ''heap'';
append_child (cast html) (cast heap);
body \<leftarrow> create_element new_document_ptr ''body'';
append_child (cast html) (cast body);
return (Some (cast new_document_ptr))
}"
abbreviation "create_document_with_null2 _ _ _ \<equiv> create_document_with_null ''''"
notation create_document_with_null ("createDocument'(_')")
notation create_document_with_null2 ("createDocument'(_, _, _')")
fun get_element_by_id_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"get_element_by_id_with_null (Some ptr) id' = do {
element_ptr_opt \<leftarrow> get_element_by_id ptr id';
(case element_ptr_opt of
Some element_ptr \<Rightarrow> return (Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr))
| None \<Rightarrow> return None)}"
| "get_element_by_id_with_null _ _ = error SegmentationFault"
notation get_element_by_id_with_null ("_ . getElementById'(_')")
fun get_elements_by_class_name_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option) list) dom_prog"
where
"get_elements_by_class_name_with_null (Some ptr) class_name =
get_elements_by_class_name ptr class_name \<bind> map_M (return \<circ> Some \<circ> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)"
notation get_elements_by_class_name_with_null ("_ . getElementsByClassName'(_')")
fun get_elements_by_tag_name_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option) list) dom_prog"
where
"get_elements_by_tag_name_with_null (Some ptr) tag =
get_elements_by_tag_name ptr tag \<bind> map_M (return \<circ> Some \<circ> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)"
notation get_elements_by_tag_name_with_null ("_ . getElementsByTagName'(_')")
fun insert_before_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow>
(_, ((_) object_ptr option)) dom_prog"
where
"insert_before_with_null (Some ptr) (Some child_obj) ref_child_obj_opt = (case cast child_obj of
Some child \<Rightarrow> do {
(case ref_child_obj_opt of
Some ref_child_obj \<Rightarrow> insert_before ptr child (cast ref_child_obj)
| None \<Rightarrow> insert_before ptr child None);
return (Some child_obj)}
| None \<Rightarrow> error HierarchyRequestError)"
notation insert_before_with_null ("_ . insertBefore'(_, _')")
fun append_child_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> (_, unit) dom_prog"
where
"append_child_with_null (Some ptr) (Some child_obj) = (case cast child_obj of
Some child \<Rightarrow> append_child ptr child
| None \<Rightarrow> error SegmentationFault)"
notation append_child_with_null ("_ . appendChild'(_')")
code_thms append_child_with_null
fun get_body :: "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"get_body ptr = do {
ptrs \<leftarrow> ptr . getElementsByTagName(''body'');
return (hd ptrs)
}"
notation get_body ("_ . body")
fun get_document_element_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"get_document_element_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
Some document_ptr \<Rightarrow> do {
element_ptr_opt \<leftarrow> get_M document_ptr document_element;
return (case element_ptr_opt of
Some element_ptr \<Rightarrow> Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr)
| None \<Rightarrow> None)})"
notation get_document_element_with_null ("_ . documentElement")
fun get_owner_document_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"get_owner_document_with_null (Some ptr) = (do {
document_ptr \<leftarrow> get_owner_document ptr;
return (Some (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr))})"
notation get_owner_document_with_null ("_ . ownerDocument")
fun remove_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"remove_with_null (Some child) = (case cast child of
Some child_node \<Rightarrow> do {
remove child_node;
return (Some child)}
| None \<Rightarrow> error NotFoundError)"
| "remove_with_null None = error TypeError"
notation remove_with_null ("_ . remove'(')")
fun remove_child_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"remove_child_with_null (Some ptr) (Some child) = (case cast child of
Some child_node \<Rightarrow> do {
remove_child ptr child_node;
return (Some child)}
| None \<Rightarrow> error NotFoundError)"
| "remove_child_with_null None _ = error TypeError"
| "remove_child_with_null _ None = error TypeError"
notation remove_child_with_null ("_ . removeChild")
fun get_tag_name_with_null :: "((_) object_ptr option) \<Rightarrow> (_, attr_value) dom_prog"
where
"get_tag_name_with_null (Some ptr) = (case cast ptr of
Some element_ptr \<Rightarrow> get_M element_ptr tag_name)"
notation get_tag_name_with_null ("_ . tagName")
abbreviation "remove_attribute_with_null ptr k \<equiv> set_attribute_with_null2 ptr k None"
notation remove_attribute_with_null ("_ . removeAttribute'(_')")
fun get_attribute_with_null :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> (_, attr_value option) dom_prog"
where
"get_attribute_with_null (Some ptr) k = (case cast ptr of
Some element_ptr \<Rightarrow> get_attribute element_ptr k)"
fun get_attribute_with_null2 :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> (_, attr_value) dom_prog"
where
"get_attribute_with_null2 (Some ptr) k = (case cast ptr of
Some element_ptr \<Rightarrow> do {
a \<leftarrow> get_attribute element_ptr k;
return (the a)})"
notation get_attribute_with_null ("_ . getAttribute'(_')")
notation get_attribute_with_null2 ("_ . getAttribute'(_')")
fun get_parent_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> (_, (_) object_ptr option) dom_prog"
where
"get_parent_with_null (Some ptr) = (case cast ptr of
Some node_ptr \<Rightarrow> get_parent node_ptr)"
notation get_parent_with_null ("_ . parentNode")
fun first_child_with_null :: "((_) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"first_child_with_null (Some ptr) = do {
child_opt \<leftarrow> first_child ptr;
return (case child_opt of
Some child \<Rightarrow> Some (cast child)
| None \<Rightarrow> None)}"
notation first_child_with_null ("_ . firstChild")
fun adopt_node_with_null ::
"((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
where
"adopt_node_with_null (Some ptr) (Some child) = (case cast ptr of
Some document_ptr \<Rightarrow> (case cast child of
Some child_node \<Rightarrow> do {
adopt_node document_ptr child_node;
return (Some child)}))"
notation adopt_node_with_null ("_ . adoptNode'(_')")
fun get_shadow_root_with_null :: "((_) object_ptr option) \<Rightarrow> (_, (_) object_ptr option) dom_prog"
where
"get_shadow_root_with_null (Some ptr) = (case cast ptr of
Some element_ptr \<Rightarrow> do {
shadow_root \<leftarrow> get_shadow_root element_ptr;
(case shadow_root of Some sr \<Rightarrow> return (Some (cast sr))
| None \<Rightarrow> return None)})"
notation get_shadow_root_with_null ("_ . shadowRoot")
subsection \<open>Making the functions under test compatible with untyped languages such as JavaScript\<close>
fun get_element_by_id_si_with_null ::
"(_::linorder) object_ptr option \<Rightarrow> string \<Rightarrow> (_, (_) object_ptr option) dom_prog"
where
"get_element_by_id_si_with_null (Some ptr) id' = do {
element_ptr_opt \<leftarrow> get_element_by_id_si ptr id';
(case element_ptr_opt of
Some element_ptr \<Rightarrow> return (Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr))
| None \<Rightarrow> return None)}"
| "get_element_by_id_si_with_null _ _ = error SegmentationFault"
fun find_slot_closed_with_null ::
"(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option) dom_prog"
where
"find_slot_closed_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
Some node_ptr \<Rightarrow> do {
element_ptr_opt \<leftarrow> find_slot True node_ptr;
(case element_ptr_opt of
Some element_ptr \<Rightarrow> return (Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr))
| None \<Rightarrow> return None)}
| None \<Rightarrow> error SegmentationFault)"
| "find_slot_closed_with_null None = error SegmentationFault"
notation find_slot_closed_with_null ("_ . assignedSlot")
fun assigned_nodes_with_null ::
"(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
where
"assigned_nodes_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
Some element_ptr \<Rightarrow> do {
l \<leftarrow> assigned_nodes element_ptr;
return (map Some (map cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r l))}
| None \<Rightarrow> error SegmentationFault)"
| "assigned_nodes_with_null None = error SegmentationFault"
notation assigned_nodes_with_null ("_ . assignedNodes'(')")
fun assigned_nodes_flatten_with_null ::
"(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
where
"assigned_nodes_flatten_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
Some element_ptr \<Rightarrow> do {
l \<leftarrow> assigned_nodes_flatten element_ptr;
return (map Some (map cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r l))}
| None \<Rightarrow> error SegmentationFault)"
| "assigned_nodes_flatten_with_null None = error SegmentationFault"
notation assigned_nodes_flatten_with_null ("_ . assignedNodes'(True')")
fun get_assigned_elements_with_null ::
"(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
where
"get_assigned_elements_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
Some element_ptr \<Rightarrow> do {
l \<leftarrow> assigned_nodes element_ptr;
l \<leftarrow> map_filter_M (return \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) l;
return (map Some (map cast l))}
| None \<Rightarrow> error SegmentationFault)"
| "get_assigned_elements_with_null None = error SegmentationFault"
notation get_assigned_elements_with_null ("_ . assignedElements'(')")
fun get_assigned_elements_flatten_with_null ::
"(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
where
"get_assigned_elements_flatten_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
Some element_ptr \<Rightarrow> do {
l \<leftarrow> assigned_nodes_flatten element_ptr;
return (map Some (map cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r l))}
| None \<Rightarrow> error SegmentationFault)"
| "get_assigned_elements_flatten_with_null None = error SegmentationFault"
notation get_assigned_elements_flatten_with_null ("_ . assignedElements'(True')")
fun createTestTree ::
"(_::linorder) object_ptr option \<Rightarrow> (_, string \<Rightarrow> (_, (_) object_ptr option) dom_prog) dom_prog"
where
"createTestTree (Some ref) = do {
tups \<leftarrow> to_tree_order_si ref \<bind> map_filter_M (\<lambda>ptr. do {
(case cast ptr of
Some element_ptr \<Rightarrow> do {
iden_opt \<leftarrow> get_attribute element_ptr ''id'';
(case iden_opt of
Some iden \<Rightarrow> return (Some (iden, ptr))
| None \<Rightarrow> return None)
}
| None \<Rightarrow> return None)});
return (return \<circ> map_of tups)
}"
| "createTestTree None = error SegmentationFault"
end

View File

@ -0,0 +1,114 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
(* This file is automatically generated, please do not modify! *)
section\<open>Testing Document\_adoptNode\<close>
text\<open>This theory contains the test cases for Document\_adoptNode.\<close>
theory Shadow_DOM_Document_adoptNode
imports
"Shadow_DOM_BaseTest"
begin
definition Document_adoptNode_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
"Document_adoptNode_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
(cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 8)] fmempty None)),
(cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7)] fmempty None)),
(cast (element_ptr.Ref 3), cast (create_element_obj ''meta'' [] (fmap_of_list [(''charset'', ''utf-8'')]) None)),
(cast (element_ptr.Ref 4), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
(cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Document.adoptNode'')),
(cast (element_ptr.Ref 5), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''help''), (''href'', ''https://dom.spec.whatwg.org/#dom-document-adoptnode'')]) None)),
(cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
(cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
(cast (element_ptr.Ref 8), cast (create_element_obj ''body'' [cast (element_ptr.Ref 9), cast (element_ptr.Ref 10), cast (element_ptr.Ref 11)] fmempty None)),
(cast (element_ptr.Ref 9), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
(cast (element_ptr.Ref 10), cast (create_element_obj ''x<'' [cast (character_data_ptr.Ref 2)] fmempty None)),
(cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''x'')),
(cast (element_ptr.Ref 11), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
(cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
definition Document_adoptNode_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Document_adoptNode_document = Some (cast (document_ptr.Ref 1))"
text \<open>"Adopting an Element called 'x<' should work."\<close>
lemma "test (do {
tmp0 \<leftarrow> Document_adoptNode_document . getElementsByTagName(''x<'');
y \<leftarrow> return (tmp0 ! 0);
child \<leftarrow> y . firstChild;
tmp1 \<leftarrow> y . parentNode;
tmp2 \<leftarrow> Document_adoptNode_document . body;
assert_equals(tmp1, tmp2);
tmp3 \<leftarrow> y . ownerDocument;
assert_equals(tmp3, Document_adoptNode_document);
tmp4 \<leftarrow> Document_adoptNode_document . adoptNode(y);
assert_equals(tmp4, y);
tmp5 \<leftarrow> y . parentNode;
assert_equals(tmp5, None);
tmp6 \<leftarrow> y . firstChild;
assert_equals(tmp6, child);
tmp7 \<leftarrow> y . ownerDocument;
assert_equals(tmp7, Document_adoptNode_document);
tmp8 \<leftarrow> child . ownerDocument;
assert_equals(tmp8, Document_adoptNode_document);
doc \<leftarrow> createDocument(None, None, None);
tmp9 \<leftarrow> doc . adoptNode(y);
assert_equals(tmp9, y);
tmp10 \<leftarrow> y . parentNode;
assert_equals(tmp10, None);
tmp11 \<leftarrow> y . firstChild;
assert_equals(tmp11, child);
tmp12 \<leftarrow> y . ownerDocument;
assert_equals(tmp12, doc);
tmp13 \<leftarrow> child . ownerDocument;
assert_equals(tmp13, doc)
}) Document_adoptNode_heap"
by eval
text \<open>"Adopting an Element called ':good:times:' should work."\<close>
lemma "test (do {
x \<leftarrow> Document_adoptNode_document . createElement('':good:times:'');
tmp0 \<leftarrow> Document_adoptNode_document . adoptNode(x);
assert_equals(tmp0, x);
doc \<leftarrow> createDocument(None, None, None);
tmp1 \<leftarrow> doc . adoptNode(x);
assert_equals(tmp1, x);
tmp2 \<leftarrow> x . parentNode;
assert_equals(tmp2, None);
tmp3 \<leftarrow> x . ownerDocument;
assert_equals(tmp3, doc)
}) Document_adoptNode_heap"
by eval
end

View File

@ -0,0 +1,278 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
(* This file is automatically generated, please do not modify! *)
section\<open>Testing Document\_getElementById\<close>
text\<open>This theory contains the test cases for Document\_getElementById.\<close>
theory Shadow_DOM_Document_getElementById
imports
"Shadow_DOM_BaseTest"
begin
definition Document_getElementById_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
"Document_getElementById_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
(cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 9)] fmempty None)),
(cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7), cast (element_ptr.Ref 8)] fmempty None)),
(cast (element_ptr.Ref 3), cast (create_element_obj ''meta'' [] (fmap_of_list [(''charset'', ''utf-8'')]) None)),
(cast (element_ptr.Ref 4), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
(cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Document.getElementById'')),
(cast (element_ptr.Ref 5), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''author''), (''title'', ''Tetsuharu OHZEKI''), (''href'', ''mailto:saneyuki.snyk@gmail.com'')]) None)),
(cast (element_ptr.Ref 6), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''help''), (''href'', ''https://dom.spec.whatwg.org/#dom-document-getelementbyid'')]) None)),
(cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
(cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
(cast (element_ptr.Ref 9), cast (create_element_obj ''body'' [cast (element_ptr.Ref 10), cast (element_ptr.Ref 11), cast (element_ptr.Ref 12), cast (element_ptr.Ref 13), cast (element_ptr.Ref 16), cast (element_ptr.Ref 19)] fmempty None)),
(cast (element_ptr.Ref 10), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
(cast (element_ptr.Ref 11), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', '''')]) None)),
(cast (element_ptr.Ref 12), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''test1'')]) None)),
(cast (element_ptr.Ref 13), cast (create_element_obj ''div'' [cast (element_ptr.Ref 14), cast (element_ptr.Ref 15)] (fmap_of_list [(''id'', ''test5''), (''data-name'', ''1st'')]) None)),
(cast (element_ptr.Ref 14), cast (create_element_obj ''p'' [cast (character_data_ptr.Ref 2)] (fmap_of_list [(''id'', ''test5''), (''data-name'', ''2nd'')]) None)),
(cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''P'')),
(cast (element_ptr.Ref 15), cast (create_element_obj ''input'' [] (fmap_of_list [(''id'', ''test5''), (''type'', ''submit''), (''value'', ''Submit''), (''data-name'', ''3rd'')]) None)),
(cast (element_ptr.Ref 16), cast (create_element_obj ''div'' [cast (element_ptr.Ref 17)] (fmap_of_list [(''id'', ''outer'')]) None)),
(cast (element_ptr.Ref 17), cast (create_element_obj ''div'' [cast (element_ptr.Ref 18)] (fmap_of_list [(''id'', ''middle'')]) None)),
(cast (element_ptr.Ref 18), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''inner'')]) None)),
(cast (element_ptr.Ref 19), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
(cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
definition Document_getElementById_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Document_getElementById_document = Some (cast (document_ptr.Ref 1))"
text \<open>"Document.getElementById with a script-inserted element"\<close>
lemma "test (do {
gBody \<leftarrow> Document_getElementById_document . body;
TEST_ID \<leftarrow> return ''test2'';
test \<leftarrow> Document_getElementById_document . createElement(''div'');
test . setAttribute(''id'', TEST_ID);
gBody . appendChild(test);
result \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_not_equals(result, None, ''should not be null.'');
tmp0 \<leftarrow> result . tagName;
assert_equals(tmp0, ''div'', ''should have appended element's tag name'');
gBody . removeChild(test);
removed \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(removed, None, ''should not get removed element.'')
}) Document_getElementById_heap"
by eval
text \<open>"update `id` attribute via setAttribute/removeAttribute"\<close>
lemma "test (do {
gBody \<leftarrow> Document_getElementById_document . body;
TEST_ID \<leftarrow> return ''test3'';
test \<leftarrow> Document_getElementById_document . createElement(''div'');
test . setAttribute(''id'', TEST_ID);
gBody . appendChild(test);
UPDATED_ID \<leftarrow> return ''test3-updated'';
test . setAttribute(''id'', UPDATED_ID);
e \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
assert_equals(e, test, ''should get the element with id.'');
old \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(old, None, ''shouldn't get the element by the old id.'');
test . removeAttribute(''id'');
e2 \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
assert_equals(e2, None, ''should return null when the passed id is none in document.'')
}) Document_getElementById_heap"
by eval
text \<open>"Ensure that the id attribute only affects elements present in a document"\<close>
lemma "test (do {
TEST_ID \<leftarrow> return ''test4-should-not-exist'';
e \<leftarrow> Document_getElementById_document . createElement(''div'');
e . setAttribute(''id'', TEST_ID);
tmp0 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(tmp0, None, ''should be null'');
tmp1 \<leftarrow> Document_getElementById_document . body;
tmp1 . appendChild(e);
tmp2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(tmp2, e, ''should be the appended element'')
}) Document_getElementById_heap"
by eval
text \<open>"in tree order, within the context object's tree"\<close>
lemma "test (do {
gBody \<leftarrow> Document_getElementById_document . body;
TEST_ID \<leftarrow> return ''test5'';
target \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_not_equals(target, None, ''should not be null'');
tmp0 \<leftarrow> target . getAttribute(''data-name'');
assert_equals(tmp0, ''1st'', ''should return the 1st'');
element4 \<leftarrow> Document_getElementById_document . createElement(''div'');
element4 . setAttribute(''id'', TEST_ID);
element4 . setAttribute(''data-name'', ''4th'');
gBody . appendChild(element4);
target2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_not_equals(target2, None, ''should not be null'');
tmp1 \<leftarrow> target2 . getAttribute(''data-name'');
assert_equals(tmp1, ''1st'', ''should be the 1st'');
tmp2 \<leftarrow> target2 . parentNode;
tmp2 . removeChild(target2);
target3 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_not_equals(target3, None, ''should not be null'');
tmp3 \<leftarrow> target3 . getAttribute(''data-name'');
assert_equals(tmp3, ''4th'', ''should be the 4th'')
}) Document_getElementById_heap"
by eval
text \<open>"Modern browsers optimize this method with using internal id cache. This test checks that their optimization should effect only append to `Document`, not append to `Node`."\<close>
lemma "test (do {
TEST_ID \<leftarrow> return ''test6'';
s \<leftarrow> Document_getElementById_document . createElement(''div'');
s . setAttribute(''id'', TEST_ID);
tmp0 \<leftarrow> Document_getElementById_document . createElement(''div'');
tmp0 . appendChild(s);
tmp1 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(tmp1, None, ''should be null'')
}) Document_getElementById_heap"
by eval
text \<open>"changing attribute's value via `Attr` gotten from `Element.attribute`."\<close>
lemma "test (do {
gBody \<leftarrow> Document_getElementById_document . body;
TEST_ID \<leftarrow> return ''test7'';
element \<leftarrow> Document_getElementById_document . createElement(''div'');
element . setAttribute(''id'', TEST_ID);
gBody . appendChild(element);
target \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(target, element, ''should return the element before changing the value'');
element . setAttribute(''id'', (TEST_ID @ ''-updated''));
target2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(target2, None, ''should return null after updated id via Attr.value'');
target3 \<leftarrow> Document_getElementById_document . getElementById((TEST_ID @ ''-updated''));
assert_equals(target3, element, ''should be equal to the updated element.'')
}) Document_getElementById_heap"
by eval
text \<open>"update `id` attribute via element.id"\<close>
lemma "test (do {
gBody \<leftarrow> Document_getElementById_document . body;
TEST_ID \<leftarrow> return ''test12'';
test \<leftarrow> Document_getElementById_document . createElement(''div'');
test . setAttribute(''id'', TEST_ID);
gBody . appendChild(test);
UPDATED_ID \<leftarrow> return (TEST_ID @ ''-updated'');
test . setAttribute(''id'', UPDATED_ID);
e \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
assert_equals(e, test, ''should get the element with id.'');
old \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(old, None, ''shouldn't get the element by the old id.'');
test . setAttribute(''id'', '''');
e2 \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
assert_equals(e2, None, ''should return null when the passed id is none in document.'')
}) Document_getElementById_heap"
by eval
text \<open>"where insertion order and tree order don't match"\<close>
lemma "test (do {
gBody \<leftarrow> Document_getElementById_document . body;
TEST_ID \<leftarrow> return ''test13'';
container \<leftarrow> Document_getElementById_document . createElement(''div'');
container . setAttribute(''id'', (TEST_ID @ ''-fixture''));
gBody . appendChild(container);
element1 \<leftarrow> Document_getElementById_document . createElement(''div'');
element1 . setAttribute(''id'', TEST_ID);
element2 \<leftarrow> Document_getElementById_document . createElement(''div'');
element2 . setAttribute(''id'', TEST_ID);
element3 \<leftarrow> Document_getElementById_document . createElement(''div'');
element3 . setAttribute(''id'', TEST_ID);
element4 \<leftarrow> Document_getElementById_document . createElement(''div'');
element4 . setAttribute(''id'', TEST_ID);
container . appendChild(element2);
container . appendChild(element4);
container . insertBefore(element3, element4);
container . insertBefore(element1, element2);
test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(test, element1, ''should return 1st element'');
container . removeChild(element1);
test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(test, element2, ''should return 2nd element'');
container . removeChild(element2);
test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(test, element3, ''should return 3rd element'');
container . removeChild(element3);
test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(test, element4, ''should return 4th element'');
container . removeChild(element4)
}) Document_getElementById_heap"
by eval
text \<open>"Inserting an id by inserting its parent node"\<close>
lemma "test (do {
gBody \<leftarrow> Document_getElementById_document . body;
TEST_ID \<leftarrow> return ''test14'';
a \<leftarrow> Document_getElementById_document . createElement(''a'');
b \<leftarrow> Document_getElementById_document . createElement(''b'');
a . appendChild(b);
b . setAttribute(''id'', TEST_ID);
tmp0 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(tmp0, None);
gBody . appendChild(a);
tmp1 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
assert_equals(tmp1, b)
}) Document_getElementById_heap"
by eval
text \<open>"Document.getElementById must not return nodes not present in document"\<close>
lemma "test (do {
TEST_ID \<leftarrow> return ''test15'';
outer \<leftarrow> Document_getElementById_document . getElementById(''outer'');
middle \<leftarrow> Document_getElementById_document . getElementById(''middle'');
inner \<leftarrow> Document_getElementById_document . getElementById(''inner'');
tmp0 \<leftarrow> Document_getElementById_document . getElementById(''middle'');
outer . removeChild(tmp0);
new_el \<leftarrow> Document_getElementById_document . createElement(''h1'');
new_el . setAttribute(''id'', ''heading'');
inner . appendChild(new_el);
tmp1 \<leftarrow> Document_getElementById_document . getElementById(''heading'');
assert_equals(tmp1, None)
}) Document_getElementById_heap"
by eval
end

View File

@ -0,0 +1,129 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
(* This file is automatically generated, please do not modify! *)
section\<open>Testing Node\_insertBefore\<close>
text\<open>This theory contains the test cases for Node\_insertBefore.\<close>
theory Shadow_DOM_Node_insertBefore
imports
"Shadow_DOM_BaseTest"
begin
definition Node_insertBefore_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
"Node_insertBefore_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
(cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 6)] fmempty None)),
(cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5)] fmempty None)),
(cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
(cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Node.insertBefore'')),
(cast (element_ptr.Ref 4), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
(cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
(cast (element_ptr.Ref 6), cast (create_element_obj ''body'' [cast (element_ptr.Ref 7), cast (element_ptr.Ref 8)] fmempty None)),
(cast (element_ptr.Ref 7), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
(cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
(cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
definition Node_insertBefore_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Node_insertBefore_document = Some (cast (document_ptr.Ref 1))"
text \<open>"Calling insertBefore an a leaf node Text must throw HIERARCHY\_REQUEST\_ERR."\<close>
lemma "test (do {
node \<leftarrow> Node_insertBefore_document . createTextNode(''Foo'');
tmp0 \<leftarrow> Node_insertBefore_document . createTextNode(''fail'');
assert_throws(HierarchyRequestError, node . insertBefore(tmp0, None))
}) Node_insertBefore_heap"
by eval
text \<open>"Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY\_REQUEST\_ERR."\<close>
lemma "test (do {
tmp1 \<leftarrow> Node_insertBefore_document . body;
tmp2 \<leftarrow> Node_insertBefore_document . getElementById(''log'');
tmp0 \<leftarrow> Node_insertBefore_document . body;
assert_throws(HierarchyRequestError, tmp0 . insertBefore(tmp1, tmp2));
tmp4 \<leftarrow> Node_insertBefore_document . documentElement;
tmp5 \<leftarrow> Node_insertBefore_document . getElementById(''log'');
tmp3 \<leftarrow> Node_insertBefore_document . body;
assert_throws(HierarchyRequestError, tmp3 . insertBefore(tmp4, tmp5))
}) Node_insertBefore_heap"
by eval
text \<open>"Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError."\<close>
lemma "test (do {
a \<leftarrow> Node_insertBefore_document . createElement(''div'');
b \<leftarrow> Node_insertBefore_document . createElement(''div'');
c \<leftarrow> Node_insertBefore_document . createElement(''div'');
assert_throws(NotFoundError, a . insertBefore(b, c))
}) Node_insertBefore_heap"
by eval
text \<open>"If the context node is a document, inserting a document or text node should throw a HierarchyRequestError."\<close>
lemma "test (do {
doc \<leftarrow> createDocument(''title'');
doc2 \<leftarrow> createDocument(''title2'');
tmp0 \<leftarrow> doc . documentElement;
assert_throws(HierarchyRequestError, doc . insertBefore(doc2, tmp0));
tmp1 \<leftarrow> doc . createTextNode(''text'');
tmp2 \<leftarrow> doc . documentElement;
assert_throws(HierarchyRequestError, doc . insertBefore(tmp1, tmp2))
}) Node_insertBefore_heap"
by eval
text \<open>"Inserting a node before itself should not move the node"\<close>
lemma "test (do {
a \<leftarrow> Node_insertBefore_document . createElement(''div'');
b \<leftarrow> Node_insertBefore_document . createElement(''div'');
c \<leftarrow> Node_insertBefore_document . createElement(''div'');
a . appendChild(b);
a . appendChild(c);
tmp0 \<leftarrow> a . childNodes;
assert_array_equals(tmp0, [b, c]);
tmp1 \<leftarrow> a . insertBefore(b, b);
assert_equals(tmp1, b);
tmp2 \<leftarrow> a . childNodes;
assert_array_equals(tmp2, [b, c]);
tmp3 \<leftarrow> a . insertBefore(c, c);
assert_equals(tmp3, c);
tmp4 \<leftarrow> a . childNodes;
assert_array_equals(tmp4, [b, c])
}) Node_insertBefore_heap"
by eval
end

View File

@ -0,0 +1,160 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
(* This file is automatically generated, please do not modify! *)
section\<open>Testing Node\_removeChild\<close>
text\<open>This theory contains the test cases for Node\_removeChild.\<close>
theory Shadow_DOM_Node_removeChild
imports
"Shadow_DOM_BaseTest"
begin
definition Node_removeChild_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
"Node_removeChild_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
(cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 7)] fmempty None)),
(cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6)] fmempty None)),
(cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
(cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Node.removeChild'')),
(cast (element_ptr.Ref 4), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
(cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
(cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''creators.js'')]) None)),
(cast (element_ptr.Ref 7), cast (create_element_obj ''body'' [cast (element_ptr.Ref 8), cast (element_ptr.Ref 9), cast (element_ptr.Ref 10)] fmempty None)),
(cast (element_ptr.Ref 8), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
(cast (element_ptr.Ref 9), cast (create_element_obj ''iframe'' [] (fmap_of_list [(''src'', ''about:blank'')]) None)),
(cast (element_ptr.Ref 10), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
(cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
definition Node_removeChild_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Node_removeChild_document = Some (cast (document_ptr.Ref 1))"
text \<open>"Passing a detached Element to removeChild should not affect it."\<close>
lemma "test (do {
doc \<leftarrow> return Node_removeChild_document;
s \<leftarrow> doc . createElement(''div'');
tmp0 \<leftarrow> s . ownerDocument;
assert_equals(tmp0, doc);
tmp1 \<leftarrow> Node_removeChild_document . body;
assert_throws(NotFoundError, tmp1 . removeChild(s));
tmp2 \<leftarrow> s . ownerDocument;
assert_equals(tmp2, doc)
}) Node_removeChild_heap"
by eval
text \<open>"Passing a non-detached Element to removeChild should not affect it."\<close>
lemma "test (do {
doc \<leftarrow> return Node_removeChild_document;
s \<leftarrow> doc . createElement(''div'');
tmp0 \<leftarrow> doc . documentElement;
tmp0 . appendChild(s);
tmp1 \<leftarrow> s . ownerDocument;
assert_equals(tmp1, doc);
tmp2 \<leftarrow> Node_removeChild_document . body;
assert_throws(NotFoundError, tmp2 . removeChild(s));
tmp3 \<leftarrow> s . ownerDocument;
assert_equals(tmp3, doc)
}) Node_removeChild_heap"
by eval
text \<open>"Calling removeChild on an Element with no children should throw NOT\_FOUND\_ERR."\<close>
lemma "test (do {
doc \<leftarrow> return Node_removeChild_document;
s \<leftarrow> doc . createElement(''div'');
tmp0 \<leftarrow> doc . body;
tmp0 . appendChild(s);
tmp1 \<leftarrow> s . ownerDocument;
assert_equals(tmp1, doc);
assert_throws(NotFoundError, s . removeChild(doc))
}) Node_removeChild_heap"
by eval
text \<open>"Passing a detached Element to removeChild should not affect it."\<close>
lemma "test (do {
doc \<leftarrow> createDocument('''');
s \<leftarrow> doc . createElement(''div'');
tmp0 \<leftarrow> s . ownerDocument;
assert_equals(tmp0, doc);
tmp1 \<leftarrow> Node_removeChild_document . body;
assert_throws(NotFoundError, tmp1 . removeChild(s));
tmp2 \<leftarrow> s . ownerDocument;
assert_equals(tmp2, doc)
}) Node_removeChild_heap"
by eval
text \<open>"Passing a non-detached Element to removeChild should not affect it."\<close>
lemma "test (do {
doc \<leftarrow> createDocument('''');
s \<leftarrow> doc . createElement(''div'');
tmp0 \<leftarrow> doc . documentElement;
tmp0 . appendChild(s);
tmp1 \<leftarrow> s . ownerDocument;
assert_equals(tmp1, doc);
tmp2 \<leftarrow> Node_removeChild_document . body;
assert_throws(NotFoundError, tmp2 . removeChild(s));
tmp3 \<leftarrow> s . ownerDocument;
assert_equals(tmp3, doc)
}) Node_removeChild_heap"
by eval
text \<open>"Calling removeChild on an Element with no children should throw NOT\_FOUND\_ERR."\<close>
lemma "test (do {
doc \<leftarrow> createDocument('''');
s \<leftarrow> doc . createElement(''div'');
tmp0 \<leftarrow> doc . body;
tmp0 . appendChild(s);
tmp1 \<leftarrow> s . ownerDocument;
assert_equals(tmp1, doc);
assert_throws(NotFoundError, s . removeChild(doc))
}) Node_removeChild_heap"
by eval
text \<open>"Passing a value that is not a Node reference to removeChild should throw TypeError."\<close>
lemma "test (do {
tmp0 \<leftarrow> Node_removeChild_document . body;
assert_throws(TypeError, tmp0 . removeChild(None))
}) Node_removeChild_heap"
by eval
end

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="test">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1"></slot>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
</body>
<script>
test(() => {
let n = createTestTree(test);
assert_equals(n.s1.ownerDocument, document);
}, 'ownerDocument inside shadow tree returns the outer document.');
test(() => {
let n = createTestTree(test);
assert_equals(n.c1.ownerDocument, document);
}, 'ownerDocument outside shadow tree returns the outer document.');
</script>
</html>

View File

@ -0,0 +1,81 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
(* This file is automatically generated, please do not modify! *)
section\<open>Testing my\_get\_owner\_document\<close>
text\<open>This theory contains the test cases for my\_get\_owner\_document.\<close>
theory my_get_owner_document
imports
"Shadow_DOM_BaseTest"
begin
definition my_get_owner_document_heap :: "heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l" where
"my_get_owner_document_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
(cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 3)] fmempty None)),
(cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [] fmempty None)),
(cast (element_ptr.Ref 3), cast (create_element_obj ''body'' [cast (element_ptr.Ref 4), cast (element_ptr.Ref 8)] fmempty None)),
(cast (element_ptr.Ref 4), cast (create_element_obj ''div'' [cast (element_ptr.Ref 5)] (fmap_of_list [(''id'', ''test'')]) None)),
(cast (element_ptr.Ref 5), cast (create_element_obj ''div'' [cast (element_ptr.Ref 6)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 1))))),
(cast (element_ptr.Ref 6), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 1), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 7)])),
(cast (element_ptr.Ref 7), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 1)] fmempty None)),
(cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
definition my_get_owner_document_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "my_get_owner_document_document = Some (cast (document_ptr.Ref 1))"
text \<open>'ownerDocument inside shadow tree returns the outer document.'\<close>
lemma "test (do {
tmp0 \<leftarrow> my_get_owner_document_document . getElementById(''test'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> tmp1 . ownerDocument;
assert_equals(tmp2, my_get_owner_document_document)
}) my_get_owner_document_heap"
by eval
text \<open>'ownerDocument outside shadow tree returns the outer document.'\<close>
lemma "test (do {
tmp0 \<leftarrow> my_get_owner_document_document . getElementById(''test'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''c1'';
tmp2 \<leftarrow> tmp1 . ownerDocument;
assert_equals(tmp2, my_get_owner_document_document)
}) my_get_owner_document_heap"
by eval
end

View File

@ -0,0 +1,253 @@
<!DOCTYPE html>
<title>Shadow DOM: Slots and fallback contents</title>
<meta name="author" title="Hayato Ito" href="mailto:hayato@google.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/shadow-dom.js"></script>
<div id="test1">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1">
<div id="f1"></div>
</slot>
</template>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test1);
removeWhiteSpaceOnlyTextNodes(n.test1);
assert_equals(n.f1.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.f1]);
}, 'Slots fallback: Basic.');
test(() => {
let n = createTestTree(test1);
assert_array_equals(n.s1.assignedElements(), []);
assert_array_equals(n.s1.assignedElements({ flatten: true }), [n.f1]);
}, 'Slots fallback: Basic, elements only.');
</script>
<div id="test2">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1">
<slot id="s2" name="slot2">
<div id="f1"></div>
</slot>
</slot>
</template>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test2);
removeWhiteSpaceOnlyTextNodes(n.test2);
assert_equals(n.f1.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), []);
assert_array_equals(n.s2.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.f1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f1]);
}, 'Slots fallback: Slots in Slots.');
test(() => {
let n = createTestTree(test2);
assert_array_equals(n.s1.assignedElements(), []);
assert_array_equals(n.s2.assignedElements(), []);
assert_array_equals(n.s1.assignedElements({ flatten: true }), [n.f1]);
assert_array_equals(n.s2.assignedElements({ flatten: true }), [n.f1]);
}, 'Slots fallback: Slots in Slots, elements only.');
</script>
<div id="test3">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1">
<slot id="s2" name="slot2">
<div id="f1"></div>
</slot>
</slot>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test3);
removeWhiteSpaceOnlyTextNodes(n.test3);
assert_equals(n.c1.assignedSlot, n.s1);
assert_equals(n.f1.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s2.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f1]);
}, 'Slots fallback: Fallback contents should not be used if a node is assigned.');
</script>
<div id="test4">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1">
<slot id="s2" name="slot2">
<div id="f1"></div>
</slot>
</slot>
</template>
<div id="c1" slot="slot2"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test4);
removeWhiteSpaceOnlyTextNodes(n.test4);
assert_equals(n.c1.assignedSlot, n.s2);
assert_equals(n.f1.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), []);
assert_array_equals(n.s2.assignedNodes(), [n.c1]);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
}, 'Slots fallback: Slots in Slots: Assigned nodes should be used as fallback contents of another slot');
</script>
<div id="test5">
<div id="host1">
<template data-mode="open">
<div id="host2">
<template data-mode="open">
<slot id="s4" name="slot4">
<slot id="s3" name="slot3">
<div id="f3"></div>
</slot>
<div id="f4"></div>
</slot>
</template>
<slot id="s2" name="slot2" slot="slot3">
<slot id="s1" name="slot1">
<div id="f1"></div>
</slot>
<div id="f2"></div>
</slot>
</div>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test5);
removeWhiteSpaceOnlyTextNodes(n.test5);
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s2.assignedNodes(), []);
assert_array_equals(n.s3.assignedNodes(), [n.s2]);
assert_array_equals(n.s4.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1, n.f2]);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c1, n.f2]);
assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.c1, n.f2, n.f4]);
}, 'Slots fallback: Complex case.');
test(() => {
let n = createTestTree(test5);
assert_array_equals(n.s1.assignedElements(), [n.c1]);
assert_array_equals(n.s2.assignedElements(), []);
assert_array_equals(n.s3.assignedElements(), [n.s2]);
assert_array_equals(n.s4.assignedElements(), []);
assert_array_equals(n.s1.assignedElements({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedElements({ flatten: true }), [n.c1, n.f2]);
assert_array_equals(n.s3.assignedElements({ flatten: true }), [n.c1, n.f2]);
assert_array_equals(n.s4.assignedElements({ flatten: true }), [n.c1, n.f2, n.f4]);
}, 'Slots fallback: Complex case, elements only.');
test(() => {
let n = createTestTree(test5);
removeWhiteSpaceOnlyTextNodes(n.test5);
let d1 = document.createElement('div');
n.s2.appendChild(d1);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1, n.f2, d1]);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c1, n.f2, d1]);
assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.c1, n.f2, d1, n.f4]);
}, 'Slots fallback: Mutation. Append fallback contents.');
test(() => {
let n = createTestTree(test5);
removeWhiteSpaceOnlyTextNodes(n.test5);
n.f2.remove();
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.c1, n.f4]);
}, 'Slots fallback: Mutation. Remove fallback contents.');
test(() => {
let n = createTestTree(test5);
removeWhiteSpaceOnlyTextNodes(n.test5);
let d2 = document.createElement('div');
d2.setAttribute('slot', 'slot2');
n.host1.appendChild(d2);
assert_array_equals(n.s2.assignedNodes(), [d2]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [d2]);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), [d2]);
assert_array_equals(n.s4.assignedNodes({ flatten: true }), [d2, n.f4]);
}, 'Slots fallback: Mutation. Assign a node to a slot so that fallback contens are no longer used.');
test(() => {
let n = createTestTree(test5);
removeWhiteSpaceOnlyTextNodes(n.test5);
n.c1.remove();
assert_array_equals(n.s1.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.f1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f1, n.f2]);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.f1, n.f2]);
assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.f1, n.f2, n.f4]);
}, 'Slots fallback: Mutation. Remove an assigned node from a slot so that fallback contens will be used.');
test(() => {
let n = createTestTree(test5);
removeWhiteSpaceOnlyTextNodes(n.test5);
n.s1.remove();
assert_array_equals(n.s1.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [],
'fall back contents should be empty because s1 is not in a shadow tree.');
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f2]);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.f2]);
assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.f2, n.f4]);
}, 'Slots fallback: Mutation. Remove a slot which is a fallback content of another slot.');
</script>

526
Shadow_DOM/tests/slots.html Normal file
View File

@ -0,0 +1,526 @@
<!DOCTYPE html>
<title>Shadow DOM: Slots and assignments</title>
<meta name="author" title="Hayato Ito" href="mailto:hayato@google.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/shadow-dom.js"></script>
<div id="test_basic">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1"></slot>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_basic);
removeWhiteSpaceOnlyTextNodes(n.test_basic);
assert_equals(n.c1.assignedSlot, n.s1);
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
}, 'Slots: Basic.');
test(() => {
let n = createTestTree(test_basic);
assert_array_equals(n.s1.assignedElements(), [n.c1]);
}, 'Slots: Basic, elements only.');
</script>
<div id="test_basic_closed">
<div id="host">
<template data-mode="closed">
<slot id="s1" name="slot1"></slot>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_basic_closed);
removeWhiteSpaceOnlyTextNodes(n.test_basic_closed);
assert_equals(n.c1.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
}, 'Slots: Slots in closed.');
test(() => {
let n = createTestTree(test_basic_closed);
assert_array_equals(n.s1.assignedElements(), [n.c1]);
}, 'Slots: Slots in closed, elements only.');
</script>
<div id="test_slot_not_in_shadow">
<slot id="s1"></slot>
</div>
<script>
test(() => {
let n = createTestTree(test_slot_not_in_shadow);
removeWhiteSpaceOnlyTextNodes(n.test_slot_not_in_shadow);
assert_array_equals(n.s1.assignedNodes(), []);
}, 'Slots: Slots not in a shadow tree.');
test(() => {
let n = createTestTree(test_slot_not_in_shadow);
assert_array_equals(n.s1.assignedElements(), []);
}, 'Slots: Slots not in a shadow tree, elements only.');
</script>
<div id="test_slot_not_in_shadow_2">
<slot id="s1">
<div id="c1"></div>
</slot>
<slot id="s2">
<div id="c2"></div>
<slot id="s3">
<div id="c3_1"></div>
<div id="c3_2"></div>
</slot>
</slot>
</div>
<script>
test(() => {
let n = createTestTree(test_slot_not_in_shadow_2);
removeWhiteSpaceOnlyTextNodes(n.test_slot_not_in_shadow_2);
assert_equals(n.c1.assignedSlot, null);
assert_equals(n.c2.assignedSlot, null);
assert_equals(n.c3_1.assignedSlot, null);
assert_equals(n.c3_2.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), []);
assert_array_equals(n.s2.assignedNodes(), []);
assert_array_equals(n.s3.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), []);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), []);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), []);
}, 'Slots: Distributed nodes for Slots not in a shadow tree.');
</script>
<div id="test_slot_name_matching">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1"></slot>
<slot id="s2" name="slot2"></slot>
<slot id="s3" name="xxx"></slot>
</template>
<div id="c1" slot="slot1"></div>
<div id="c2" slot="slot2"></div>
<div id="c3" slot="yyy"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_slot_name_matching);
removeWhiteSpaceOnlyTextNodes(n.test_slot_name_matching);
assert_equals(n.c1.assignedSlot, n.s1);
assert_equals(n.c2.assignedSlot, n.s2);
assert_equals(n.c3.assignedSlot, null);
}, 'Slots: Name matching');
</script>
<div id="test_no_direct_host_child">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1"></slot>
<slot id="s2" name="slot1"></slot>
</template>
<div id="c1" slot="slot1"></div>
<div id="c2" slot="slot1"></div>
<div>
<div id="c3" slot="slot1"></div>
</div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_no_direct_host_child);
removeWhiteSpaceOnlyTextNodes(n.test_no_direct_host_child);
assert_equals(n.c1.assignedSlot, n.s1);
assert_equals(n.c2.assignedSlot, n.s1);
assert_equals(n.c3.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), [n.c1, n.c2]);
}, 'Slots: No direct host child.');
</script>
<div id="test_default_slot">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1"></slot>
<slot id="s2"></slot>
<slot id="s3"></slot>
</template>
<div id="c1"></div>
<div id="c2" slot=""></div>
<div id="c3" slot="foo"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_default_slot);
removeWhiteSpaceOnlyTextNodes(n.test_default_slot);
assert_equals(n.c1.assignedSlot, n.s2);
assert_equals(n.c2.assignedSlot, n.s2);
assert_equals(n.c3.assignedSlot, null);
}, 'Slots: Default Slot.');
</script>
<div id="test_slot_in_slot">
<div id="host">
<template data-mode="open">
<slot id="s1" name="slot1">
<slot id="s2" name="slot2"></slot>
</slot>
</template>
<div id="c1" slot="slot2"></div>
<div id="c2" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_slot_in_slot);
removeWhiteSpaceOnlyTextNodes(n.test_slot_in_slot);
assert_equals(n.c1.assignedSlot, n.s2);
assert_equals(n.c2.assignedSlot, n.s1);
}, 'Slots: Slot in Slot does not matter in assignment.');
</script>
<div id="test_slot_is_assigned_to_slot">
<div id="host1">
<template data-mode="open">
<div id="host2">
<template data-mode="open">
<slot id="s2" name="slot2"></slot>
</template>
<slot id="s1" name="slot1" slot="slot2"></slot>
</div>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_slot_is_assigned_to_slot);
removeWhiteSpaceOnlyTextNodes(n.test_slot_is_assigned_to_slot);
assert_equals(n.c1.assignedSlot, n.s1);
assert_equals(n.s1.assignedSlot, n.s2);
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s2.assignedNodes(), [n.s1]);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
}, 'Slots: Slot is assigned to another slot');
</script>
<div id="test_open_closed">
<div id="host1">
<template data-mode="open">
<div id="host2">
<template data-mode="closed">
<slot id="s2" name="slot2"></slot>
</template>
<slot id="s1" name="slot1" slot="slot2"></slot>
</div>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_open_closed);
removeWhiteSpaceOnlyTextNodes(n.test_open_closed);
assert_equals(n.c1.assignedSlot, n.s1);
assert_equals(n.s1.assignedSlot, null,
'A slot in a closed shadow tree should not be accessed via assignedSlot');
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s2.assignedNodes(), [n.s1]);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
}, 'Slots: Open > Closed.');
</script>
<div id="test_closed_closed">
<div id="host1">
<template data-mode="closed">
<div id="host2">
<template data-mode="closed">
<slot id="s2" name="slot2"></slot>
</template>
<slot id="s1" name="slot1" slot="slot2"></slot>
</div>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_closed_closed);
removeWhiteSpaceOnlyTextNodes(n.test_closed_closed);
assert_equals(n.c1.assignedSlot, null,
'A slot in a closed shadow tree should not be accessed via assignedSlot');
assert_equals(n.s1.assignedSlot, null,
'A slot in a closed shadow tree should not be accessed via assignedSlot');
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s2.assignedNodes(), [n.s1]);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
}, 'Slots: Closed > Closed.');
</script>
<div id="test_closed_open">
<div id="host1">
<template data-mode="closed">
<div id="host2">
<template data-mode="open">
<slot id="s2" name="slot2"></slot>
</template>
<slot id="s1" name="slot1" slot="slot2"></slot>
</div>
</template>
<div id="c1" slot="slot1"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_closed_open);
removeWhiteSpaceOnlyTextNodes(n.test_closed_open);
assert_equals(n.c1.assignedSlot, null,
'A slot in a closed shadow tree should not be accessed via assignedSlot');
assert_equals(n.s1.assignedSlot, n.s2);
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s2.assignedNodes(), [n.s1]);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
}, 'Slots: Closed > Open.');
</script>
<div id="test_complex">
<div id="host1">
<template data-mode="open">
<div id="host2">
<template data-mode="open">
<slot id="s5" name="slot5"></slot>
<slot id="s6" name="slot6"></slot>
<slot id="s7"></slot>
<slot id="s8" name="slot8"></slot>
</template>
<slot id="s1" name="slot1" slot="slot5"></slot>
<slot id="s2" name="slot2" slot="slot6"></slot>
<slot id="s3"></slot>
<slot id="s4" name="slot4" slot="slot-none"></slot>
<div id="c5" slot="slot5"></div>
<div id="c6" slot="slot6"></div>
<div id="c7"></div>
<div id="c8" slot="slot-none"></div>
</div>
</template>
<div id="c1" slot="slot1"></div>
<div id="c2" slot="slot2"></div>
<div id="c3"></div>
<div id="c4" slot="slot-none"></div>
</div>
</div>
<script>
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
assert_equals(n.c1.assignedSlot, n.s1);
assert_equals(n.c2.assignedSlot, n.s2);
assert_equals(n.c3.assignedSlot, n.s3);
assert_equals(n.c4.assignedSlot, null);
assert_equals(n.s1.assignedSlot, n.s5);
assert_equals(n.s2.assignedSlot, n.s6);
assert_equals(n.s3.assignedSlot, n.s7);
assert_equals(n.s4.assignedSlot, null);
assert_equals(n.c5.assignedSlot, n.s5);
assert_equals(n.c6.assignedSlot, n.s6);
assert_equals(n.c7.assignedSlot, n.s7);
assert_equals(n.c8.assignedSlot, null);
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s2.assignedNodes(), [n.c2]);
assert_array_equals(n.s3.assignedNodes(), [n.c3]);
assert_array_equals(n.s4.assignedNodes(), []);
assert_array_equals(n.s5.assignedNodes(), [n.s1, n.c5]);
assert_array_equals(n.s6.assignedNodes(), [n.s2, n.c6]);
assert_array_equals(n.s7.assignedNodes(), [n.s3, n.c7]);
assert_array_equals(n.s8.assignedNodes(), []);
assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c2]);
assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c3]);
assert_array_equals(n.s4.assignedNodes({ flatten: true }), []);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, n.c5]);
assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c2, n.c6]);
assert_array_equals(n.s7.assignedNodes({ flatten: true }), [n.c3, n.c7]);
assert_array_equals(n.s8.assignedNodes({ flatten: true }), []);
}, 'Slots: Complex case: Basi line.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
let d1 = document.createElement('div');
d1.setAttribute('slot', 'slot1');
n.host1.appendChild(d1);
assert_array_equals(n.s1.assignedNodes(), [n.c1, d1]);
assert_equals(d1.assignedSlot, n.s1);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, d1, n.c5]);
}, 'Slots: Mutation: appendChild.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
n.c1.setAttribute('slot', 'slot-none');
assert_array_equals(n.s1.assignedNodes(), []);
assert_equals(n.c1.assignedSlot, null);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
}, 'Slots: Mutation: Change slot= attribute 1.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
n.c1.setAttribute('slot', 'slot2');
assert_array_equals(n.s1.assignedNodes(), []);
assert_array_equals(n.s2.assignedNodes(), [n.c1, n.c2]);
assert_equals(n.c1.assignedSlot, n.s2);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c1, n.c2, n.c6]);
}, 'Slots: Mutation: Change slot= attribute 2.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
n.c4.setAttribute('slot', 'slot1');
assert_array_equals(n.s1.assignedNodes(), [n.c1, n.c4]);
assert_equals(n.c4.assignedSlot, n.s1);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, n.c4, n.c5]);
}, 'Slots: Mutation: Change slot= attribute 3.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
n.c1.remove();
assert_array_equals(n.s1.assignedNodes(), []);
assert_equals(n.c1.assignedSlot, null);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
}, 'Slots: Mutation: Remove a child.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
let slot = document.createElement('slot');
slot.setAttribute('name', 'slot1');
n.host2.appendChild(slot);
assert_array_equals(slot.assignedNodes(), []);
}, 'Slots: Mutation: Add a slot: after.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
let slot = document.createElement('slot');
slot.setAttribute('name', 'slot1');
n.host2.insertBefore(slot, n.s1);
assert_array_equals(slot.assignedNodes(), [n.c1]);
assert_equals(n.c1.assignedSlot, slot);
assert_array_equals(n.s7.assignedNodes(), [slot, n.s3, n.c7]);
assert_array_equals(n.s7.assignedNodes({ flatten: true }), [n.c1, n.c3, n.c7]);
}, 'Slots: Mutation: Add a slot: before.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
n.s1.remove();
assert_array_equals(n.s1.assignedNodes(), []);
assert_equals(n.c1.assignedSlot, null);
assert_array_equals(n.s5.assignedNodes(), [n.c5]);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
}, 'Slots: Mutation: Remove a slot.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
n.s1.setAttribute('name', 'slot2');
assert_array_equals(n.s1.assignedNodes(), [n.c2]);
assert_equals(n.c1.assignedSlot, null);
assert_equals(n.c2.assignedSlot, n.s1);
assert_array_equals(n.s5.assignedNodes(), [n.s1, n.c5]);
assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c2, n.c5]);
}, 'Slots: Mutation: Change slot name= attribute.');
test(() => {
let n = createTestTree(test_complex);
removeWhiteSpaceOnlyTextNodes(n.test_complex);
n.s1.setAttribute('slot', 'slot6');
assert_array_equals(n.s1.assignedNodes(), [n.c1]);
assert_array_equals(n.s5.assignedNodes(), [n.c5]);
assert_array_equals(n.s6.assignedNodes(), [n.s1, n.s2, n.c6]);
assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c1, n.c2, n.c6]);
}, 'Slots: Mutation: Change slot slot= attribute.');
</script>

947
Shadow_DOM/tests/slots.thy Normal file
View File

@ -0,0 +1,947 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
(* This file is automatically generated, please do not modify! *)
section\<open>Testing slots\<close>
text\<open>This theory contains the test cases for slots.\<close>
theory slots
imports
"Shadow_DOM_BaseTest"
begin
definition slots_heap :: "heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l" where
"slots_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
(cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 8)] fmempty None)),
(cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7)] fmempty None)),
(cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
(cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Shadow%20DOM%3A%20Slots%20and%20assignments'')),
(cast (element_ptr.Ref 4), cast (create_element_obj ''meta'' [] (fmap_of_list [(''name'', ''author''), (''title'', ''Hayato Ito''), (''href'', ''mailto:hayato@google.com'')]) None)),
(cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
(cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
(cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''resources/shadow-dom.js'')]) None)),
(cast (element_ptr.Ref 8), cast (create_element_obj ''body'' [cast (element_ptr.Ref 9), cast (element_ptr.Ref 13), cast (element_ptr.Ref 14), cast (element_ptr.Ref 18), cast (element_ptr.Ref 19), cast (element_ptr.Ref 21), cast (element_ptr.Ref 22), cast (element_ptr.Ref 30), cast (element_ptr.Ref 31), cast (element_ptr.Ref 39), cast (element_ptr.Ref 40), cast (element_ptr.Ref 48), cast (element_ptr.Ref 49), cast (element_ptr.Ref 57), cast (element_ptr.Ref 58), cast (element_ptr.Ref 64), cast (element_ptr.Ref 65), cast (element_ptr.Ref 71), cast (element_ptr.Ref 72), cast (element_ptr.Ref 78), cast (element_ptr.Ref 79), cast (element_ptr.Ref 85), cast (element_ptr.Ref 86), cast (element_ptr.Ref 92), cast (element_ptr.Ref 93), cast (element_ptr.Ref 112)] fmempty None)),
(cast (element_ptr.Ref 9), cast (create_element_obj ''div'' [cast (element_ptr.Ref 10)] (fmap_of_list [(''id'', ''test_basic'')]) None)),
(cast (element_ptr.Ref 10), cast (create_element_obj ''div'' [cast (element_ptr.Ref 11)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 1))))),
(cast (element_ptr.Ref 11), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 1), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 12)])),
(cast (element_ptr.Ref 12), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 13), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
(cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 14), cast (create_element_obj ''div'' [cast (element_ptr.Ref 15)] (fmap_of_list [(''id'', ''test_basic_closed'')]) None)),
(cast (element_ptr.Ref 15), cast (create_element_obj ''div'' [cast (element_ptr.Ref 16)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 2))))),
(cast (element_ptr.Ref 16), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 2), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 17)])),
(cast (element_ptr.Ref 17), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 18), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
(cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 19), cast (create_element_obj ''div'' [cast (element_ptr.Ref 20)] (fmap_of_list [(''id'', ''test_slot_not_in_shadow'')]) None)),
(cast (element_ptr.Ref 20), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1'')]) None)),
(cast (element_ptr.Ref 21), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 4)] fmempty None)),
(cast (character_data_ptr.Ref 4), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 22), cast (create_element_obj ''div'' [cast (element_ptr.Ref 23), cast (element_ptr.Ref 25)] (fmap_of_list [(''id'', ''test_slot_not_in_shadow_2'')]) None)),
(cast (element_ptr.Ref 23), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 24)] (fmap_of_list [(''id'', ''s1'')]) None)),
(cast (element_ptr.Ref 24), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1'')]) None)),
(cast (element_ptr.Ref 25), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 26), cast (element_ptr.Ref 27)] (fmap_of_list [(''id'', ''s2'')]) None)),
(cast (element_ptr.Ref 26), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2'')]) None)),
(cast (element_ptr.Ref 27), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 28), cast (element_ptr.Ref 29)] (fmap_of_list [(''id'', ''s3'')]) None)),
(cast (element_ptr.Ref 28), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3_1'')]) None)),
(cast (element_ptr.Ref 29), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3_2'')]) None)),
(cast (element_ptr.Ref 30), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 5)] fmempty None)),
(cast (character_data_ptr.Ref 5), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 31), cast (create_element_obj ''div'' [cast (element_ptr.Ref 32)] (fmap_of_list [(''id'', ''test_slot_name_matching'')]) None)),
(cast (element_ptr.Ref 32), cast (create_element_obj ''div'' [cast (element_ptr.Ref 33), cast (element_ptr.Ref 34), cast (element_ptr.Ref 35)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 3))))),
(cast (element_ptr.Ref 33), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (element_ptr.Ref 34), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot2'')]) None)),
(cast (element_ptr.Ref 35), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3''), (''slot'', ''yyy'')]) None)),
(cast (shadow_root_ptr.Ref 3), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 36), cast (element_ptr.Ref 37), cast (element_ptr.Ref 38)])),
(cast (element_ptr.Ref 36), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 37), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 38), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s3''), (''name'', ''xxx'')]) None)),
(cast (element_ptr.Ref 39), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 6)] fmempty None)),
(cast (character_data_ptr.Ref 6), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 40), cast (create_element_obj ''div'' [cast (element_ptr.Ref 41)] (fmap_of_list [(''id'', ''test_no_direct_host_child'')]) None)),
(cast (element_ptr.Ref 41), cast (create_element_obj ''div'' [cast (element_ptr.Ref 42), cast (element_ptr.Ref 43), cast (element_ptr.Ref 44)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 4))))),
(cast (element_ptr.Ref 42), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (element_ptr.Ref 43), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot1'')]) None)),
(cast (element_ptr.Ref 44), cast (create_element_obj ''div'' [cast (element_ptr.Ref 45)] fmempty None)),
(cast (element_ptr.Ref 45), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 4), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 46), cast (element_ptr.Ref 47)])),
(cast (element_ptr.Ref 46), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 47), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 48), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 7)] fmempty None)),
(cast (character_data_ptr.Ref 7), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 49), cast (create_element_obj ''div'' [cast (element_ptr.Ref 50)] (fmap_of_list [(''id'', ''test_default_slot'')]) None)),
(cast (element_ptr.Ref 50), cast (create_element_obj ''div'' [cast (element_ptr.Ref 51), cast (element_ptr.Ref 52), cast (element_ptr.Ref 53)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 5))))),
(cast (element_ptr.Ref 51), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1'')]) None)),
(cast (element_ptr.Ref 52), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', '''')]) None)),
(cast (element_ptr.Ref 53), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3''), (''slot'', ''foo'')]) None)),
(cast (shadow_root_ptr.Ref 5), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 54), cast (element_ptr.Ref 55), cast (element_ptr.Ref 56)])),
(cast (element_ptr.Ref 54), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 55), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2'')]) None)),
(cast (element_ptr.Ref 56), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s3'')]) None)),
(cast (element_ptr.Ref 57), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 8)] fmempty None)),
(cast (character_data_ptr.Ref 8), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 58), cast (create_element_obj ''div'' [cast (element_ptr.Ref 59)] (fmap_of_list [(''id'', ''test_slot_in_slot'')]) None)),
(cast (element_ptr.Ref 59), cast (create_element_obj ''div'' [cast (element_ptr.Ref 60), cast (element_ptr.Ref 61)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 6))))),
(cast (element_ptr.Ref 60), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot2'')]) None)),
(cast (element_ptr.Ref 61), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 6), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 62)])),
(cast (element_ptr.Ref 62), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 63)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 63), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 64), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 9)] fmempty None)),
(cast (character_data_ptr.Ref 9), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 65), cast (create_element_obj ''div'' [cast (element_ptr.Ref 66)] (fmap_of_list [(''id'', ''test_slot_is_assigned_to_slot'')]) None)),
(cast (element_ptr.Ref 66), cast (create_element_obj ''div'' [cast (element_ptr.Ref 67)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 7))))),
(cast (element_ptr.Ref 67), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 7), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 68)])),
(cast (element_ptr.Ref 68), cast (create_element_obj ''div'' [cast (element_ptr.Ref 69)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 8))))),
(cast (element_ptr.Ref 69), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
(cast (shadow_root_ptr.Ref 8), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 70)])),
(cast (element_ptr.Ref 70), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 71), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 10)] fmempty None)),
(cast (character_data_ptr.Ref 10), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 72), cast (create_element_obj ''div'' [cast (element_ptr.Ref 73)] (fmap_of_list [(''id'', ''test_open_closed'')]) None)),
(cast (element_ptr.Ref 73), cast (create_element_obj ''div'' [cast (element_ptr.Ref 74)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 9))))),
(cast (element_ptr.Ref 74), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 9), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 75)])),
(cast (element_ptr.Ref 75), cast (create_element_obj ''div'' [cast (element_ptr.Ref 76)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 10))))),
(cast (element_ptr.Ref 76), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
(cast (shadow_root_ptr.Ref 10), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 77)])),
(cast (element_ptr.Ref 77), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 78), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 11)] fmempty None)),
(cast (character_data_ptr.Ref 11), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 79), cast (create_element_obj ''div'' [cast (element_ptr.Ref 80)] (fmap_of_list [(''id'', ''test_closed_closed'')]) None)),
(cast (element_ptr.Ref 80), cast (create_element_obj ''div'' [cast (element_ptr.Ref 81)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 11))))),
(cast (element_ptr.Ref 81), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 11), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 82)])),
(cast (element_ptr.Ref 82), cast (create_element_obj ''div'' [cast (element_ptr.Ref 83)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 12))))),
(cast (element_ptr.Ref 83), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
(cast (shadow_root_ptr.Ref 12), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 84)])),
(cast (element_ptr.Ref 84), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 85), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 12)] fmempty None)),
(cast (character_data_ptr.Ref 12), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 86), cast (create_element_obj ''div'' [cast (element_ptr.Ref 87)] (fmap_of_list [(''id'', ''test_closed_open'')]) None)),
(cast (element_ptr.Ref 87), cast (create_element_obj ''div'' [cast (element_ptr.Ref 88)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 13))))),
(cast (element_ptr.Ref 88), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 13), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 89)])),
(cast (element_ptr.Ref 89), cast (create_element_obj ''div'' [cast (element_ptr.Ref 90)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 14))))),
(cast (element_ptr.Ref 90), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
(cast (shadow_root_ptr.Ref 14), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 91)])),
(cast (element_ptr.Ref 91), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 92), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 13)] fmempty None)),
(cast (character_data_ptr.Ref 13), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 93), cast (create_element_obj ''div'' [cast (element_ptr.Ref 94)] (fmap_of_list [(''id'', ''test_complex'')]) None)),
(cast (element_ptr.Ref 94), cast (create_element_obj ''div'' [cast (element_ptr.Ref 95), cast (element_ptr.Ref 96), cast (element_ptr.Ref 97), cast (element_ptr.Ref 98)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 15))))),
(cast (element_ptr.Ref 95), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (element_ptr.Ref 96), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot2'')]) None)),
(cast (element_ptr.Ref 97), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3'')]) None)),
(cast (element_ptr.Ref 98), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c4''), (''slot'', ''slot-none'')]) None)),
(cast (shadow_root_ptr.Ref 15), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 99)])),
(cast (element_ptr.Ref 99), cast (create_element_obj ''div'' [cast (element_ptr.Ref 100), cast (element_ptr.Ref 101), cast (element_ptr.Ref 102), cast (element_ptr.Ref 103), cast (element_ptr.Ref 104), cast (element_ptr.Ref 105), cast (element_ptr.Ref 106), cast (element_ptr.Ref 107)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 16))))),
(cast (element_ptr.Ref 100), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot5'')]) None)),
(cast (element_ptr.Ref 101), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2''), (''slot'', ''slot6'')]) None)),
(cast (element_ptr.Ref 102), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s3'')]) None)),
(cast (element_ptr.Ref 103), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s4''), (''name'', ''slot4''), (''slot'', ''slot-none'')]) None)),
(cast (element_ptr.Ref 104), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c5''), (''slot'', ''slot5'')]) None)),
(cast (element_ptr.Ref 105), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c6''), (''slot'', ''slot6'')]) None)),
(cast (element_ptr.Ref 106), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c7'')]) None)),
(cast (element_ptr.Ref 107), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c8''), (''slot'', ''slot-none'')]) None)),
(cast (shadow_root_ptr.Ref 16), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 108), cast (element_ptr.Ref 109), cast (element_ptr.Ref 110), cast (element_ptr.Ref 111)])),
(cast (element_ptr.Ref 108), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s5''), (''name'', ''slot5'')]) None)),
(cast (element_ptr.Ref 109), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s6''), (''name'', ''slot6'')]) None)),
(cast (element_ptr.Ref 110), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s7'')]) None)),
(cast (element_ptr.Ref 111), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s8''), (''name'', ''slot8'')]) None)),
(cast (element_ptr.Ref 112), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 14)] fmempty None)),
(cast (character_data_ptr.Ref 14), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
definition slots_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "slots_document = Some (cast (document_ptr.Ref 1))"
text \<open>'Slots: Basic.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_basic'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_basic'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s1'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''s1'';
tmp6 \<leftarrow> tmp5 . assignedNodes();
tmp7 \<leftarrow> n . ''c1'';
assert_array_equals(tmp6, [tmp7])
}) slots_heap"
by eval
text \<open>'Slots: Basic, elements only.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_basic'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> tmp1 . assignedElements();
tmp3 \<leftarrow> n . ''c1'';
assert_array_equals(tmp2, [tmp3])
}) slots_heap"
by eval
text \<open>'Slots: Slots in closed.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_basic_closed'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_basic_closed'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
assert_equals(tmp3, None);
tmp4 \<leftarrow> n . ''s1'';
tmp5 \<leftarrow> tmp4 . assignedNodes();
tmp6 \<leftarrow> n . ''c1'';
assert_array_equals(tmp5, [tmp6])
}) slots_heap"
by eval
text \<open>'Slots: Slots in closed, elements only.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_basic_closed'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> tmp1 . assignedElements();
tmp3 \<leftarrow> n . ''c1'';
assert_array_equals(tmp2, [tmp3])
}) slots_heap"
by eval
text \<open>'Slots: Slots not in a shadow tree.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_slot_not_in_shadow'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_slot_not_in_shadow'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''s1'';
tmp3 \<leftarrow> tmp2 . assignedNodes();
assert_array_equals(tmp3, [])
}) slots_heap"
by eval
text \<open>'Slots: Slots not in a shadow tree, elements only.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_slot_not_in_shadow'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> tmp1 . assignedElements();
assert_array_equals(tmp2, [])
}) slots_heap"
by eval
text \<open>'Slots: Distributed nodes for Slots not in a shadow tree.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_slot_not_in_shadow_2'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_slot_not_in_shadow_2'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
assert_equals(tmp3, None);
tmp4 \<leftarrow> n . ''c2'';
tmp5 \<leftarrow> tmp4 . assignedSlot;
assert_equals(tmp5, None);
tmp6 \<leftarrow> n . ''c3_1'';
tmp7 \<leftarrow> tmp6 . assignedSlot;
assert_equals(tmp7, None);
tmp8 \<leftarrow> n . ''c3_2'';
tmp9 \<leftarrow> tmp8 . assignedSlot;
assert_equals(tmp9, None);
tmp10 \<leftarrow> n . ''s1'';
tmp11 \<leftarrow> tmp10 . assignedNodes();
assert_array_equals(tmp11, []);
tmp12 \<leftarrow> n . ''s2'';
tmp13 \<leftarrow> tmp12 . assignedNodes();
assert_array_equals(tmp13, []);
tmp14 \<leftarrow> n . ''s3'';
tmp15 \<leftarrow> tmp14 . assignedNodes();
assert_array_equals(tmp15, []);
tmp16 \<leftarrow> n . ''s1'';
tmp17 \<leftarrow> tmp16 . assignedNodes(True);
assert_array_equals(tmp17, []);
tmp18 \<leftarrow> n . ''s2'';
tmp19 \<leftarrow> tmp18 . assignedNodes(True);
assert_array_equals(tmp19, []);
tmp20 \<leftarrow> n . ''s3'';
tmp21 \<leftarrow> tmp20 . assignedNodes(True);
assert_array_equals(tmp21, [])
}) slots_heap"
by eval
text \<open>'Slots: Name matching'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_slot_name_matching'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_slot_name_matching'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s1'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''c2'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
tmp7 \<leftarrow> n . ''s2'';
assert_equals(tmp6, tmp7);
tmp8 \<leftarrow> n . ''c3'';
tmp9 \<leftarrow> tmp8 . assignedSlot;
assert_equals(tmp9, None)
}) slots_heap"
by eval
text \<open>'Slots: No direct host child.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_no_direct_host_child'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_no_direct_host_child'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s1'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''c2'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
tmp7 \<leftarrow> n . ''s1'';
assert_equals(tmp6, tmp7);
tmp8 \<leftarrow> n . ''c3'';
tmp9 \<leftarrow> tmp8 . assignedSlot;
assert_equals(tmp9, None);
tmp10 \<leftarrow> n . ''s1'';
tmp11 \<leftarrow> tmp10 . assignedNodes();
tmp12 \<leftarrow> n . ''c1'';
tmp13 \<leftarrow> n . ''c2'';
assert_array_equals(tmp11, [tmp12, tmp13])
}) slots_heap"
by eval
text \<open>'Slots: Default Slot.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_default_slot'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_default_slot'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s2'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''c2'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
tmp7 \<leftarrow> n . ''s2'';
assert_equals(tmp6, tmp7);
tmp8 \<leftarrow> n . ''c3'';
tmp9 \<leftarrow> tmp8 . assignedSlot;
assert_equals(tmp9, None)
}) slots_heap"
by eval
text \<open>'Slots: Slot in Slot does not matter in assignment.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_slot_in_slot'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_slot_in_slot'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s2'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''c2'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
tmp7 \<leftarrow> n . ''s1'';
assert_equals(tmp6, tmp7)
}) slots_heap"
by eval
text \<open>'Slots: Slot is assigned to another slot'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_slot_is_assigned_to_slot'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_slot_is_assigned_to_slot'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s1'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''s1'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
tmp7 \<leftarrow> n . ''s2'';
assert_equals(tmp6, tmp7);
tmp8 \<leftarrow> n . ''s1'';
tmp9 \<leftarrow> tmp8 . assignedNodes();
tmp10 \<leftarrow> n . ''c1'';
assert_array_equals(tmp9, [tmp10]);
tmp11 \<leftarrow> n . ''s2'';
tmp12 \<leftarrow> tmp11 . assignedNodes();
tmp13 \<leftarrow> n . ''s1'';
assert_array_equals(tmp12, [tmp13]);
tmp14 \<leftarrow> n . ''s1'';
tmp15 \<leftarrow> tmp14 . assignedNodes(True);
tmp16 \<leftarrow> n . ''c1'';
assert_array_equals(tmp15, [tmp16]);
tmp17 \<leftarrow> n . ''s2'';
tmp18 \<leftarrow> tmp17 . assignedNodes(True);
tmp19 \<leftarrow> n . ''c1'';
assert_array_equals(tmp18, [tmp19])
}) slots_heap"
by eval
text \<open>'Slots: Open > Closed.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_open_closed'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_open_closed'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s1'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''s1'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
assert_equals(tmp6, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
tmp7 \<leftarrow> n . ''s1'';
tmp8 \<leftarrow> tmp7 . assignedNodes();
tmp9 \<leftarrow> n . ''c1'';
assert_array_equals(tmp8, [tmp9]);
tmp10 \<leftarrow> n . ''s2'';
tmp11 \<leftarrow> tmp10 . assignedNodes();
tmp12 \<leftarrow> n . ''s1'';
assert_array_equals(tmp11, [tmp12]);
tmp13 \<leftarrow> n . ''s1'';
tmp14 \<leftarrow> tmp13 . assignedNodes(True);
tmp15 \<leftarrow> n . ''c1'';
assert_array_equals(tmp14, [tmp15]);
tmp16 \<leftarrow> n . ''s2'';
tmp17 \<leftarrow> tmp16 . assignedNodes(True);
tmp18 \<leftarrow> n . ''c1'';
assert_array_equals(tmp17, [tmp18])
}) slots_heap"
by eval
text \<open>'Slots: Closed > Closed.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_closed_closed'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_closed_closed'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
assert_equals(tmp3, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
tmp4 \<leftarrow> n . ''s1'';
tmp5 \<leftarrow> tmp4 . assignedSlot;
assert_equals(tmp5, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
tmp6 \<leftarrow> n . ''s1'';
tmp7 \<leftarrow> tmp6 . assignedNodes();
tmp8 \<leftarrow> n . ''c1'';
assert_array_equals(tmp7, [tmp8]);
tmp9 \<leftarrow> n . ''s2'';
tmp10 \<leftarrow> tmp9 . assignedNodes();
tmp11 \<leftarrow> n . ''s1'';
assert_array_equals(tmp10, [tmp11]);
tmp12 \<leftarrow> n . ''s1'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''c1'';
assert_array_equals(tmp13, [tmp14]);
tmp15 \<leftarrow> n . ''s2'';
tmp16 \<leftarrow> tmp15 . assignedNodes(True);
tmp17 \<leftarrow> n . ''c1'';
assert_array_equals(tmp16, [tmp17])
}) slots_heap"
by eval
text \<open>'Slots: Closed > Open.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_closed_open'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_closed_open'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
assert_equals(tmp3, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
tmp4 \<leftarrow> n . ''s1'';
tmp5 \<leftarrow> tmp4 . assignedSlot;
tmp6 \<leftarrow> n . ''s2'';
assert_equals(tmp5, tmp6);
tmp7 \<leftarrow> n . ''s1'';
tmp8 \<leftarrow> tmp7 . assignedNodes();
tmp9 \<leftarrow> n . ''c1'';
assert_array_equals(tmp8, [tmp9]);
tmp10 \<leftarrow> n . ''s2'';
tmp11 \<leftarrow> tmp10 . assignedNodes();
tmp12 \<leftarrow> n . ''s1'';
assert_array_equals(tmp11, [tmp12]);
tmp13 \<leftarrow> n . ''s1'';
tmp14 \<leftarrow> tmp13 . assignedNodes(True);
tmp15 \<leftarrow> n . ''c1'';
assert_array_equals(tmp14, [tmp15]);
tmp16 \<leftarrow> n . ''s2'';
tmp17 \<leftarrow> tmp16 . assignedNodes(True);
tmp18 \<leftarrow> n . ''c1'';
assert_array_equals(tmp17, [tmp18])
}) slots_heap"
by eval
text \<open>'Slots: Complex case: Basi line.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s1'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''c2'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
tmp7 \<leftarrow> n . ''s2'';
assert_equals(tmp6, tmp7);
tmp8 \<leftarrow> n . ''c3'';
tmp9 \<leftarrow> tmp8 . assignedSlot;
tmp10 \<leftarrow> n . ''s3'';
assert_equals(tmp9, tmp10);
tmp11 \<leftarrow> n . ''c4'';
tmp12 \<leftarrow> tmp11 . assignedSlot;
assert_equals(tmp12, None);
tmp13 \<leftarrow> n . ''s1'';
tmp14 \<leftarrow> tmp13 . assignedSlot;
tmp15 \<leftarrow> n . ''s5'';
assert_equals(tmp14, tmp15);
tmp16 \<leftarrow> n . ''s2'';
tmp17 \<leftarrow> tmp16 . assignedSlot;
tmp18 \<leftarrow> n . ''s6'';
assert_equals(tmp17, tmp18);
tmp19 \<leftarrow> n . ''s3'';
tmp20 \<leftarrow> tmp19 . assignedSlot;
tmp21 \<leftarrow> n . ''s7'';
assert_equals(tmp20, tmp21);
tmp22 \<leftarrow> n . ''s4'';
tmp23 \<leftarrow> tmp22 . assignedSlot;
assert_equals(tmp23, None);
tmp24 \<leftarrow> n . ''c5'';
tmp25 \<leftarrow> tmp24 . assignedSlot;
tmp26 \<leftarrow> n . ''s5'';
assert_equals(tmp25, tmp26);
tmp27 \<leftarrow> n . ''c6'';
tmp28 \<leftarrow> tmp27 . assignedSlot;
tmp29 \<leftarrow> n . ''s6'';
assert_equals(tmp28, tmp29);
tmp30 \<leftarrow> n . ''c7'';
tmp31 \<leftarrow> tmp30 . assignedSlot;
tmp32 \<leftarrow> n . ''s7'';
assert_equals(tmp31, tmp32);
tmp33 \<leftarrow> n . ''c8'';
tmp34 \<leftarrow> tmp33 . assignedSlot;
assert_equals(tmp34, None);
tmp35 \<leftarrow> n . ''s1'';
tmp36 \<leftarrow> tmp35 . assignedNodes();
tmp37 \<leftarrow> n . ''c1'';
assert_array_equals(tmp36, [tmp37]);
tmp38 \<leftarrow> n . ''s2'';
tmp39 \<leftarrow> tmp38 . assignedNodes();
tmp40 \<leftarrow> n . ''c2'';
assert_array_equals(tmp39, [tmp40]);
tmp41 \<leftarrow> n . ''s3'';
tmp42 \<leftarrow> tmp41 . assignedNodes();
tmp43 \<leftarrow> n . ''c3'';
assert_array_equals(tmp42, [tmp43]);
tmp44 \<leftarrow> n . ''s4'';
tmp45 \<leftarrow> tmp44 . assignedNodes();
assert_array_equals(tmp45, []);
tmp46 \<leftarrow> n . ''s5'';
tmp47 \<leftarrow> tmp46 . assignedNodes();
tmp48 \<leftarrow> n . ''s1'';
tmp49 \<leftarrow> n . ''c5'';
assert_array_equals(tmp47, [tmp48, tmp49]);
tmp50 \<leftarrow> n . ''s6'';
tmp51 \<leftarrow> tmp50 . assignedNodes();
tmp52 \<leftarrow> n . ''s2'';
tmp53 \<leftarrow> n . ''c6'';
assert_array_equals(tmp51, [tmp52, tmp53]);
tmp54 \<leftarrow> n . ''s7'';
tmp55 \<leftarrow> tmp54 . assignedNodes();
tmp56 \<leftarrow> n . ''s3'';
tmp57 \<leftarrow> n . ''c7'';
assert_array_equals(tmp55, [tmp56, tmp57]);
tmp58 \<leftarrow> n . ''s8'';
tmp59 \<leftarrow> tmp58 . assignedNodes();
assert_array_equals(tmp59, []);
tmp60 \<leftarrow> n . ''s1'';
tmp61 \<leftarrow> tmp60 . assignedNodes(True);
tmp62 \<leftarrow> n . ''c1'';
assert_array_equals(tmp61, [tmp62]);
tmp63 \<leftarrow> n . ''s2'';
tmp64 \<leftarrow> tmp63 . assignedNodes(True);
tmp65 \<leftarrow> n . ''c2'';
assert_array_equals(tmp64, [tmp65]);
tmp66 \<leftarrow> n . ''s3'';
tmp67 \<leftarrow> tmp66 . assignedNodes(True);
tmp68 \<leftarrow> n . ''c3'';
assert_array_equals(tmp67, [tmp68]);
tmp69 \<leftarrow> n . ''s4'';
tmp70 \<leftarrow> tmp69 . assignedNodes(True);
assert_array_equals(tmp70, []);
tmp71 \<leftarrow> n . ''s5'';
tmp72 \<leftarrow> tmp71 . assignedNodes(True);
tmp73 \<leftarrow> n . ''c1'';
tmp74 \<leftarrow> n . ''c5'';
assert_array_equals(tmp72, [tmp73, tmp74]);
tmp75 \<leftarrow> n . ''s6'';
tmp76 \<leftarrow> tmp75 . assignedNodes(True);
tmp77 \<leftarrow> n . ''c2'';
tmp78 \<leftarrow> n . ''c6'';
assert_array_equals(tmp76, [tmp77, tmp78]);
tmp79 \<leftarrow> n . ''s7'';
tmp80 \<leftarrow> tmp79 . assignedNodes(True);
tmp81 \<leftarrow> n . ''c3'';
tmp82 \<leftarrow> n . ''c7'';
assert_array_equals(tmp80, [tmp81, tmp82]);
tmp83 \<leftarrow> n . ''s8'';
tmp84 \<leftarrow> tmp83 . assignedNodes(True);
assert_array_equals(tmp84, [])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: appendChild.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
d1 \<leftarrow> slots_document . createElement(''div'');
d1 . setAttribute(''slot'', ''slot1'');
tmp2 \<leftarrow> n . ''host1'';
tmp2 . appendChild(d1);
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
tmp5 \<leftarrow> n . ''c1'';
assert_array_equals(tmp4, [tmp5, d1]);
tmp6 \<leftarrow> d1 . assignedSlot;
tmp7 \<leftarrow> n . ''s1'';
assert_equals(tmp6, tmp7);
tmp8 \<leftarrow> n . ''s5'';
tmp9 \<leftarrow> tmp8 . assignedNodes(True);
tmp10 \<leftarrow> n . ''c1'';
tmp11 \<leftarrow> n . ''c5'';
assert_array_equals(tmp9, [tmp10, d1, tmp11])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Change slot= attribute 1.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp2 . setAttribute(''slot'', ''slot-none'');
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
assert_array_equals(tmp4, []);
tmp5 \<leftarrow> n . ''c1'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
assert_equals(tmp6, None);
tmp7 \<leftarrow> n . ''s5'';
tmp8 \<leftarrow> tmp7 . assignedNodes(True);
tmp9 \<leftarrow> n . ''c5'';
assert_array_equals(tmp8, [tmp9])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Change slot= attribute 2.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp2 . setAttribute(''slot'', ''slot2'');
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
assert_array_equals(tmp4, []);
tmp5 \<leftarrow> n . ''s2'';
tmp6 \<leftarrow> tmp5 . assignedNodes();
tmp7 \<leftarrow> n . ''c1'';
tmp8 \<leftarrow> n . ''c2'';
assert_array_equals(tmp6, [tmp7, tmp8]);
tmp9 \<leftarrow> n . ''c1'';
tmp10 \<leftarrow> tmp9 . assignedSlot;
tmp11 \<leftarrow> n . ''s2'';
assert_equals(tmp10, tmp11);
tmp12 \<leftarrow> n . ''s5'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''c5'';
assert_array_equals(tmp13, [tmp14]);
tmp15 \<leftarrow> n . ''s6'';
tmp16 \<leftarrow> tmp15 . assignedNodes(True);
tmp17 \<leftarrow> n . ''c1'';
tmp18 \<leftarrow> n . ''c2'';
tmp19 \<leftarrow> n . ''c6'';
assert_array_equals(tmp16, [tmp17, tmp18, tmp19])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Change slot= attribute 3.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c4'';
tmp2 . setAttribute(''slot'', ''slot1'');
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
tmp5 \<leftarrow> n . ''c1'';
tmp6 \<leftarrow> n . ''c4'';
assert_array_equals(tmp4, [tmp5, tmp6]);
tmp7 \<leftarrow> n . ''c4'';
tmp8 \<leftarrow> tmp7 . assignedSlot;
tmp9 \<leftarrow> n . ''s1'';
assert_equals(tmp8, tmp9);
tmp10 \<leftarrow> n . ''s5'';
tmp11 \<leftarrow> tmp10 . assignedNodes(True);
tmp12 \<leftarrow> n . ''c1'';
tmp13 \<leftarrow> n . ''c4'';
tmp14 \<leftarrow> n . ''c5'';
assert_array_equals(tmp11, [tmp12, tmp13, tmp14])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Remove a child.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp2 . remove();
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
assert_array_equals(tmp4, []);
tmp5 \<leftarrow> n . ''c1'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
assert_equals(tmp6, None);
tmp7 \<leftarrow> n . ''s5'';
tmp8 \<leftarrow> tmp7 . assignedNodes(True);
tmp9 \<leftarrow> n . ''c5'';
assert_array_equals(tmp8, [tmp9])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Add a slot: after.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
slot \<leftarrow> slots_document . createElement(''slot'');
slot . setAttribute(''name'', ''slot1'');
tmp2 \<leftarrow> n . ''host2'';
tmp2 . appendChild(slot);
tmp3 \<leftarrow> slot . assignedNodes();
assert_array_equals(tmp3, [])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Add a slot: before.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
slot \<leftarrow> slots_document . createElement(''slot'');
slot . setAttribute(''name'', ''slot1'');
tmp3 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> n . ''host2'';
tmp2 . insertBefore(slot, tmp3);
tmp4 \<leftarrow> slot . assignedNodes();
tmp5 \<leftarrow> n . ''c1'';
assert_array_equals(tmp4, [tmp5]);
tmp6 \<leftarrow> n . ''c1'';
tmp7 \<leftarrow> tmp6 . assignedSlot;
assert_equals(tmp7, slot);
tmp8 \<leftarrow> n . ''s7'';
tmp9 \<leftarrow> tmp8 . assignedNodes();
tmp10 \<leftarrow> n . ''s3'';
tmp11 \<leftarrow> n . ''c7'';
assert_array_equals(tmp9, [slot, tmp10, tmp11]);
tmp12 \<leftarrow> n . ''s7'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''c1'';
tmp15 \<leftarrow> n . ''c3'';
tmp16 \<leftarrow> n . ''c7'';
assert_array_equals(tmp13, [tmp14, tmp15, tmp16])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Remove a slot.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''s1'';
tmp2 . remove();
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
assert_array_equals(tmp4, []);
tmp5 \<leftarrow> n . ''c1'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
assert_equals(tmp6, None);
tmp7 \<leftarrow> n . ''s5'';
tmp8 \<leftarrow> tmp7 . assignedNodes();
tmp9 \<leftarrow> n . ''c5'';
assert_array_equals(tmp8, [tmp9]);
tmp10 \<leftarrow> n . ''s5'';
tmp11 \<leftarrow> tmp10 . assignedNodes(True);
tmp12 \<leftarrow> n . ''c5'';
assert_array_equals(tmp11, [tmp12])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Change slot name= attribute.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''s1'';
tmp2 . setAttribute(''name'', ''slot2'');
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
tmp5 \<leftarrow> n . ''c2'';
assert_array_equals(tmp4, [tmp5]);
tmp6 \<leftarrow> n . ''c1'';
tmp7 \<leftarrow> tmp6 . assignedSlot;
assert_equals(tmp7, None);
tmp8 \<leftarrow> n . ''c2'';
tmp9 \<leftarrow> tmp8 . assignedSlot;
tmp10 \<leftarrow> n . ''s1'';
assert_equals(tmp9, tmp10);
tmp11 \<leftarrow> n . ''s5'';
tmp12 \<leftarrow> tmp11 . assignedNodes();
tmp13 \<leftarrow> n . ''s1'';
tmp14 \<leftarrow> n . ''c5'';
assert_array_equals(tmp12, [tmp13, tmp14]);
tmp15 \<leftarrow> n . ''s5'';
tmp16 \<leftarrow> tmp15 . assignedNodes(True);
tmp17 \<leftarrow> n . ''c2'';
tmp18 \<leftarrow> n . ''c5'';
assert_array_equals(tmp16, [tmp17, tmp18])
}) slots_heap"
by eval
text \<open>'Slots: Mutation: Change slot slot= attribute.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test_complex'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''s1'';
tmp2 . setAttribute(''slot'', ''slot6'');
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
tmp5 \<leftarrow> n . ''c1'';
assert_array_equals(tmp4, [tmp5]);
tmp6 \<leftarrow> n . ''s5'';
tmp7 \<leftarrow> tmp6 . assignedNodes();
tmp8 \<leftarrow> n . ''c5'';
assert_array_equals(tmp7, [tmp8]);
tmp9 \<leftarrow> n . ''s6'';
tmp10 \<leftarrow> tmp9 . assignedNodes();
tmp11 \<leftarrow> n . ''s1'';
tmp12 \<leftarrow> n . ''s2'';
tmp13 \<leftarrow> n . ''c6'';
assert_array_equals(tmp10, [tmp11, tmp12, tmp13]);
tmp14 \<leftarrow> n . ''s6'';
tmp15 \<leftarrow> tmp14 . assignedNodes(True);
tmp16 \<leftarrow> n . ''c1'';
tmp17 \<leftarrow> n . ''c2'';
tmp18 \<leftarrow> n . ''c6'';
assert_array_equals(tmp15, [tmp16, tmp17, tmp18])
}) slots_heap"
by eval
end

View File

@ -0,0 +1,507 @@
(***********************************************************************************
* Copyright (c) 2016-2020 The University of Sheffield, UK
* 2019-2020 University of Exeter, UK
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-2-Clause
***********************************************************************************)
(* This file is automatically generated, please do not modify! *)
section\<open>Testing slots\_fallback\<close>
text\<open>This theory contains the test cases for slots\_fallback.\<close>
theory slots_fallback
imports
"Shadow_DOM_BaseTest"
begin
definition slots_fallback_heap :: "heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l" where
"slots_fallback_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
(cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 8)] fmempty None)),
(cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7)] fmempty None)),
(cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
(cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Shadow%20DOM%3A%20Slots%20and%20fallback%20contents'')),
(cast (element_ptr.Ref 4), cast (create_element_obj ''meta'' [] (fmap_of_list [(''name'', ''author''), (''title'', ''Hayato Ito''), (''href'', ''mailto:hayato@google.com'')]) None)),
(cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
(cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
(cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''resources/shadow-dom.js'')]) None)),
(cast (element_ptr.Ref 8), cast (create_element_obj ''body'' [cast (element_ptr.Ref 9), cast (element_ptr.Ref 13), cast (element_ptr.Ref 14), cast (element_ptr.Ref 19), cast (element_ptr.Ref 20), cast (element_ptr.Ref 26), cast (element_ptr.Ref 27), cast (element_ptr.Ref 33), cast (element_ptr.Ref 34), cast (element_ptr.Ref 46)] fmempty None)),
(cast (element_ptr.Ref 9), cast (create_element_obj ''div'' [cast (element_ptr.Ref 10)] (fmap_of_list [(''id'', ''test1'')]) None)),
(cast (element_ptr.Ref 10), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 1))))),
(cast (shadow_root_ptr.Ref 1), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 11)])),
(cast (element_ptr.Ref 11), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 12)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 12), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
(cast (element_ptr.Ref 13), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
(cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 14), cast (create_element_obj ''div'' [cast (element_ptr.Ref 15)] (fmap_of_list [(''id'', ''test2'')]) None)),
(cast (element_ptr.Ref 15), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 2))))),
(cast (shadow_root_ptr.Ref 2), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 16)])),
(cast (element_ptr.Ref 16), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 17)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 17), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 18)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 18), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
(cast (element_ptr.Ref 19), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
(cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 20), cast (create_element_obj ''div'' [cast (element_ptr.Ref 21)] (fmap_of_list [(''id'', ''test3'')]) None)),
(cast (element_ptr.Ref 21), cast (create_element_obj ''div'' [cast (element_ptr.Ref 22)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 3))))),
(cast (element_ptr.Ref 22), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 3), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 23)])),
(cast (element_ptr.Ref 23), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 24)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 24), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 25)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 25), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
(cast (element_ptr.Ref 26), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 4)] fmempty None)),
(cast (character_data_ptr.Ref 4), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 27), cast (create_element_obj ''div'' [cast (element_ptr.Ref 28)] (fmap_of_list [(''id'', ''test4'')]) None)),
(cast (element_ptr.Ref 28), cast (create_element_obj ''div'' [cast (element_ptr.Ref 29)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 4))))),
(cast (element_ptr.Ref 29), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot2'')]) None)),
(cast (shadow_root_ptr.Ref 4), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 30)])),
(cast (element_ptr.Ref 30), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 31)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 31), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 32)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
(cast (element_ptr.Ref 32), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
(cast (element_ptr.Ref 33), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 5)] fmempty None)),
(cast (character_data_ptr.Ref 5), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
(cast (element_ptr.Ref 34), cast (create_element_obj ''div'' [cast (element_ptr.Ref 35)] (fmap_of_list [(''id'', ''test5'')]) None)),
(cast (element_ptr.Ref 35), cast (create_element_obj ''div'' [cast (element_ptr.Ref 36)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 5))))),
(cast (element_ptr.Ref 36), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
(cast (shadow_root_ptr.Ref 5), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 37)])),
(cast (element_ptr.Ref 37), cast (create_element_obj ''div'' [cast (element_ptr.Ref 38)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 6))))),
(cast (element_ptr.Ref 38), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 39), cast (element_ptr.Ref 41)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2''), (''slot'', ''slot3'')]) None)),
(cast (element_ptr.Ref 39), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 40)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
(cast (element_ptr.Ref 40), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
(cast (element_ptr.Ref 41), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f2'')]) None)),
(cast (shadow_root_ptr.Ref 6), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 42)])),
(cast (element_ptr.Ref 42), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 43), cast (element_ptr.Ref 45)] (fmap_of_list [(''id'', ''s4''), (''name'', ''slot4'')]) None)),
(cast (element_ptr.Ref 43), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 44)] (fmap_of_list [(''id'', ''s3''), (''name'', ''slot3'')]) None)),
(cast (element_ptr.Ref 44), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f3'')]) None)),
(cast (element_ptr.Ref 45), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f4'')]) None)),
(cast (element_ptr.Ref 46), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 6)] fmempty None)),
(cast (character_data_ptr.Ref 6), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
definition slots_fallback_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "slots_fallback_document = Some (cast (document_ptr.Ref 1))"
text \<open>'Slots fallback: Basic.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test1'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test1'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''f1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
assert_equals(tmp3, None);
tmp4 \<leftarrow> n . ''s1'';
tmp5 \<leftarrow> tmp4 . assignedNodes();
assert_array_equals(tmp5, []);
tmp6 \<leftarrow> n . ''s1'';
tmp7 \<leftarrow> tmp6 . assignedNodes(True);
tmp8 \<leftarrow> n . ''f1'';
assert_array_equals(tmp7, [tmp8])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Basic, elements only.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test1'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> tmp1 . assignedElements();
assert_array_equals(tmp2, []);
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedElements(True);
tmp5 \<leftarrow> n . ''f1'';
assert_array_equals(tmp4, [tmp5])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Slots in Slots.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test2'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test2'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''f1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
assert_equals(tmp3, None);
tmp4 \<leftarrow> n . ''s1'';
tmp5 \<leftarrow> tmp4 . assignedNodes();
assert_array_equals(tmp5, []);
tmp6 \<leftarrow> n . ''s2'';
tmp7 \<leftarrow> tmp6 . assignedNodes();
assert_array_equals(tmp7, []);
tmp8 \<leftarrow> n . ''s1'';
tmp9 \<leftarrow> tmp8 . assignedNodes(True);
tmp10 \<leftarrow> n . ''f1'';
assert_array_equals(tmp9, [tmp10]);
tmp11 \<leftarrow> n . ''s2'';
tmp12 \<leftarrow> tmp11 . assignedNodes(True);
tmp13 \<leftarrow> n . ''f1'';
assert_array_equals(tmp12, [tmp13])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Slots in Slots, elements only.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test2'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> tmp1 . assignedElements();
assert_array_equals(tmp2, []);
tmp3 \<leftarrow> n . ''s2'';
tmp4 \<leftarrow> tmp3 . assignedElements();
assert_array_equals(tmp4, []);
tmp5 \<leftarrow> n . ''s1'';
tmp6 \<leftarrow> tmp5 . assignedElements(True);
tmp7 \<leftarrow> n . ''f1'';
assert_array_equals(tmp6, [tmp7]);
tmp8 \<leftarrow> n . ''s2'';
tmp9 \<leftarrow> tmp8 . assignedElements(True);
tmp10 \<leftarrow> n . ''f1'';
assert_array_equals(tmp9, [tmp10])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Fallback contents should not be used if a node is assigned.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test3'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test3'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s1'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''f1'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
assert_equals(tmp6, None);
tmp7 \<leftarrow> n . ''s1'';
tmp8 \<leftarrow> tmp7 . assignedNodes();
tmp9 \<leftarrow> n . ''c1'';
assert_array_equals(tmp8, [tmp9]);
tmp10 \<leftarrow> n . ''s2'';
tmp11 \<leftarrow> tmp10 . assignedNodes();
assert_array_equals(tmp11, []);
tmp12 \<leftarrow> n . ''s1'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''c1'';
assert_array_equals(tmp13, [tmp14]);
tmp15 \<leftarrow> n . ''s2'';
tmp16 \<leftarrow> tmp15 . assignedNodes(True);
tmp17 \<leftarrow> n . ''f1'';
assert_array_equals(tmp16, [tmp17])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Slots in Slots: Assigned nodes should be used as fallback contents of another slot'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test4'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test4'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp3 \<leftarrow> tmp2 . assignedSlot;
tmp4 \<leftarrow> n . ''s2'';
assert_equals(tmp3, tmp4);
tmp5 \<leftarrow> n . ''f1'';
tmp6 \<leftarrow> tmp5 . assignedSlot;
assert_equals(tmp6, None);
tmp7 \<leftarrow> n . ''s1'';
tmp8 \<leftarrow> tmp7 . assignedNodes();
assert_array_equals(tmp8, []);
tmp9 \<leftarrow> n . ''s2'';
tmp10 \<leftarrow> tmp9 . assignedNodes();
tmp11 \<leftarrow> n . ''c1'';
assert_array_equals(tmp10, [tmp11]);
tmp12 \<leftarrow> n . ''s1'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''c1'';
assert_array_equals(tmp13, [tmp14]);
tmp15 \<leftarrow> n . ''s2'';
tmp16 \<leftarrow> tmp15 . assignedNodes(True);
tmp17 \<leftarrow> n . ''c1'';
assert_array_equals(tmp16, [tmp17])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Complex case.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test5'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''s1'';
tmp3 \<leftarrow> tmp2 . assignedNodes();
tmp4 \<leftarrow> n . ''c1'';
assert_array_equals(tmp3, [tmp4]);
tmp5 \<leftarrow> n . ''s2'';
tmp6 \<leftarrow> tmp5 . assignedNodes();
assert_array_equals(tmp6, []);
tmp7 \<leftarrow> n . ''s3'';
tmp8 \<leftarrow> tmp7 . assignedNodes();
tmp9 \<leftarrow> n . ''s2'';
assert_array_equals(tmp8, [tmp9]);
tmp10 \<leftarrow> n . ''s4'';
tmp11 \<leftarrow> tmp10 . assignedNodes();
assert_array_equals(tmp11, []);
tmp12 \<leftarrow> n . ''s1'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''c1'';
assert_array_equals(tmp13, [tmp14]);
tmp15 \<leftarrow> n . ''s2'';
tmp16 \<leftarrow> tmp15 . assignedNodes(True);
tmp17 \<leftarrow> n . ''c1'';
tmp18 \<leftarrow> n . ''f2'';
assert_array_equals(tmp16, [tmp17, tmp18]);
tmp19 \<leftarrow> n . ''s3'';
tmp20 \<leftarrow> tmp19 . assignedNodes(True);
tmp21 \<leftarrow> n . ''c1'';
tmp22 \<leftarrow> n . ''f2'';
assert_array_equals(tmp20, [tmp21, tmp22]);
tmp23 \<leftarrow> n . ''s4'';
tmp24 \<leftarrow> tmp23 . assignedNodes(True);
tmp25 \<leftarrow> n . ''c1'';
tmp26 \<leftarrow> n . ''f2'';
tmp27 \<leftarrow> n . ''f4'';
assert_array_equals(tmp24, [tmp25, tmp26, tmp27])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Complex case, elements only.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''s1'';
tmp2 \<leftarrow> tmp1 . assignedElements();
tmp3 \<leftarrow> n . ''c1'';
assert_array_equals(tmp2, [tmp3]);
tmp4 \<leftarrow> n . ''s2'';
tmp5 \<leftarrow> tmp4 . assignedElements();
assert_array_equals(tmp5, []);
tmp6 \<leftarrow> n . ''s3'';
tmp7 \<leftarrow> tmp6 . assignedElements();
tmp8 \<leftarrow> n . ''s2'';
assert_array_equals(tmp7, [tmp8]);
tmp9 \<leftarrow> n . ''s4'';
tmp10 \<leftarrow> tmp9 . assignedElements();
assert_array_equals(tmp10, []);
tmp11 \<leftarrow> n . ''s1'';
tmp12 \<leftarrow> tmp11 . assignedElements(True);
tmp13 \<leftarrow> n . ''c1'';
assert_array_equals(tmp12, [tmp13]);
tmp14 \<leftarrow> n . ''s2'';
tmp15 \<leftarrow> tmp14 . assignedElements(True);
tmp16 \<leftarrow> n . ''c1'';
tmp17 \<leftarrow> n . ''f2'';
assert_array_equals(tmp15, [tmp16, tmp17]);
tmp18 \<leftarrow> n . ''s3'';
tmp19 \<leftarrow> tmp18 . assignedElements(True);
tmp20 \<leftarrow> n . ''c1'';
tmp21 \<leftarrow> n . ''f2'';
assert_array_equals(tmp19, [tmp20, tmp21]);
tmp22 \<leftarrow> n . ''s4'';
tmp23 \<leftarrow> tmp22 . assignedElements(True);
tmp24 \<leftarrow> n . ''c1'';
tmp25 \<leftarrow> n . ''f2'';
tmp26 \<leftarrow> n . ''f4'';
assert_array_equals(tmp23, [tmp24, tmp25, tmp26])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Mutation. Append fallback contents.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test5'';
removeWhiteSpaceOnlyTextNodes(tmp1);
d1 \<leftarrow> slots_fallback_document . createElement(''div'');
tmp2 \<leftarrow> n . ''s2'';
tmp2 . appendChild(d1);
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes(True);
tmp5 \<leftarrow> n . ''c1'';
assert_array_equals(tmp4, [tmp5]);
tmp6 \<leftarrow> n . ''s2'';
tmp7 \<leftarrow> tmp6 . assignedNodes(True);
tmp8 \<leftarrow> n . ''c1'';
tmp9 \<leftarrow> n . ''f2'';
assert_array_equals(tmp7, [tmp8, tmp9, d1]);
tmp10 \<leftarrow> n . ''s3'';
tmp11 \<leftarrow> tmp10 . assignedNodes(True);
tmp12 \<leftarrow> n . ''c1'';
tmp13 \<leftarrow> n . ''f2'';
assert_array_equals(tmp11, [tmp12, tmp13, d1]);
tmp14 \<leftarrow> n . ''s4'';
tmp15 \<leftarrow> tmp14 . assignedNodes(True);
tmp16 \<leftarrow> n . ''c1'';
tmp17 \<leftarrow> n . ''f2'';
tmp18 \<leftarrow> n . ''f4'';
assert_array_equals(tmp15, [tmp16, tmp17, d1, tmp18])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Mutation. Remove fallback contents.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test5'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''f2'';
tmp2 . remove();
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes(True);
tmp5 \<leftarrow> n . ''c1'';
assert_array_equals(tmp4, [tmp5]);
tmp6 \<leftarrow> n . ''s2'';
tmp7 \<leftarrow> tmp6 . assignedNodes(True);
tmp8 \<leftarrow> n . ''c1'';
assert_array_equals(tmp7, [tmp8]);
tmp9 \<leftarrow> n . ''s3'';
tmp10 \<leftarrow> tmp9 . assignedNodes(True);
tmp11 \<leftarrow> n . ''c1'';
assert_array_equals(tmp10, [tmp11]);
tmp12 \<leftarrow> n . ''s4'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''c1'';
tmp15 \<leftarrow> n . ''f4'';
assert_array_equals(tmp13, [tmp14, tmp15])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Mutation. Assign a node to a slot so that fallback contens are no longer used.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test5'';
removeWhiteSpaceOnlyTextNodes(tmp1);
d2 \<leftarrow> slots_fallback_document . createElement(''div'');
d2 . setAttribute(''slot'', ''slot2'');
tmp2 \<leftarrow> n . ''host1'';
tmp2 . appendChild(d2);
tmp3 \<leftarrow> n . ''s2'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
assert_array_equals(tmp4, [d2]);
tmp5 \<leftarrow> n . ''s2'';
tmp6 \<leftarrow> tmp5 . assignedNodes(True);
assert_array_equals(tmp6, [d2]);
tmp7 \<leftarrow> n . ''s3'';
tmp8 \<leftarrow> tmp7 . assignedNodes(True);
assert_array_equals(tmp8, [d2]);
tmp9 \<leftarrow> n . ''s4'';
tmp10 \<leftarrow> tmp9 . assignedNodes(True);
tmp11 \<leftarrow> n . ''f4'';
assert_array_equals(tmp10, [d2, tmp11])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Mutation. Remove an assigned node from a slot so that fallback contens will be used.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test5'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''c1'';
tmp2 . remove();
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
assert_array_equals(tmp4, []);
tmp5 \<leftarrow> n . ''s1'';
tmp6 \<leftarrow> tmp5 . assignedNodes(True);
tmp7 \<leftarrow> n . ''f1'';
assert_array_equals(tmp6, [tmp7]);
tmp8 \<leftarrow> n . ''s2'';
tmp9 \<leftarrow> tmp8 . assignedNodes(True);
tmp10 \<leftarrow> n . ''f1'';
tmp11 \<leftarrow> n . ''f2'';
assert_array_equals(tmp9, [tmp10, tmp11]);
tmp12 \<leftarrow> n . ''s3'';
tmp13 \<leftarrow> tmp12 . assignedNodes(True);
tmp14 \<leftarrow> n . ''f1'';
tmp15 \<leftarrow> n . ''f2'';
assert_array_equals(tmp13, [tmp14, tmp15]);
tmp16 \<leftarrow> n . ''s4'';
tmp17 \<leftarrow> tmp16 . assignedNodes(True);
tmp18 \<leftarrow> n . ''f1'';
tmp19 \<leftarrow> n . ''f2'';
tmp20 \<leftarrow> n . ''f4'';
assert_array_equals(tmp17, [tmp18, tmp19, tmp20])
}) slots_fallback_heap"
by eval
text \<open>'Slots fallback: Mutation. Remove a slot which is a fallback content of another slot.'\<close>
lemma "test (do {
tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
n \<leftarrow> createTestTree(tmp0);
tmp1 \<leftarrow> n . ''test5'';
removeWhiteSpaceOnlyTextNodes(tmp1);
tmp2 \<leftarrow> n . ''s1'';
tmp2 . remove();
tmp3 \<leftarrow> n . ''s1'';
tmp4 \<leftarrow> tmp3 . assignedNodes();
assert_array_equals(tmp4, []);
tmp5 \<leftarrow> n . ''s1'';
tmp6 \<leftarrow> tmp5 . assignedNodes(True);
assert_array_equals(tmp6, [], ''fall back contents should be empty because s1 is not in a shadow tree.'');
tmp7 \<leftarrow> n . ''s2'';
tmp8 \<leftarrow> tmp7 . assignedNodes(True);
tmp9 \<leftarrow> n . ''f2'';
assert_array_equals(tmp8, [tmp9]);
tmp10 \<leftarrow> n . ''s3'';
tmp11 \<leftarrow> tmp10 . assignedNodes(True);
tmp12 \<leftarrow> n . ''f2'';
assert_array_equals(tmp11, [tmp12]);
tmp13 \<leftarrow> n . ''s4'';
tmp14 \<leftarrow> tmp13 . assignedNodes(True);
tmp15 \<leftarrow> n . ''f2'';
tmp16 \<leftarrow> n . ''f4'';
assert_array_equals(tmp14, [tmp15, tmp16])
}) slots_fallback_heap"
by eval
end