Initial import from AFP.
This commit is contained in:
commit
63fc6cd87c
|
@ -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"
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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
|
|
@ -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}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue