Initial import from AFP.

This commit is contained in:
Achim D. Brucker 2020-12-19 15:19:51 +00:00
commit 63fc6cd87c
22 changed files with 19477 additions and 0 deletions

14
Shadow_SC_DOM/ROOT Normal file
View File

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

12913
Shadow_SC_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,499 @@
(***********************************************************************************
* 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_SC_DOM.ShadowRootPointer
Core_SC_DOM.DocumentClass
begin
subsection \<open>ShadowRoot\<close>
datatype shadow_root_mode = Open | Closed
record ('node_ptr, 'element_ptr, 'character_data_ptr) RShadowRoot =
"('node_ptr, 'element_ptr, 'character_data_ptr) RDocument" +
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, 'Document, 'ShadowRoot) Document
= "('node_ptr, 'element_ptr, 'character_data_ptr, ('node_ptr, 'element_ptr, 'character_data_ptr,
'ShadowRoot option) RShadowRoot_ext + 'Document) Document"
register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'Document, 'ShadowRoot) Document"
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, 'Object, 'Node, 'Element,
'CharacterData, ('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot option)
RShadowRoot_ext + '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,
'Object, 'Node, 'Element, 'CharacterData, ('node_ptr, 'element_ptr,
'character_data_ptr, 'ShadowRoot option) RShadowRoot_ext + '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\<^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>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |`| (ffilter is_shadow_root_ptr_kind (document_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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) Document \<Rightarrow> (_) ShadowRoot option"
where
"cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document = (case RDocument.more document of Some (Inl shadow_root) \<Rightarrow>
Some (RDocument.extend (RDocument.truncate document) shadow_root) | _ \<Rightarrow> None)"
adhoc_overloading cast cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
abbreviation 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 \<equiv> (case cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t obj of
Some document \<Rightarrow> cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document | None \<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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) ShadowRoot \<Rightarrow> (_) Document"
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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root = RDocument.extend (RDocument.truncate shadow_root)
(Some (Inl (RDocument.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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
abbreviation 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 ptr \<equiv> cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr)"
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
consts is_shadow_root_kind :: 'a
definition is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) Document \<Rightarrow> bool"
where
"is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr \<longleftrightarrow> cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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"
adhoc_overloading is_shadow_root_kind is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
lemmas is_shadow_root_kind_def = is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
abbreviation is_shadow_root_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) Object \<Rightarrow> bool"
where
"is_shadow_root_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr \<equiv> 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"
adhoc_overloading is_shadow_root_kind is_shadow_root_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
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\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t (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)
using DocumentClass.a_type_wf_def
by (meson ShadowRootClass.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)
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"
proof
assume "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
then
show "get 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[unfolded l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def type_wf_defs] assms
by (meson notin_fset)
next
assume "get shadow_root_ptr h \<noteq> None"
then
show "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
apply(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 get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def shadow_root_ptr_kinds_def
document_ptr_kinds_def object_ptr_kinds_def
split: Option.bind_splits)[1]
by (metis comp_eq_dest_lhs document_ptr_casts_commute2 document_ptr_document_ptr_cast
ffmember_filter fimageI fmdomI is_shadow_root_ptr_kind_cast option.sel
shadow_root_ptr_casts_commute2)
qed
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\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t (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 shadow_root_ptr_kinds_def
by (metis ffmember_filter fimage_eqI is_shadow_root_ptr_kind_cast option.sel
put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap shadow_root_ptr_casts_commute2)
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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t y \<longleftrightarrow> x = y"
apply(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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RObject.extend_def RDocument.extend_def
RDocument.truncate_def)[1]
by (metis RDocument.select_convs(5) RShadowRoot.surjective old.unit.exhaust)
lemma cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document = 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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root = document)"
apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RObject.extend_def
RDocument.extend_def RDocument.truncate_def
split: sum.splits option.splits)[1]
by (metis (mono_tags, lifting) RDocument.select_convs(2) RDocument.select_convs(3)
RDocument.select_convs(4) RDocument.select_convs(5) RDocument.surjective old.unit.exhaust)
lemma cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document = Some shadow_root \<longleftrightarrow> cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root = document"
apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RObject.extend_def
RDocument.extend_def RDocument.truncate_def
split: sum.splits option.splits)[1]
by (metis RDocument.select_convs(5) RShadowRoot.surjective old.unit.exhaust)
lemma cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root) = Some shadow_root"
by simp
lemma is_shadow_root_kind_doctype [simp]:
"is_shadow_root_kind x \<longleftrightarrow> is_shadow_root_kind (doctype_update (\<lambda>_. v) x)"
apply(auto simp add: is_shadow_root_kind_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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def
RDocument.truncate_def split: option.splits)[1]
apply (metis RDocument.ext_inject RDocument.select_convs(3) RDocument.surjective RObject.ext_inject)
by (smt RDocument.select_convs(2) RDocument.select_convs(3) RDocument.select_convs(4)
RDocument.select_convs(5) RDocument.surjective RDocument.update_convs(2) old.unit.exhaust)
lemma is_shadow_root_kind_document_element [simp]:
"is_shadow_root_kind x \<longleftrightarrow> is_shadow_root_kind (document_element_update (\<lambda>_. v) x)"
apply(auto simp add: is_shadow_root_kind_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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def
RDocument.truncate_def split: option.splits)[1]
apply (metis RDocument.ext_inject RDocument.select_convs(3) RDocument.surjective RObject.ext_inject)
by (metis (no_types, lifting) RDocument.ext_inject RDocument.surjective RDocument.update_convs(3)
RObject.select_convs(1) RObject.select_convs(2))
lemma is_shadow_root_kind_disconnected_nodes [simp]:
"is_shadow_root_kind x \<longleftrightarrow> is_shadow_root_kind (disconnected_nodes_update (\<lambda>_. v) x)"
apply(auto simp add: is_shadow_root_kind_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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def
RDocument.truncate_def split: option.splits)[1]
apply (metis RDocument.ext_inject RDocument.select_convs(3) RDocument.surjective RObject.ext_inject)
by (metis (no_types, lifting) RDocument.ext_inject RDocument.surjective RDocument.update_convs(4)
RObject.select_convs(1) RObject.select_convs(2))
lemma shadow_root_ptr_kinds_commutes [simp]:
"cast shadow_root_ptr |\<in>| document_ptr_kinds h \<longleftrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
apply(auto simp add: document_ptr_kinds_def shadow_root_ptr_kinds_def)[1]
by (metis (no_types, lifting) shadow_root_ptr_casts_commute2 ffmember_filter fimage_eqI
fset.map_comp is_shadow_root_ptr_kind_none document_ptr_casts_commute3
document_ptr_kinds_commutes document_ptr_kinds_def option.sel option.simps(3))
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 put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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 get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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 put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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 get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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_put_document [simp]:
"cast shadow_root_ptr \<noteq> document_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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document 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_document_put_shadow_root [simp]:
"document_ptr \<noteq> cast shadow_root_ptr
\<Longrightarrow> 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 shadow_root 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: 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>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')"
assumes "cast ptr \<noteq> new_document_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>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 = (), RDocument.nothing = (), RDocument.doctype = ''html'',
RDocument.document_element = None, RDocument.disconnected_nodes = [], 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
apply(auto simp add: Let_def new\<^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)[1]
by (metis Suc_n_not_le_n fMax_ge ffmember_filter fimageI is_shadow_root_ptr_ref
shadow_root_ptr.disc(1) shadow_root_ptr.exhaust shadow_root_ptr.is_Ref_def shadow_root_ptr.sel(1)
shadow_root_ptr.simps(4) shadow_root_ptr_casts_commute3 shadow_root_ptr_kinds_commutes
shadow_root_ptrs_def)
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 put\<^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>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 put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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')"
assumes "ptr \<noteq> cast new_shadow_root_ptr"
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 put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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: a_known_ptrs_def less_eq_fset.rep_eq 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 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
document_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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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]:
"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>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^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> 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_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>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_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>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_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>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_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> document_ptr \<noteq> cast shadow_root_ptr \<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_8 [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,601 @@
@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}
}
@Article{ brucker.ea:afp-core-sc-dom:2020,
author = {Achim D. Brucker and Michael Herzberg},
title = {The Safely Composable {DOM}},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
date = {2020-09-28},
note = {\url{http://www.isa-afp.org/entries/Core_SC_DOM.html}, Formal proof development},
issn = {2150-914x},
abstract = { In this AFP entry, we formalize the core of the Safely Composable Document Object Model (SC DOM).
The SC DOM improve the standard DOM by strengthening the tree boundaries set by shadow roots: in the
SC DOM, the shadow root is a sub-class of the document class (instead of a base class).
This modifications also results in changes to some API methods (e.g., getOwnerDocument) to return the
nearest shadow root rather than the document root. As a result, many API methods that, when called on
a node inside a shadow tree, would previously ``break out'' and return or modify nodes that are
possibly outside the shadow tree, now stay within its boundaries. This change in behavior makes
programs that operate on shadow trees more predictable for the developer and allows them to make more
assumptions about other code accessing the DOM. },
public = {yes},
classification= {formal},
categories = {websecurity},
pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-core-sc-dom-2018.pdf},
filelabel = {Outline},
file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-core-sc-dom-outline-2018.pdf},
areas = {formal methods, security, software engineering},
url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-core-sc-dom-2020}
}
@Article{ brucker.ea:afp-shadow-dom:2020,
author = {Achim D. Brucker and Michael Herzberg},
title = {Shadow DOM: A Formal Model of the Document Object Model \emph{with Shadow Roots}},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
date = {2020-09-28},
note = {\url{http://www.isa-afp.org/entries/Shadow_DOM.html}, Formal proof development},
issn = {2150-914x},
abstract = { In this AFP entry, we extend our formalization of the 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 extensible, i.e., can
be extended without the need of re-proving already proven properties and executable, i.e., we can
generate executable code from our specification. We exploit the executability to show that our
formalization complies to the official standard of the W3C, respectively, the WHATWG. },
public = {yes},
classification= {formal},
categories = {websecurity},
pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-dom-2018.pdf},
filelabel = {Outline},
file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-dom-outline-2018.pdf},
areas = {formal methods, security, software engineering},
url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-shadow-dom-2020}
}
@Article{ brucker.ea:afp-sc-dom-components:2020,
author = {Achim D. Brucker and Michael Herzberg},
title = {A Formalization of Safely Composable Web Components},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
date = {2020-09-28},
note = {\url{http://www.isa-afp.org/entries/SC_DOM_Components.html}, Formal proof development},
issn = {2150-914x},
public = {yes},
classification= {formal},
categories = {websecurity},
pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-sc-dom-components-2020.pdf},
filelabel = {Outline},
file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-sc-dom-components-outline-2020.pdf},
areas = {formal methods, security, software engineering},
url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-sc-dom-components-2020}
}
@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,231 @@
\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 SC DOM\\\medskip \Large
A Formal Model of the Safely Composable 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 safely
composable DOM
(\href{https://www.isa-afp.org/entries/Core_SC_DOM.html}
{Core\_SC\_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-sc-dom:2020}, we formalized the core of
the safely composable 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-sc-dom:2020}, 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-sc-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 (for a more
abstract presentation and more explanations, please
see~\cite{herzberg:web-components:2020}). 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}.
\paragraph{Important Note:} This document describes the formalization
of the \emph{Safely Composable Document Object Model with Shadow
Roots} (SC DOM with Shadow Roots), which deviated in one important
aspect from the official DOM standard: in the SC DOM, the shadow root
is a sub-class of the document class (instead of a base class). This
modification results in a stronger notion of web components that
provide improved safety properties for the composition of web
components. While the SC DOM still passes the compliance test suite as
provided by the authors of the DOM standard, its data model is
different. We refer readers interested in a formalisation of the
standard compliant DOM to the AFP entries
``Core\_DOM''~\cite{brucker.ea:afp-core-dom:2018} and
``Shadow\_DOM''~\cite{brucker.ea:afp-shadow-dom:2020}.
\begin{figure}
\centering
\includegraphics[angle=90,scale=0.5]{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:

File diff suppressed because it is too large Load Diff

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,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.
*
* 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 ()"
partial_function (dom_prog) assert_equal_subtrees :: "(_::linorder) object_ptr option \<Rightarrow>
(_::linorder) object_ptr option \<Rightarrow> (_, unit) dom_prog"
where
[code]: "assert_equal_subtrees ptr ptr' = (case cast (the ptr) of
None \<Rightarrow> (case cast (the ptr) of
None \<Rightarrow> (case cast (the ptr) of
None \<Rightarrow> (case cast (the ptr) of
None \<Rightarrow> error AssertException |
Some shadow_root_ptr \<Rightarrow> (case cast (the ptr') of
None \<Rightarrow> error AssertException |
Some shadow_root_ptr' \<Rightarrow> do {
mode_val \<leftarrow> get_M shadow_root_ptr mode;
mode_val' \<leftarrow> get_M shadow_root_ptr' mode;
(if mode_val = mode_val' then return () else error AssertException);
child_nodes_val \<leftarrow> get_M shadow_root_ptr RShadowRoot.child_nodes;
child_nodes_val' \<leftarrow> get_M shadow_root_ptr' RShadowRoot.child_nodes;
(if length child_nodes_val = length child_nodes_val'
then return () else error AssertException);
map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
(zip child_nodes_val child_nodes_val');
document_ptr \<leftarrow> return (cast shadow_root_ptr);
document_ptr' \<leftarrow> return (cast shadow_root_ptr');
document_element_val \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document_element;
document_element_val' \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr' document_element;
(if (document_element_val = None) \<and> (document_element_val' = None)
then return () else assert_equal_subtrees (Some (cast (the document_element_val)))
(Some (cast (the document_element_val'))));
disconnected_nodes_val \<leftarrow> get_M document_ptr disconnected_nodes;
disconnected_nodes_val' \<leftarrow> get_M document_ptr' disconnected_nodes;
(if length disconnected_nodes_val = length disconnected_nodes_val'
then return () else error AssertException);
map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
(zip disconnected_nodes_val disconnected_nodes_val');
doctype_val \<leftarrow> get_M document_ptr doctype;
doctype_val' \<leftarrow> get_M document_ptr' doctype;
(if doctype_val = doctype_val' then return () else error AssertException);
return ()
})) |
Some document_ptr \<Rightarrow> (case cast (the ptr') of
None \<Rightarrow> error AssertException |
Some document_ptr' \<Rightarrow> do {
document_element_val \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document_element;
document_element_val' \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr' document_element;
(if (document_element_val = None) \<and> (document_element_val' = None)
then return () else assert_equal_subtrees (Some (cast (the document_element_val)))
(Some (cast (the document_element_val'))));
disconnected_nodes_val \<leftarrow> get_M document_ptr disconnected_nodes;
disconnected_nodes_val' \<leftarrow> get_M document_ptr' disconnected_nodes;
(if length disconnected_nodes_val = length disconnected_nodes_val'
then return () else error AssertException);
map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
(zip disconnected_nodes_val disconnected_nodes_val');
doctype_val \<leftarrow> get_M document_ptr doctype;
doctype_val' \<leftarrow> get_M document_ptr' doctype;
(if doctype_val = doctype_val' then return () else error AssertException);
return ()
})) |
Some character_data_ptr \<Rightarrow> (case cast (the ptr') of
None \<Rightarrow> error AssertException |
Some character_data_ptr' \<Rightarrow> do {
val_val \<leftarrow> get_M character_data_ptr val;
val_val' \<leftarrow> get_M character_data_ptr' val;
(if val_val = val_val' then return () else error AssertException)
})) |
Some element_ptr \<Rightarrow> (case cast (the ptr') of
None \<Rightarrow> error AssertException |
Some element_ptr' \<Rightarrow> do {
tag_name_val \<leftarrow> get_M element_ptr tag_name;
tag_name_val' \<leftarrow> get_M element_ptr' tag_name;
(if tag_name_val = tag_name_val' then return () else error AssertException);
child_nodes_val \<leftarrow> get_M element_ptr RElement.child_nodes;
child_nodes_val' \<leftarrow> get_M element_ptr' RElement.child_nodes;
(if length child_nodes_val = length child_nodes_val' then return () else error AssertException);
map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
(zip child_nodes_val child_nodes_val');
attrs_val \<leftarrow> get_M element_ptr attrs;
attrs_val' \<leftarrow> get_M element_ptr' attrs;
(if attrs_val = attrs_val' then return () else error AssertException);
shadow_root_opt_val \<leftarrow> get_M element_ptr shadow_root_opt;
shadow_root_opt_val' \<leftarrow> get_M element_ptr' shadow_root_opt;
(if (shadow_root_opt_val = None) \<and> (shadow_root_opt_val' = None)
then return () else assert_equal_subtrees (Some (cast (the shadow_root_opt_val)))
(Some (cast (the shadow_root_opt_val'))));
return ()
}))"
notation assert_equal_subtrees ("assert'_equal'_subtrees'(_, _')")
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>

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>

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